GLES2.0 上的 VBO glDrawElements 和 glVertexAttribPointer 不显示任何内容

Posted

技术标签:

【中文标题】GLES2.0 上的 VBO glDrawElements 和 glVertexAttribPointer 不显示任何内容【英文标题】:VBO glDrawElements and glVertexAttribPointer on GLES2.0 displays nothing 【发布时间】:2011-08-03 03:40:07 【问题描述】:

我可以像这样使用着色器、glVertexAttribPointer 和 glDrawArrays 显示纹理:

初始化

const GLfloat squareVertices[] = 
    -0.5f, -0.33f,
    0.5f, -0.33f,
    -0.5f,  0.33f,
    0.5f,  0.33f
;


const GLfloat squareTex[] = 
    0, 0,
    1, 0,
    0, 1,
    1, 1
;


glEnableVertexAttribArray(PositionTag);
glEnableVertexAttribArray(TexCoord0Tag);

glVertexAttribPointer(PositionTag, 2, GL_FLOAT, GL_FALSE, 0, squareVertices);
glVertexAttribPointer(TexCoord0Tag, 2, GL_FLOAT, GL_FALSE, 0, squareTex);

为了抽奖

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

但我在转换为 VBO、着色器和 glDrawElements 时遇到了困难。这是我到目前为止的代码,但没有显示:

标题

typedef struct MyVertex

    float x, y, z;        //Vertex
    float nx, ny, nz;     //Normal
    float s0, t0;         //Texcoord0
 MyVertex;

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

初始化

glGenBuffers(1, &VertexVBOID);

glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);

MyVertex pvertices[4];
//Fill the pvertices array
pvertices[0].x = -0.5f;
pvertices[0].y = -0.33f;
pvertices[0].z = 0.0;
pvertices[0].nx = 0.0;
pvertices[0].ny = 0.0;
pvertices[0].nz = 1.0;
pvertices[0].s0 = 0.0;
pvertices[0].t0 = 0.0;

pvertices[1].x = 0.5f;
pvertices[1].y = -0.33f;
pvertices[1].z = 0.0;
pvertices[1].nx = 0.0;
pvertices[1].ny = 0.0;
pvertices[1].nz = 1.0;
pvertices[1].s0 = 1.0;
pvertices[1].t0 = 0.0;

pvertices[2].x = -0.5f;
pvertices[2].y = 0.33f;
pvertices[2].z = 0.0;
pvertices[2].nx = 0.0;
pvertices[2].ny = 0.0;
pvertices[2].nz = 1.0;
pvertices[2].s0 = 0.0;
pvertices[2].t0 = 1.0;

pvertices[3].x = 0.5f;
pvertices[3].y = 0.33f;
pvertices[3].z = 0.0;
pvertices[3].nx = 0.0;
pvertices[3].ny = 0.0;
pvertices[3].nz = 1.0;
pvertices[3].s0 = 1.0;
pvertices[3].t0 = 1.0;

glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*4, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(MyVertex)*4, pvertices);


glGenBuffers(1, &IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);

int pindices[6];
pindices[0]=0;
pindices[1]=1;
pindices[2]=2;
pindices[3]=2;
pindices[4]=1;
pindices[5]=3;
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*6, NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int)*6, pindices);

glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);

glEnableVertexAttribArray(PositionTag);
glEnableVertexAttribArray(NormalTag);
glEnableVertexAttribArray(TexCoord0Tag);

glVertexAttribPointer(PositionTag, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(0));
glVertexAttribPointer(NormalTag, 3, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(12));
glVertexAttribPointer(TexCoord0Tag, 2, GL_FLOAT, GL_FALSE, 32, BUFFER_OFFSET(24));

//    glDrawRangeElements(GL_TRIANGLES, x, y, z, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glDrawElements(GL_TRIANGLES, 3, GL_INT, 0);

【问题讨论】:

【参考方案1】:

根据here,GL_INT 不是用于glDrawElements 中的索引的有效类型。尝试将unsigned ints 用于您的索引(当然还有glDrawElements 中的GL_UNSIGNED_INT)。您仍然可以使用您的int 数据作为索引,但是由于glDrawElements 需要GL_UNSIGNED_INT,因此将数组设置为unsigned int 会更加一致。

编辑:在查看了规范(基于你的标签,我采用了 ES 2.0 规范)之后,他们似乎进一步将其限制为无符号字节和无符号短。我不知道它在 ios 中是否受到限制,但我们可以得出结论,数据至少必须是未签名的。另一方面,我还没有找到任何关于可能在错误类型参数上引发的 GL_INVALID_ENUM 错误的声明,但得到一个是合理的。

【讨论】:

这带来了以下几点:Zeophlite 应该测试 GL 是否在调试中报告错误。然后 glDrawElements 应该报告 GL_INVALID_ENUM。 @Bahbar 虽然很明显,错误的类型参数没有作为 GL_INVALID_ENUM 的来源在给定的参考链接上列出。这就是为什么我没有在回答中明确说明的原因。但是链接仍然说只有无符号是有效的。也许我应该检查规范以进行澄清。 是的,错误规范适用于所有枚举,而不是特定于每个命令。 “如果需要枚举值的命令传递的符号常量不是为该命令指定的允许值之一,则会生成错误 INVALID_ENUM 错误。” 感谢 Christian 的回答,其实我事先已经想好了,但是 *** 不允许我发布答案。还有@Bahbar,没有产生错误! (我删除了我的帖子的错误检查代码) @Zeophlite:那么这是一个驱动程序错误。归档:D?【参考方案2】:

您的代码看起来并没有大错特错,所以这一次魔鬼在细节的某个地方。我的猜测是,您使用的结构及其数据字段的对齐方式与传递给 OpenGL 的偏移量不匹配。

我建议你使用 stddef.h 中的offsetof() 宏来便携地获取数据字段的偏移量。

【讨论】:

以上是关于GLES2.0 上的 VBO glDrawElements 和 glVertexAttribPointer 不显示任何内容的主要内容,如果未能解决你的问题,请参考以下文章

如何设置 Open GLES2.0 与 Android 相机配合使用?

从 iPhone 上的 VBO 读取数据

iOS 上的 OpenGL ES 多个没有索引的 VBO

在 Android 上的 OpenGL ES 2.0 中使用 VBO/IBO

Android 上的 OpenGL ES 2:如何使用 VBO

是否可以在顶点着色器内持续更改 iPhone OpenGL ES 2.0 上的 VBO 值?