opengl es 2.0填充Vertex和index Buffer

时间:2014-04-10 19:27:15

标签: java android memory buffer opengl-es-2.0

这可能看起来像一个愚蠢的问题,但我觉得我需要问它所以我能理解openGl缓冲如何工作。

我有两个缓冲区,顶点缓冲区和索引缓冲区。为了填充这些缓冲区,我正在解析一个obj文件。

解析数据后,我用我认为正确的数据和数据顺序填充缓冲区。

然而,当我调试代码时,我在缓冲区中看到了一些奇怪的东西。

首先是顶点缓冲区。我放在Vbuffer中的前三个值是 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);

我输入的索引缓冲区不同 4,1,2 当我检查它时,我似乎在每个值之间得到额外的0 4,0,1,0,2

    this.IndexBuffer = ByteBuffer.allocateDirect(IndexList.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
    this.IndexBuffer.put(IndexList);
    this.IndexBuffer.position(0);

在这个缓冲区中我可以将数据读取为ShortBuffer,即使它是一个字节缓冲区。 另外,为什么其他每个值都为0?

理解这一点的任何帮助都将受到赞赏。

UPDATE!

这是我完整的代码,用于解析obj文件中的数据并填充缓冲区。放入缓冲区的数据似乎是正确的。

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

这是一个简单的立方体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

我现在正在画画,但顶点似乎已经过了。

这是我的绘图方法

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

2 个答案:

答案 0 :(得分:1)

没有完整的代码来判断问题的位置是相当复杂的。

在我看来,您正在使用混合数据类型。

浮点数相当棘手,如果不将它们作为浮点数处理,则无法轻易“读取”浮点存储单元的内容。

Float,根据标准是基于3个不同的组件,位符号(最有意义的),指数和尾数。

通常是浮点数,现在最常见的平台用32位(4字节)表示,其中:

1为标志 指数为8位 尾数为23位(通常是打包的,但这将是一个很长的讨论)

如果你没有“读取”或“写”一个浮点数作为一个浮点数(有些方法可以处理整数浮点作为整数知道它们的属性,但这会有太大的偏离性)你以不可预测的方式解释它们的风险。 / p>

我的建议是将这些值读/写为float,不要以读/写操作的字节/整数方式进行。

答案 1 :(得分:0)

好的,我终于设法解决了渲染问题。我非常感谢@MaurizioBenedetti评论并回答了我的一些问题,这些问题帮助我了解了我的情况。

首先,我在缓冲区中放入的内容在某种程度上是正确的。我的问题来了,因为我创建了一个交错的顶点缓冲区 - 这意味着数据已经按正确的顺序VVVNNNTT。然后我去创建了索引缓冲区,其中包含实际的索引数据,这是无交错缓冲区的指示

例如,如果面包含2/4/6 4/7/9 2/1/3,那么我的索引缓冲区包含这些确切的值,但因为我的顶点缓冲区是交错的,所以它应该包含一个有序列表的数量indicies。

所以这意味着如果上面的面是唯一的指标,那么索引缓冲区应该包含 0,1,2,3,4,5,6,7,8

在我填充顶点信息时总结上面的代码

我应该说过这样的话

indicies.add(index++);

而不是分配每个标记值

我希望对于那些坚持这种事情并希望有所帮助的人来说这是明确的。