【问题标题】:OpenGL ES 2.0 glDrawElements odd behaviorOpenGL ES 2.0 glDrawElements 奇怪的行为
【发布时间】:2016-06-10 08:43:08
【问题描述】:

在我的应用程序(在 Mali-400 GPU 上运行)中,我使用 OpenGL ES 2.0 来绘制 UI。为此,我设置了正交投影矩阵并使用 2D 向量来描述几何(仅 x、y 属性)。

所以我的顶点结构看起来像这样:

struct my_vertext {
    struct vec2 pos;
    struct unsigned int color;
}

然后我准备 GL 上下文,设置着色器:

顶点:

uniform mat4 matrix;
attribute vec2 pos;
attribute vec4 color;
varying vec4 frag_color;
void main() {
   frag_color = color;
   gl_Position = matrix * vec4(pos.xy, 0, 1);
};

片段:

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

并将它们与属性数组绑定:

GLuint prog = glCreateProgram(); CHECK_GL;
// create shaders, load source and compile them
...
/// binding with attributes
GLuint attrib_pos, attrib_col, vertex_index = 0;
glBindAttribLocation(prog, vertex_index, "pos"); CHECK_GL;
attrib_pos = vertex_index++;
glBindAttribLocation(prog, vertex_index, "color"); CHECK_GL;
attrib_col = vertex_index++;

// link program
glLinkProgram(prog); CHECK_GL;

glUseProgram(prog); CHECK_GL;

当我渲染我的几何图形时(为简单起见,我正在绘制 2 个一个接一个的矩形) - 只有第一次调用 glDrawElements 在屏幕上生成图像(深灰色矩形),第二个(红色) - 没有。 对于渲染,我使用带有 2 个绑定缓冲区的顶点数组对象 - 一个用于几何 (GL_ARRAY_BUFFER),第二个用于索引 (GL_ELEMENT_ARRAY_BUFFER)。所有几何图形都放置到此缓冲区中,然后使用 glDrawElements 调用绘制所需的偏移量。

我的绘图代码:

glBindVertexArray(vao); CHECK_GL;

...
GLuint *offset = 0;
for each UI object:
{
    glDrawElements(GL_TRIANGLES, (GLsizei)ui_object->elem_count,
        GL_UNSIGNED_SHORT, offset); CHECK_GL;
    offset += ui_object->elem_count;
}

这让我很困惑,因为我检查了 glXXX 函数的每一个返回码,它们都返回 GL_NO_ERROR。此外,我在 Mali Graphics Debugger 中运行我的程序,后者没有发现任何问题/错误。

两个调用的几何和索引(从 Mali Graphics Debugger 获得):

First rectangle geometry (which is shown on screen):
0 Position=[30.5, 30.5]     Color=[45, 45, 45, 255]
1 Position=[1250.5, 30.5]   Color=[45, 45, 45, 255]
2 Position=[1250.5, 690.5]  Color=[45, 45, 45, 255]
3 Position=[30.5, 690.5]    Color=[45, 45, 45, 255]

Indices: [0, 1, 2, 0, 2, 3]

Second rectangle geometry (which isnt` shown on screen):
4 Position=[130.5, 130.5]   Color=[255, 0, 0, 255]
5 Position=[230.5, 130.5]   Color=[255, 0, 0, 255]
6 Position=[230.5, 230.5]   Color=[255, 0, 0, 255]
7 Position=[130.5, 230.5]   Color=[255, 0, 0, 255]

Indices: [4, 5, 6, 4, 6, 7]

P.S.:在我的桌面上一切正常。我想这与嵌入式 Open GL 的局限性/特殊性有关。

On my desktop:
$ inxi -F
$ ....
$ GLX Renderer: Mesa DRI Intel Ivybridge Desktop GLX Version: 3.0 Mesa 10.1.3

【问题讨论】:

  • 看起来有问题的一件事是您使用elem_count 来计算传递给glDrawElements() 的偏移量,而该偏移量必须以字节为单位。另外,您是否启用了深度测试?如果这样做,第二个矩形可能会被深度测试简单地消除,因为它与第一个矩形共面。
  • @RetoKoradi:感谢您的提示,但 offset 是指向 unsigned short 的指针,这意味着它以字节为单位递增,并且深度测试被禁用glDisable(GL_DEPTH_TEST); 在实际渲染之前。
  • 它在您发布的代码中被声明为GLuint 类型。
  • @RetoKoradi:抱歉,它是指向 GLuint 的指针。我已经更正了帖子。
  • 您是否能够制作完整的最小失败代码?

标签: c opengl-es-2.0


【解决方案1】:

我对OpenGL ES知之甚少,但这部分看起来不对:

glBindVertexArray(vao); CHECK_GL;

...
GLuint *offset = 0;
for each UI object:
{
    glDrawElements(GL_TRIANGLES, (GLsizei)ui_object->elem_count,
        GL_UNSIGNED_SHORT, offset); CHECK_GL;
    offset += ui_object->elem_count;
}

相比

glBindVertexArray(vao); CHECK_GL;

...
GLuint offset = 0;
for each UI object:
{
    glDrawElements(GL_TRIANGLES, (GLsizei)ui_object->elem_count,
        GL_UNSIGNED_SHORT, &offset); CHECK_GL;
    offset += ui_object->elem_count;
}

【讨论】:

  • 进一步搜索 glDrawElements 的最后一个参数:songho.ca/opengl/gl_vertexarray.html 显示最后一个参数应该包含输入数据。为了测试,您的代码有些不完整
  • 这没关系,因为我在实际渲染循环之前绑定了一个顶点数组对象 (vao)。所有的数据都来自它。至于最后一个参数中的指针 - 它仅被视为绑定缓冲区对象内的偏移量,而不是指向实时数据的实际指针。
猜你喜欢
  • 1970-01-01
  • 2013-09-30
  • 2015-04-08
  • 2012-11-10
  • 2011-06-10
  • 2010-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多