Question

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");
}
Was it helpful?

Solution 2

Ok i have finally managed to solve my rendering issue. quick thanks to @MaurizioBenedetti as he has commented and answered some of my questions which has helped me get to where i am.

Firstly what i am putting into the buffers is correct to some extent. My Problem comes because i create a interleaved vertex buffer - this means the data is already in the correct order VVVNNNTT. Then i went and created the index buffer which contained the actual index data which is the indicies for a none interleaved buffer

for example if the faces contained 2/4/6 4/7/9 2/1/3 then my index buffer contained these exact values but because my vertex buffer is interleaved it should have containd an ordered list of the number of indicies.

So this means if the above faces were the only indicies then the index buffer should have contained 0,1,2,3,4,5,6,7,8

to sum up in the above code when i populate the vertex info

I should have said something like this

indicies.add(index++);

Instead of assigning each indicie value

I hope this is clear for anyone who is stuck on this sort of thing and will hopefully help.

OTHER TIPS

not having the whole code is rather complicated to judge where the problem is.

It looks to me that you are working mixing data types.

The float numbers are rather tricky and if you do not handle them as floats you cannot easily "read" the content of a float memory unit.

Float, according to the standard is based on 3 different components, the bit sign (the most significative), the exponent and the mantissa.

Usually floats, on nowadays most common platforms are represented with 32 bit (4 bytes) where:

1 for the sign 8 bits for the exponent 23 bits for the mantissa (which is usually packed, but this would be a long discussion to be taken here)

If you do not "read" or "write" a float as a float (there are ways to handle floats as integer knowing their properties but this would go too much offtopic) your risk to interpret them in an unpredictable manner.

My advice is to read/write those values as float and do not go in a read/write operation byte/integer wise.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top