我正在尝试在iOS上使用openGL渲染三角形。我有我的环境设置。我可以更改屏幕的背景色。我有一个基本的顶点和片段着色器,它们都可以成功编译并链接到程序。 glError()也不会报告任何错误。
由于某种原因,我的三角形没有渲染。
我这样设置帧缓冲区和渲染缓冲区:
glGenRenderbuffers(1, &_colorRenderBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _colorRenderBuffer);
[_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:drawable];
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_RENDERBUFFER, _colorRenderBuffer);
然后定义三角形的3个顶点:
_triangleMatrix[0] = -1.0; _triangleMatrix[1] = 0.0;
_triangleMatrix[2] = 0.0; _triangleMatrix[3] = 1.0;
_triangleMatrix[4] = 1.0; _triangleMatrix[5] = 0.0;
我创建并链接我的着色器。由于没有编译或链接错误,因此我不会在此处显示整个代码:
[self createVertexShader];
[self createFragmentShader];
[self linkProgram];
然后,我使用该程序并获取属性“ position”插槽并启用它:
glUseProgram(_program);
_position_slot = glGetAttribLocation(_program, "position");
glEnableVertexAttribArray(_position_slot);
现在,我需要设置我的VBO。这是我最不确定的部分。
glGenBuffers(1, &_vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(_triangleMatrix), _triangleMatrix, GL_STATIC_DRAW);
然后是我的render()方法:
glClear(GL_COLOR_BUFFER_BIT);
// 1rst attribute buffer : vertices
glVertexAttribPointer(
_position_slot,
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
[_context presentRenderbuffer:GL_RENDERBUFFER];
这是编译的顶点着色器的代码:
NSString* vshader = \
@"attribute vec2 position; \
void main()\
{\
gl_Position = vec4(position.x, position.y, 0.0, 1.0);\
}";
和片段着色器:
NSString* fshader = \
@"void main()\
{\
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\
}";
基本上就是这样,对于整个文件,您可以查看以下链接:
https://gist.github.com/anonymous/6ed3f8231e76db35921ef260bfa6bf43
我认为问题是我的顶点着色器没有从我的_triangleMatrix成员接收“位置”数据。因此,要么属性设置不正确,要么openGL无法读取_triangleMatrix的数据本身。无论如何,从我看过的所有教程和指南中,我相信我已经正确设置了它,我很茫然。
此外,glError()不会返回错误,并且可以检查错误的每个着色器编译或链接过程均不会报告任何错误。
有任何想法吗?
最佳答案
您缺少了几块。
您错过的最重要的事情是设置视口:glViewport(x, y, width, height)
应该设置为渲染缓冲区的大小。这定义了要绘制到缓冲区的哪一部分,并且必须手动设置。
第二个似乎是您在draw调用结束时禁用了vertex属性数组,但是在调用开始时未启用它。在您的情况下,禁用并不是真正必要的,只有在使用着色器(glUseProgram
)时才有意义。但一般来说,请确保已启用所有使用的属性。在您的代码中,三角形仅在第一帧绘制,然后在下一帧消失。