This may seem like a silly question but i feel i need to ask it so i can understand how openGl buffers work.
I have two buffers , vertex buffer and index buffer. To fill these buffers i am parsing an obj file.
After parsing the data i fill the buffers with what i think is the correct data and order of data.
However when i debug the code i see some strange things in the buffers.
Firstly the vertex buffer. The first 3 values that i put in the Vbuffer are
0.99,-0.99,-0.7741
However when i check the buffer by steping through the values are
-92,112,125
is this because this is a FloatBuffer but as a byte buffer?
this.vertexBuffer = ByteBuffer.allocateDirect(VertexList.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
this.vertexBuffer.put(VertexList);
this.vertexBuffer.position(0);
The index buffer is different i put in
4,1,2
and when i check it i seem to get an extra 0 between each value
4,0,1,0,2
this.IndexBuffer = ByteBuffer.allocateDirect(IndexList.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
this.IndexBuffer.put(IndexList);
this.IndexBuffer.position(0);
in this buffer i can read the data as ShortBuffer even though its a byte buffer.
Also why is every other value a 0?
Any help understanding this would be appreciated.
UPDATE!
This is my full code for parsing the data from an obj file and filling the buffers. The data that gets put into the buffers appears to be correct.
public class RBLoadModelFromFile
{
/** How many bytes per float. */
private final int mBytesPerFloat = 4;
private Context context;
public FloatBuffer vertexBuffer;
public ShortBuffer IndexBuffer;
public float[] vertices;
public float[] normals;
public float[] uVs;
public short[] Ind;
private ArrayList<Short> indicies;
public int NumVertices;
public int NumIndicies;
public RBLoadModelFromFile(Context c)
{
context = c;
}
public void loadModel(String filename)
{
ArrayList<RBVector3> tempVertices = new ArrayList<RBVector3>();
ArrayList<RBVector3> tempNormals = new ArrayList<RBVector3>();
ArrayList<RBVector3> tempUVs = new ArrayList<RBVector3>();
ArrayList<Short> vertexIndices = new ArrayList<Short>();
ArrayList<Short> normalIndices = new ArrayList<Short>();
ArrayList<Short> textureIndices = new ArrayList<Short>();
indicies = new ArrayList<Short>();
try {
AssetManager manager = context.getAssets();
BufferedReader reader = new BufferedReader(new InputStreamReader(manager.open(filename)));
String line;
while ((line = reader.readLine()) != null)
{
if (line.startsWith("v "))
{
RBVector3 tempVert = new RBVector3(0f,0f,0f);
tempVert.add(Float.valueOf(line.split(" ")[2]),Float.valueOf(line.split(" ")[3]),Float.valueOf(line.split(" ")[4]));
tempVertices.add(tempVert);
}
else if (line.startsWith("vn"))
{
RBVector3 tempNorm = new RBVector3(0f,0f,0f);
tempNorm.add(Float.valueOf(line.split(" ")[1]),Float.valueOf(line.split(" ")[2]),Float.valueOf(line.split(" ")[3]));
tempNormals.add(tempNorm);
}
else if (line.startsWith("vt"))
{
RBVector3 tempUV = new RBVector3(0f,0f,0f);
tempUV.add(Float.valueOf(line.split(" ")[1]),Float.valueOf(line.split(" ")[2]), 0f);
tempUVs.add(tempUV);
}
else if (line.startsWith("f"))
{
String tmp[] = line.split(" ");
vertexIndices.add(Short.valueOf(tmp[1].split("/")[0]));
textureIndices.add(Short.valueOf(tmp[1].split("/")[1]));
normalIndices.add(Short.valueOf(tmp[1].split("/")[2]));
vertexIndices.add(Short.valueOf(tmp[2].split("/")[0]));
textureIndices.add(Short.valueOf(tmp[2].split("/")[1]));
normalIndices.add(Short.valueOf(tmp[2].split("/")[2]));
vertexIndices.add(Short.valueOf(tmp[3].split("/")[0]));
textureIndices.add(Short.valueOf(tmp[3].split("/")[1]));
normalIndices.add(Short.valueOf(tmp[3].split("/")[2]));
}
}
Ind = new short[vertexIndices.size() + normalIndices.size() + textureIndices.size()];
vertices = new float[(vertexIndices.size() * 3) + (normalIndices.size() * 3) + (textureIndices.size() * 2)];
ArrayList<Float> vertInfo = new ArrayList<Float>();
for (int i = 0; i < vertexIndices.size(); i++)
{
Short v = vertexIndices.get(i);
vertInfo.add(tempVertices.get(v-1).x);
vertInfo.add(tempVertices.get(v-1).y);
vertInfo.add(tempVertices.get(v-1).z);
indicies.add((short) (v-1));
Short n = normalIndices.get(i);
vertInfo.add(tempNormals.get(n-1).x);
vertInfo.add(tempNormals.get(n-1).y);
vertInfo.add(tempNormals.get(n-1).z);
indicies.add((short) (n-1));
Short t = textureIndices.get(i);
vertInfo.add(tempUVs.get(t-1).x);
vertInfo.add(tempUVs.get(t-1).y);
indicies.add((short) (t-1));
}
for(int i = 0; i < indicies.size(); i++)
{
Ind[i] = indicies.get(i);
}
for (int i = 0; i < vertInfo.size(); i++)
{
vertices[i] = vertInfo.get(i);
}
createIndexBuffer(Ind);
createVertexBuffer(vertices);
NumIndicies = Ind.length;
NumVertices = vertices.length;
}
catch (Exception e)
{
Log.d("DEBUG", "Error.", e);
}
}
private void createVertexBuffer(float[] VertexList)
{
this.vertexBuffer = ByteBuffer.allocateDirect(VertexList.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
this.vertexBuffer.put(VertexList);
this.vertexBuffer.position(0);
}
private void createIndexBuffer(short[] IndexList)
{
this.IndexBuffer = ByteBuffer.allocateDirect(IndexList.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
this.IndexBuffer.put(IndexList);
this.IndexBuffer.position(0);
}
}
and here is a simple cube obj file that i am trying to parse
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
f 1/1/1 2/2/1 3/3/1
f 3/3/1 2/2/1 4/4/1
f 3/1/2 4/2/2 5/3/2
f 5/3/2 4/2/2 6/4/2
f 5/4/3 6/3/3 7/2/3
f 7/2/3 6/3/3 8/1/3
f 7/1/4 8/2/4 1/3/4
f 1/3/4 8/2/4 2/4/4
f 2/1/5 8/2/5 4/3/5
f 4/3/5 8/2/5 6/4/5
f 7/1/6 1/2/6 5/3/6
f 5/3/6 1/2/6 3/4/6
I am now getting something draw but the vertices seems to be way off.
this is now my drawing method
public void DrawModel(float[] mProjectionMatrix, float[] mViewMatrix, float[] mMVPMatrix, int mProgramHandle, int mMVPMatrixHandle, int mMVMatrixHandle, int mLightPosHandle, float[] mLightPosInEyeSpace)
{
mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
mNormalHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Normal");
mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Texture");
mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
// Pass in the modelview matrix.
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
// Pass in the combined matrix.
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Pass in the light position in eye space.
GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
// the vertex coordinates
VertexBuffer.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, VertexBuffer);
GLES20.glEnableVertexAttribArray(mPositionHandle);
// the normal info
VertexBuffer.position(TRIANGLE_VERTICES_DATA_NOR_OFFSET);
GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, VertexBuffer);
GLES20.glEnableVertexAttribArray(mNormalHandle);
// texture coordinates
VertexBuffer.position(TRIANGLE_VERTICES_DATA_TEX_OFFSET);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, VertexBuffer);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);//GLES20.glEnableVertexAttribArray(shader.maTextureHandle);
// Draw with indices
GLES20.glDrawElements(GLES20.GL_TRIANGLES, NumIndicies , GLES20.GL_UNSIGNED_SHORT, IndexBuffer);
//checkGlError("glDrawElements");
}