Subversion Repositories AndroidProjects

Rev

Blame | Last modification | View Log | RSS feed

package com.gebauz.pingK.common.framework;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

import javax.microedition.khronos.opengles.GL10;

/**
 * Simple Mesh class.
 * @author chiu
 *
 */

public class Mesh
{
        /**
         * Helper class to fill an array with vertex information
         *
         */

        public static class AttributeArray
        {
                private float[] mAttributeArray;
                private int mCurrentIndex = 0;
               
                public AttributeArray(int size)
                {
                        mAttributeArray = new float[size];
                        mCurrentIndex = 0;
                }
               
                public void fill(float x)
                {
                        mAttributeArray[mCurrentIndex] = x; mCurrentIndex++;
                }
               
                public void fill(float x, float y)
                {
                        mAttributeArray[mCurrentIndex] = x; mCurrentIndex++;
                        mAttributeArray[mCurrentIndex] = y; mCurrentIndex++;
                }
               
                public void fill(float x, float y, float z)
                {
                        mAttributeArray[mCurrentIndex] = x; mCurrentIndex++;
                        mAttributeArray[mCurrentIndex] = y; mCurrentIndex++;           
                        mAttributeArray[mCurrentIndex] = z; mCurrentIndex++;
                }
               
                public void fill(float x, float y, float z, float w)
                {
                        mAttributeArray[mCurrentIndex] = x; mCurrentIndex++;
                        mAttributeArray[mCurrentIndex] = y; mCurrentIndex++;           
                        mAttributeArray[mCurrentIndex] = z; mCurrentIndex++;
                        mAttributeArray[mCurrentIndex] = w; mCurrentIndex++;                   
                }
               
                public float[] getAttributeArray()
                {
                        return mAttributeArray;
                }
               
                public int getUsedCount()
                {
                        return mCurrentIndex;
                }
        }
       
        public class AttributeBuffer
        {
                public ByteBuffer byteBuffer;
                public FloatBuffer floatBuffer;
                public int length;
               
                public AttributeBuffer()
                {
                }
               
                public AttributeBuffer(float data[])
                {
                        setData(data);
                }
               
                public void setData(float data[])
                {
                        byteBuffer = ByteBuffer.allocateDirect(data.length * 4);
                        byteBuffer.order(ByteOrder.nativeOrder());
                        floatBuffer = byteBuffer.asFloatBuffer();
                        floatBuffer.put(data);
                        floatBuffer.position(0);
                        length = data.length;
                }
        }
       
        public class IndexBuffer
        {
                public ByteBuffer byteBuffer;
                public ShortBuffer shortBuffer;
                public int length;

                public IndexBuffer()
                {
                }
               
                public IndexBuffer(short data[])
                {
                        setData(data);
                }
               
                public void setData(short data[])
                {
                        byteBuffer = ByteBuffer.allocateDirect(data.length * 2);
                        byteBuffer.order(ByteOrder.nativeOrder());
                        shortBuffer = byteBuffer.asShortBuffer();
                        shortBuffer.put(data);
                        shortBuffer.position(0);
                        length = data.length;
                }
        }
       
        AttributeBuffer vertexBuffer = null;
        AttributeBuffer colorBuffer = null;
        AttributeBuffer normalBuffer = null;
        AttributeBuffer texCoordBuffer = null;
        IndexBuffer indexBuffer = null;
       
        public static final int COORD_ELEMENTS_COUNT = 3;
        public static final int COLOR_ELEMENTS_COUNT = 4;
        public static final int TEX_COORD_ELEMENTS_COUNT = 2;
        public static final int NORMAL_ELEMENTS_COUNT = 3;
       
        private int mPrimitiveType = GL10.GL_TRIANGLES;

        public Mesh()
        {
               
        }
       
        public void setVertices(float vertices[])
        {
                if (vertices == null)
                {
                        vertexBuffer = null;
                        return;
                }
               
                vertexBuffer = new AttributeBuffer(vertices);          
        }
       
        public void setColors(float colors[])
        {
                if (colors == null)
                {
                        colorBuffer = null;
                        return;
                }
               
                colorBuffer = new AttributeBuffer(colors);     
        }
       
        public void setNormals(float normals[])
        {
                if (normals == null)
                {
                        normalBuffer = null;
                        return;
                }
               
                normalBuffer = new AttributeBuffer(normals);   
        }
       
        public void setTexCoords(float texCoords[])
        {
                if (texCoords == null)
                {
                        texCoordBuffer = null;
                        return;
                }
               
                texCoordBuffer = new AttributeBuffer(texCoords);       
        }
       
        public void setIndices(short indices[])
        {
                if (indices == null)
                {
                        indexBuffer = null;
                        return;
                }
               
                indexBuffer = new IndexBuffer(indices);
        }
       
        public void setVertex(int index, Vector3 vertex)
        {
                vertexBuffer.floatBuffer.put(index * COORD_ELEMENTS_COUNT + 0, vertex.x);
                vertexBuffer.floatBuffer.put(index * COORD_ELEMENTS_COUNT + 1, vertex.y);
                vertexBuffer.floatBuffer.put(index * COORD_ELEMENTS_COUNT + 2, vertex.z);
        }
       
        public Vector3 getVertex(int index)
        {
                return new Vector3(
                                vertexBuffer.floatBuffer.get(index * COORD_ELEMENTS_COUNT + 0),
                                vertexBuffer.floatBuffer.get(index * COORD_ELEMENTS_COUNT + 1),
                                vertexBuffer.floatBuffer.get(index * COORD_ELEMENTS_COUNT + 2));
        }
       
        public int getVertexCount()
        {
                return vertexBuffer.floatBuffer.limit() / COORD_ELEMENTS_COUNT;
        }
       
        public void setColor(int index, Vector4 color)
        {
                colorBuffer.floatBuffer.put(index * COLOR_ELEMENTS_COUNT + 0, color.x);
                colorBuffer.floatBuffer.put(index * COLOR_ELEMENTS_COUNT + 1, color.y);
                colorBuffer.floatBuffer.put(index * COLOR_ELEMENTS_COUNT + 2, color.z);
                colorBuffer.floatBuffer.put(index * COLOR_ELEMENTS_COUNT + 3, color.w);
        }
       
        public int getColorCount()
        {
                return colorBuffer.floatBuffer.limit() / COLOR_ELEMENTS_COUNT;
        }
       
        public Vector4 getColor(int index)
        {
                return new Vector4(
                                colorBuffer.floatBuffer.get(index * COLOR_ELEMENTS_COUNT + 0),
                                colorBuffer.floatBuffer.get(index * COLOR_ELEMENTS_COUNT + 1),
                                colorBuffer.floatBuffer.get(index * COLOR_ELEMENTS_COUNT + 2),
                                colorBuffer.floatBuffer.get(index * COLOR_ELEMENTS_COUNT + 3));
        }
       
        public void setNormal(int index, Vector3 normal)
        {
                normalBuffer.floatBuffer.put(index * NORMAL_ELEMENTS_COUNT + 0, normal.x);
                normalBuffer.floatBuffer.put(index * NORMAL_ELEMENTS_COUNT + 1, normal.y);
                normalBuffer.floatBuffer.put(index * NORMAL_ELEMENTS_COUNT + 2, normal.z);
        }

        public Vector3 getNormal(int index)
        {
                return new Vector3(
                                normalBuffer.floatBuffer.get(index * NORMAL_ELEMENTS_COUNT + 0),
                                normalBuffer.floatBuffer.get(index * NORMAL_ELEMENTS_COUNT + 1),
                                normalBuffer.floatBuffer.get(index * NORMAL_ELEMENTS_COUNT + 2));
        }
       
        public int getNormalCount()
        {
                return normalBuffer.floatBuffer.limit() / NORMAL_ELEMENTS_COUNT;
        }
       
        public void setTexCoord(int index, Vector2 texCoord)
        {
                texCoordBuffer.floatBuffer.put(index * TEX_COORD_ELEMENTS_COUNT + 0, texCoord.x);
                texCoordBuffer.floatBuffer.put(index * TEX_COORD_ELEMENTS_COUNT + 1, texCoord.y);
        }
       
        public Vector2 getTexCoord(int index)
        {
                return new Vector2(
                                texCoordBuffer.floatBuffer.get(index * TEX_COORD_ELEMENTS_COUNT + 0),
                                texCoordBuffer.floatBuffer.get(index * TEX_COORD_ELEMENTS_COUNT + 1));
        }      
       
        public int getTexCoordCount()
        {
                return texCoordBuffer.floatBuffer.limit() / TEX_COORD_ELEMENTS_COUNT;
        }
       
       
        /**
         * Activate the vertex buffer for rendering
         */

        public void activate()
        {
               
                GL10 gl = GLUtil.getGL();
               
                if (vertexBuffer != null)
                {
                        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);                  
                        gl.glVertexPointer(COORD_ELEMENTS_COUNT, GL10.GL_FLOAT, 0, vertexBuffer.floatBuffer);
                }
                if (colorBuffer != null)
                {
                        gl.glEnableClientState(GL10.GL_COLOR_ARRAY);                   
                        gl.glColorPointer(COLOR_ELEMENTS_COUNT, GL10.GL_FLOAT, 0, colorBuffer.floatBuffer);
                }
                if (normalBuffer != null)
                {
                        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);
                        gl.glNormalPointer(GL10.GL_FLOAT, 0, normalBuffer.floatBuffer);
                }
                if (texCoordBuffer != null)
                {
                        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
                        gl.glTexCoordPointer(TEX_COORD_ELEMENTS_COUNT, GL10.GL_FLOAT, 0, texCoordBuffer.floatBuffer);
                }
        }
       
        /**
         * Deactivate the vertex buffer for rendering
         */

        public void deactivate()
        {
                GL10 gl = GLUtil.getGL();
               
                if (vertexBuffer != null)
                {
                        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
                }
                if (colorBuffer != null)
                {
                        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
                }
                if (normalBuffer != null)
                {
                        gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
                }
                if (texCoordBuffer != null)
                {
                        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
                }
        }
       
        public void setPrimitiveType(int primitiveType)
        {
                mPrimitiveType = primitiveType;
        }
       
        /**
         * Render the vertex buffer
         */

        public void render()
        {              
                GL10 gl = GLUtil.getGL();
               
                activate();
               
                if (indexBuffer != null)
                {
                        // indexed drawing
                        gl.glDrawElements(mPrimitiveType, indexBuffer.length, GL10.GL_UNSIGNED_SHORT, indexBuffer.shortBuffer);
                }
                else if (vertexBuffer != null)
                {                      
                        // non-indexed drawing
                        gl.glDrawArrays(mPrimitiveType, 0, vertexBuffer.length);
                }
               
                deactivate();
        }
       
        /**
         * Render the vertex buffer with a specified amount of primitives
         */

        public void render(int numPrimitives)
        {
                GL10 gl = GLUtil.getGL();
               
                activate();
               
                if (indexBuffer != null)
                {
                        // indexed drawing
                        gl.glDrawElements(mPrimitiveType, numPrimitives, GL10.GL_UNSIGNED_SHORT, indexBuffer.shortBuffer);
                }
                else if (vertexBuffer != null)
                {                      
                        // non-indexed drawing
                        gl.glDrawArrays(mPrimitiveType, 0, numPrimitives);
                }
               
                deactivate();
        }
       
}