切换到使用交错 VBO - 编译但没有绘制 - opengl es 2.0

Posted

技术标签:

【中文标题】切换到使用交错 VBO - 编译但没有绘制 - opengl es 2.0【英文标题】:Switching to use Interleaved VBO's - compiles but nothing is drawn - opengl es 2.0 【发布时间】:2014-04-09 09:38:49 【问题描述】:

我刚刚尝试切换到使用交错 VBO。我已经逐步完成了创建交错式 VBO 的过程,并且它似乎具有正确的 init 信息。

VVV NNN TT 等

这里是初始化缓冲区的代码

VertexBuffer = Loader.vertexBuffer;     

final int buffers[] = new int[1];
GLES20.glGenBuffers(1, buffers, 0); 

GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, VertexBuffer.capacity(), VertexBuffer, GLES20.GL_STATIC_DRAW);  

GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

mBufferIdx = buffers[0];    

VertexBuffer.limit(0);
VertexBuffer = null;

这是我绘制模型的代码

final int stride = (mPositionDataSize + mNormalDataSize + mTextureCoordinateDataSize) * mBytesPerFloat;

// Pass in the position information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBufferIdx);
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GL_FLOAT, false, stride, 0);

// Pass in the normal information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBufferIdx);
GLES20.glEnableVertexAttribArray(mNormalHandle);
GLES20.glVertexAttribPointer(mNormalHandle, mNormalDataSize, GLES20.GL_FLOAT, false, stride,   mPositionDataSize * mBytesPerFloat);

// Pass in the texture information
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mBufferIdx);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize,  GLES20.GL_FLOAT, false,
stride, (mPositionDataSize + mNormalDataSize) * mBytesPerFloat);


// Clear the currently bound buffer (so future OpenGL calls do not use this buffer).
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

// Draw .
GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, NumVertices);

我让矩阵在使用 VBO 之前工作正常,并且我正确地看到了所有句柄。

我的应用运行起来好像模型就在那里,但只是不可见。例如,我正在移动一个模型,并在它到达某个位置时被告知,我只是无法像在移动到 VBO 之前那样看到它。

如果我需要上传其他内容,请告诉我。任何建议将不胜感激。

更新!

我认为问题可能在于我在这里创建交错 VBO 的方式是代码

private void createVertexBuffer(float[] VertexList, float[] NormalList, float[] TextureList)

    final int vertexDataSize = VertexList.length + NormalList.length + TextureList.length;
    this.vertexBuffer = ByteBuffer.allocateDirect(vertexDataSize * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();

    int PositionOffset = 0;
    int NormalOffset = 0;
    int TextureOffset = 0;

    for(int i = 0; i < NumVerts; i++)
                           
        this.vertexBuffer.put(VertexList, PositionOffset, mPositionDataSize);
        PositionOffset += mPositionDataSize;
        this.vertexBuffer.put(NormalList, NormalOffset, mNormalDataSize);
        NormalOffset += mNormalDataSize;
        this.vertexBuffer.put(TextureList, TextureOffset, mTextureCoordinateDataSize);
        TextureOffset += mTextureCoordinateDataSize;            
    
    this.vertexBuffer.position(0);

我做错了什么?

更新代码

 mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVPMatrix");
    mMVMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_MVMatrix");
    mLightPosHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_LightPos");
    //mColorHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Color");

    Cube1.mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Texture");
    Cube1.mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
    Cube1.mNormalHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Normal");
    Cube1.mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");

 Cube1.SetTexture();
    Cube1.SetIdentity();
    Cube1.SetPosition();
    Cube1.SetScale(10.0f, 10.0f, 10.0f);
    Cube1.SetRotation(RotationAngle, 0.0f, 0.0f, 1.0f);
    Cube1.DrawModel(mProjectionMatrix, mViewMatrix, mMVPMatrix, mMVPMatrixHandle, mMVMatrixHandle, mLightPosHandle, mLightPosInEyeSpace); 

public void SetTexture()

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

【问题讨论】:

我抢,您在不同的 VertexAttribPointer 中设置的步幅/大小偏移似乎存在某种问题。你能报告你设置不同的 mPositionDataSize 、 mNormalDataSize 、 mTextureCoordinateDataSize 的方式吗?函数参数(非常脏的计算方式)应该是 0 x sizeof(float)、3 x sizeof(float)、6 x sizeof(float)。像这样的东西。尝试检查或报告这两个变量。再见。毛里齐奥 嗨@MaurizioBenedetti我将这些设置为在类的开始处的最终整数 private final int mBytesPerFloat = 4;私有最终 int mPositionDataSize = 3;私有最终 int mNormalDataSize = 3;私有最终 int mTextureCoordinateDataSize = 2; 当你说这是一种非常肮脏的计算方式(意思是createvertexbuffer方法?)有没有更好的方法呢? @MaurizioBenedetti 我已经检查了缓冲区以及我填充它的方式。我认为问题不存在,所以我回到了步幅/大小。你还有什么建议吗? 嗨,罗伯。我一直在再次审查您的代码,一切看起来都很好。只是一个简短的说明,你在哪里绑定纹理?由于您正在传递纹理坐标,我猜 frag_color 是根据纹理计算的。我在您的代码中看不到着色器或纹理绑定。我建议审查那部分。如果您使用着色器,您可以尝试非常简单地将 frag_color 强制为固定值(即黑屏为白色或白屏为黑色),以查看是否至少处理了几何信息。 【参考方案1】:

我不确定上述代码中的问题是什么,我是如何重新编写代码以使用索引缓冲区并在另一个问题中提交的。找到here

除了我在另一个问题中给出的答案之外,它应该为任何正在苦苦挣扎的人提供一种明确的方式来介绍 VBO 和 IBO

【讨论】:

以上是关于切换到使用交错 VBO - 编译但没有绘制 - opengl es 2.0的主要内容,如果未能解决你的问题,请参考以下文章

opengl交错vbo不渲染到屏幕

VBO 中的交错是帮助还是阻碍性能?

交错的 VBO 导致 glDrawArrays() 错误

打开 GL ES 2.0 为啥我的 VBO 不工作?

各种顶点格式和vbo

OpenGL:尝试使用 VBO(顶点缓冲区对象)绘制线条,它不显示