【问题标题】:Opengles 2.0 without VAO没有 VAO 的 Opengles 2.0
【发布时间】:2015-08-22 21:51:10
【问题描述】:

我在 opengles 2.0 应用程序上工作得很好,直到我在不支持 VAO 的旧手机上对其进行了测试,现在我似乎陷入了困境。

在 VAO 成为某种标准并且无处不在之后,我开始使用 opengl,所以我从来不用不使用它来渲染。现在我必须编写支持它的代码,我遇到了一些麻烦。

顶点着色器

attribute vec3 position;
attribute vec4 icolor;
varying vec4 fcolor;

void main()
{
    gl_Position =  vec4(position, 1.0);
    fcolor = icolor;
}

片段着色器

precision mediump float;
varying vec4 fcolor;
void main (void)
{
gl_FragColor = fcolor;
}

应用方面

初始化代码:

glGenBuffers(1, &verticesBuffer);
glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->vertices), rend2d->vertices, GL_STATIC_DRAW);

glGenBuffers(1, &indicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rend2d->indices), rend2d->indices, GL_STATIC_DRAW);

glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->colors), rend2d->colors, GL_STATIC_DRAW);

渲染代码: glClearColor(1.0f, 1.0f, 1.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glUseProgram(sp);

GLint posLoc = glGetAttribLocation(sp, "position"); 
GLint colLoc = glGetAttribLocation(sp, "icolor");

glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(colLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);

glDrawElements(GL_TRIANGLES, rend2d->vertexCount, GL_UNSIGNED_INT, 0);

我的错误可能非常明显,但我只是看不到我目前没有正确执行的部分,并希望获得有关半现代 opengl 的帮助。这主要是为opengles 2.0但不支持的app提供支持 GL_OES_vertex_array_object 扩展。

【问题讨论】:

  • 我在您的代码中没有看到任何 glEnableVertexAttribArray() 调用。每个属性的启用状态也存储在 VAO 中。

标签: android c opengl-es vbo


【解决方案1】:

我想发布答案,因为有很多小问题是错误的。首先,我将发布用于保存 gl 数据的数据结构。

typedef struct
{
    GLuint vertexCount;

    GLfloat vertices[12];
    GLfloat colors[16];
    GLuint  indices[6];
    GLfloat texCoords[8];

} renderable2d;

第一个问题就在这里。正如@derhass 在 irc 频道上指出的那样,opengles 2.0 不支持 32 位索引。因此,第一步是将上面的 gluint 更改为 glushort

typedef struct
{
    GLushort vertexCount; //I made this a short as well

    GLfloat vertices[12];
    GLfloat colors[16];
    GLushort  indices[6]; //make this a short instead of an int
    GLfloat texCoords[8];

} 

一旦修复了那部分,我就必须生成缓冲区,绑定它们并将数据放入其中,然后解除绑定。

//bind n setup vertices
glGenBuffers(1, &verticesBuffer);
glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->vertices), rend2d->vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

//bind n setup colors
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->colors), rend2d->colors, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

//bind n setup indices
glGenBuffers(1, &indicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rend2d->indices), rend2d->indices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

最后是渲染代码

glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(sp);

glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
glEnableVertexAttribArray(posLoc);
glVertexAttribPointer(posLoc, 3, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glEnableVertexAttribArray(colLoc);
glVertexAttribPointer(colLoc, 4, GL_FLOAT, GL_FALSE, 0, 0);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glDrawElements(GL_TRIANGLES, rend2d->vertexCount, GL_UNSIGNED_SHORT, 0);

完成所有操作后,我在两台设备上都整理好了。为了清楚起见,rend2d 只是一个带纹理的四边形,所以rend2d->vertexCount = 6; 使用更复杂的模型,您将在其他地方获得该信息。

【讨论】:

    【解决方案2】:

    1) GL_UNSIGNED_INT 在 ES 2.0 中不被正式支持作为索引类型

    您的 GL_UNSIGNED_INT 必须是 GL_UNSIGNED_BYTE 或 GL_UNSIGNED_SHORT

    2) 当您使用没有 VAO 的 VBO 时,假设他们是朋友。

    glBindBuffer();
    glVertexAttribPointer();
    glEnableVertexAttribArray(); // you don't call it
    

    在init()中

    GLint posLoc = glGetAttribLocation(sp, "position"); 
    GLint colLoc = glGetAttribLocation(sp, "icolor");
    
    glGenBuffers(1, &verticesBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->vertices), rend2d->vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(posLoc);
    glVertexAttribPointer(posLoc, GL_FLOAT,0,0,0);
    
    glGenBuffers(1, &colorBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(rend2d->colors), rend2d->colors, GL_STATIC_DRAW);
    glEnableVertexAttribArray(colLoc)
    glVertexAttribPointer(colLoc, GL_FLOAT,0,0,0);
    

    在渲染中()

    glBindBuffer(GL_ARRAY_BUFFER, verticesBuffer);
    glEnableVertexAttribArray(posLoc);
    glVertexAttribPointer(posLoc, GL_FLOAT,0,0,0);
    
    glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
    glEnableVertexAttribArray(colLoc)
    glVertexAttribPointer(colLoc, GL_FLOAT,0,0,0);
    

    3) 只是不要在 ES 2.0 中使用 VAO,其中 VAO 不受官方支持。但是,IOS 是个例外。

    【讨论】:

    • 我不明白代码在哪里调用glEnableVertexAttribArray,如果我按照你上面指定的顺序调用它,我仍然没有得到渲染输出。
    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 2023-03-08
    • 1970-01-01
    • 2020-09-09
    相关资源
    最近更新 更多