package com.gebauz.Bauzoid.graphics.model;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import android.opengl.GLES20;
import com.gebauz.Bauzoid.math.Vector2;
import com.gebauz.Bauzoid.math.Vector3;
import com.gebauz.Bauzoid.math.Vector4;
/** Simple Geometry class that manages vertex buffers and index buffers. */
public class SimpleGeometry
{
static final int SIZEOF_FLOAT =
Float.
SIZE /
8;
static final int SIZEOF_SHORT =
Short.
SIZE /
8;
/** 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 =
0;
private int mID =
0;
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 void createBuffer
()
{
GLES20.
glGenBuffers(1, BUFFERID,
0);
mID = BUFFERID
[0];
GLES20.
glBindBuffer(GLES20.
GL_ARRAY_BUFFER, mID
);
GLES20.
glBufferData(GLES20.
GL_ARRAY_BUFFER, floatBuffer.
capacity() * SIZEOF_FLOAT, floatBuffer, GLES20.
GL_STATIC_DRAW);
GLES20.
glBindBuffer(GLES20.
GL_ARRAY_BUFFER,
0);
}
public void destroyBuffer
()
{
if (mID
!=
0)
{
BUFFERID
[0] = mID
;
GLES20.
glDeleteBuffers(1, BUFFERID,
0);
mID =
0;
}
}
public void bindBuffer
(int attribHandle,
int numComponents
)
{
// TODO: state tracking for bindbuffer
GLES20.
glBindBuffer(GLES20.
GL_ARRAY_BUFFER, mID
);
GLES20.
glVertexAttribPointer(attribHandle, numComponents, GLES20.
GL_FLOAT,
false,
0,
0);
GLES20.
glEnableVertexAttribArray(attribHandle
);
}
public void unbindBuffer
()
{
GLES20.
glBindBuffer(GLES20.
GL_ARRAY_BUFFER,
0);
}
}
public class IndexBuffer
{
public ByteBuffer byteBuffer
;
public ShortBuffer shortBuffer
;
public int length =
0;
private int mID =
0;
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;
}
public void createBuffer
()
{
GLES20.
glGenBuffers(1, BUFFERID,
0);
mID = BUFFERID
[0];
GLES20.
glBindBuffer(GLES20.
GL_ELEMENT_ARRAY_BUFFER, mID
);
GLES20.
glBufferData(GLES20.
GL_ELEMENT_ARRAY_BUFFER, shortBuffer.
capacity() * SIZEOF_SHORT, shortBuffer, GLES20.
GL_STATIC_DRAW);
GLES20.
glBindBuffer(GLES20.
GL_ELEMENT_ARRAY_BUFFER,
0);
}
public void destroyBuffer
()
{
if (mID
!=
0)
{
BUFFERID
[0] = mID
;
GLES20.
glDeleteBuffers(1, BUFFERID,
0);
mID =
0;
}
}
public void bindBuffer
()
{
if (mID ==
0)
return;
// TODO: state tracking for bindbuffer
GLES20.
glBindBuffer(GLES20.
GL_ELEMENT_ARRAY_BUFFER, mID
);
}
public void unbindBuffer
()
{
GLES20.
glBindBuffer(GLES20.
GL_ELEMENT_ARRAY_BUFFER,
0);
}
}
private AttributeBuffer mVertexBuffer =
null;
private AttributeBuffer mColorBuffer =
null;
private AttributeBuffer mNormalBuffer =
null;
private AttributeBuffer mTexCoordBuffer =
null;
private IndexBuffer mIndexBuffer =
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 = GLES20.
GL_TRIANGLES;
public static final int COORD_ATTRIB_INDEX =
0;
public static final int COLOR_ATTRIB_INDEX =
1;
public static final int TEX_COORD_ATTRIB_INDEX =
2;
public static final int NORMAL_ATTRIB_INDEX =
3;
public static int BUFFERID
[] =
new int[1];
public SimpleGeometry
()
{
}
/** Create the vertex buffer objects after modifying the attribute buffers. */
public void createBuffers
()
{
if (mVertexBuffer
!=
null)
mVertexBuffer.
createBuffer();
if (mColorBuffer
!=
null)
mColorBuffer.
createBuffer();
if (mNormalBuffer
!=
null)
mNormalBuffer.
createBuffer();
if (mTexCoordBuffer
!=
null)
mTexCoordBuffer.
createBuffer();
if (mIndexBuffer
!=
null)
mIndexBuffer.
createBuffer();
}
/** Destroy all buffers. */
public void destroyBuffers
()
{
if (mVertexBuffer
!=
null)
mVertexBuffer.
destroyBuffer();
if (mColorBuffer
!=
null)
mColorBuffer.
destroyBuffer();
if (mNormalBuffer
!=
null)
mNormalBuffer.
destroyBuffer();
if (mTexCoordBuffer
!=
null)
mTexCoordBuffer.
destroyBuffer();
if (mIndexBuffer
!=
null)
mIndexBuffer.
destroyBuffer();
}
/** Activate the vertex buffer for rendering */
public void activate
()
{
if (mVertexBuffer
!=
null)
mVertexBuffer.
bindBuffer(COORD_ATTRIB_INDEX, COORD_ELEMENTS_COUNT
);
if (mColorBuffer
!=
null)
mColorBuffer.
bindBuffer(COLOR_ATTRIB_INDEX, COLOR_ELEMENTS_COUNT
);
if (mNormalBuffer
!=
null)
mNormalBuffer.
bindBuffer(NORMAL_ATTRIB_INDEX, NORMAL_ELEMENTS_COUNT
);
if (mTexCoordBuffer
!=
null)
mTexCoordBuffer.
bindBuffer(TEX_COORD_ATTRIB_INDEX, TEX_COORD_ELEMENTS_COUNT
);
if (mIndexBuffer
!=
null)
mIndexBuffer.
bindBuffer();
}
/**
* Deactivate the vertex buffer for rendering
*/
public void deactivate
()
{
if (mVertexBuffer
!=
null)
mVertexBuffer.
unbindBuffer();
if (mColorBuffer
!=
null)
mColorBuffer.
unbindBuffer();
if (mNormalBuffer
!=
null)
mNormalBuffer.
unbindBuffer();
if (mTexCoordBuffer
!=
null)
mTexCoordBuffer.
unbindBuffer();
if (mIndexBuffer
!=
null)
mIndexBuffer.
unbindBuffer();
}
public void setPrimitiveType
(int primitiveType
)
{
mPrimitiveType = primitiveType
;
}
/**
* Render the vertex buffer
*/
public void render
()
{
activate
();
if (mIndexBuffer
!=
null)
{
GLES20.
glDrawElements(mPrimitiveType, mIndexBuffer.
length, GLES20.
GL_UNSIGNED_SHORT,
0);
}
else
{
GLES20.
glDrawArrays(mPrimitiveType,
0, mVertexBuffer.
length);
}
deactivate
();
/* GL10 gl = GLUtil.getGL();
activate();
if (mIndexBuffer != null)
{
// indexed drawing
gl.glDrawElements(mPrimitiveType, mIndexBuffer.length, GL10.GL_UNSIGNED_SHORT, mIndexBuffer.shortBuffer);
}
else if (mVertexBuffer != null)
{
// non-indexed drawing
gl.glDrawArrays(mPrimitiveType, 0, mVertexBuffer.length);
}
deactivate();*/
}
/**
* Render the vertex buffer with a specified amount of primitives
*/
public void render
(int numPrimitives
)
{
/* GL10 gl = GLUtil.getGL();
activate();
if (mIndexBuffer != null)
{
// indexed drawing
gl.glDrawElements(mPrimitiveType, numPrimitives, GL10.GL_UNSIGNED_SHORT, mIndexBuffer.shortBuffer);
}
else if (mVertexBuffer != null)
{
// non-indexed drawing
gl.glDrawArrays(mPrimitiveType, 0, numPrimitives);
}
deactivate();*/
}
public void setVertices
(float vertices
[])
{
if (vertices ==
null)
{
mVertexBuffer =
null;
return;
}
mVertexBuffer =
new AttributeBuffer
(vertices
);
}
public void setColors
(float colors
[])
{
if (colors ==
null)
{
mColorBuffer =
null;
return;
}
mColorBuffer =
new AttributeBuffer
(colors
);
}
public void setNormals
(float normals
[])
{
if (normals ==
null)
{
mNormalBuffer =
null;
return;
}
mNormalBuffer =
new AttributeBuffer
(normals
);
}
public void setTexCoords
(float texCoords
[])
{
if (texCoords ==
null)
{
mTexCoordBuffer =
null;
return;
}
mTexCoordBuffer =
new AttributeBuffer
(texCoords
);
}
public void setIndices
(short indices
[])
{
if (indices ==
null)
{
mIndexBuffer =
null;
return;
}
mIndexBuffer =
new IndexBuffer
(indices
);
}
public void setVertex
(int index, Vector3 vertex
)
{
mVertexBuffer.
floatBuffer.
put(index
* COORD_ELEMENTS_COUNT +
0, vertex.
x);
mVertexBuffer.
floatBuffer.
put(index
* COORD_ELEMENTS_COUNT +
1, vertex.
y);
mVertexBuffer.
floatBuffer.
put(index
* COORD_ELEMENTS_COUNT +
2, vertex.
z);
}
public Vector3 getVertex
(int index
)
{
return new Vector3
(
mVertexBuffer.
floatBuffer.
get(index
* COORD_ELEMENTS_COUNT +
0),
mVertexBuffer.
floatBuffer.
get(index
* COORD_ELEMENTS_COUNT +
1),
mVertexBuffer.
floatBuffer.
get(index
* COORD_ELEMENTS_COUNT +
2));
}
public int getVertexCount
()
{
return mVertexBuffer.
floatBuffer.
limit() / COORD_ELEMENTS_COUNT
;
}
public void setColor
(int index, Vector4 color
)
{
mColorBuffer.
floatBuffer.
put(index
* COLOR_ELEMENTS_COUNT +
0, color.
x);
mColorBuffer.
floatBuffer.
put(index
* COLOR_ELEMENTS_COUNT +
1, color.
y);
mColorBuffer.
floatBuffer.
put(index
* COLOR_ELEMENTS_COUNT +
2, color.
z);
mColorBuffer.
floatBuffer.
put(index
* COLOR_ELEMENTS_COUNT +
3, color.
w);
}
public int getColorCount
()
{
return mColorBuffer.
floatBuffer.
limit() / COLOR_ELEMENTS_COUNT
;
}
public Vector4 getColor
(int index
)
{
return new Vector4
(
mColorBuffer.
floatBuffer.
get(index
* COLOR_ELEMENTS_COUNT +
0),
mColorBuffer.
floatBuffer.
get(index
* COLOR_ELEMENTS_COUNT +
1),
mColorBuffer.
floatBuffer.
get(index
* COLOR_ELEMENTS_COUNT +
2),
mColorBuffer.
floatBuffer.
get(index
* COLOR_ELEMENTS_COUNT +
3));
}
public void setNormal
(int index, Vector3 normal
)
{
mNormalBuffer.
floatBuffer.
put(index
* NORMAL_ELEMENTS_COUNT +
0, normal.
x);
mNormalBuffer.
floatBuffer.
put(index
* NORMAL_ELEMENTS_COUNT +
1, normal.
y);
mNormalBuffer.
floatBuffer.
put(index
* NORMAL_ELEMENTS_COUNT +
2, normal.
z);
}
public Vector3 getNormal
(int index
)
{
return new Vector3
(
mNormalBuffer.
floatBuffer.
get(index
* NORMAL_ELEMENTS_COUNT +
0),
mNormalBuffer.
floatBuffer.
get(index
* NORMAL_ELEMENTS_COUNT +
1),
mNormalBuffer.
floatBuffer.
get(index
* NORMAL_ELEMENTS_COUNT +
2));
}
public int getNormalCount
()
{
return mNormalBuffer.
floatBuffer.
limit() / NORMAL_ELEMENTS_COUNT
;
}
public void setTexCoord
(int index, Vector2 texCoord
)
{
mTexCoordBuffer.
floatBuffer.
put(index
* TEX_COORD_ELEMENTS_COUNT +
0, texCoord.
x);
mTexCoordBuffer.
floatBuffer.
put(index
* TEX_COORD_ELEMENTS_COUNT +
1, texCoord.
y);
}
public Vector2 getTexCoord
(int index
)
{
return new Vector2
(
mTexCoordBuffer.
floatBuffer.
get(index
* TEX_COORD_ELEMENTS_COUNT +
0),
mTexCoordBuffer.
floatBuffer.
get(index
* TEX_COORD_ELEMENTS_COUNT +
1));
}
public int getTexCoordCount
()
{
return mTexCoordBuffer.
floatBuffer.
limit() / TEX_COORD_ELEMENTS_COUNT
;
}
}