简体   繁体   English

opengl es 2.0填充顶点和索引缓冲区

[英]opengl es 2.0 populating the Vertex and index Buffer

This may seem like a silly question but i feel i need to ask it so i can understand how openGl buffers work. 这似乎是一个愚蠢的问题,但是我觉得我需要问这个问题,这样我才能了解openGl缓冲区的工作方式。

I have two buffers , vertex buffer and index buffer. 我有两个缓冲区,顶点缓冲区和索引缓冲区。 To fill these buffers i am parsing an obj file. 为了填充这些缓冲区,我正在解析一个obj文件。

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? 我在Vbuffer中输入的前3个值是0.99,-0.99,-0.7741,但是当我通过逐步检查值来检查缓冲区时是-92,112,125,这是因为这是一个FloatBuffer但作为字节缓冲区吗?

    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 索引缓冲区是不同的,我放入4,1,2,当我检查它时,我似乎在每个值4,0,1,0,2之间得到一个额外的0

    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. 在此缓冲区中,即使它是字节缓冲区,我也可以将数据读取为ShortBuffer。 Also why is every other value a 0? 另外为什么其他所有值都为0?

Any help understanding this would be appreciated. 任何帮助理解这一点将不胜感激。

UPDATE! UPDATE!

This is my full code for parsing the data from an obj file and filling the buffers. 这是我解析obj文件中的数据并填充缓冲区的完整代码。 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 这是我要解析的一个简单的多维数据集obj文件

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");
}

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. 根据标准,浮点数基于3个不同的分量,即位符号(最有意义),指数和尾数。

Usually floats, on nowadays most common platforms are represented with 32 bit (4 bytes) where: 通常是浮动的,在当今最常见的平台上用32位(4字节)表示,其中:

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) 1表示符号,8表示指数,23表示尾数(通常打包,但这将在此处进行很长的讨论)

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. 我的建议是将这些值读/写为浮点,并且不要以读/写操作字节/整数的方式进行操作。

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. 快速感谢@MaurizioBenedetti,因为他评论并回答了我的一些问题,这帮助我到达了我所在的位置。

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. 我的问题来了,因为我创建了一个交错的顶点缓冲区-这意味着数据已经按照正确的顺序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. 例如,如果面包含2/4/6 4/7/9 2/1/3,则我的索引缓冲区包含这些确切值,但是由于我的顶点缓冲区是交错的,因此它应该包含索引数量的有序列表。

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 因此,这意味着如果上述面是唯一的指标,则索引缓冲区应包含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. 我希望这对那些坚持这种事情并希望会有所帮助的人来说都是清楚的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM