我正在使用OpenGL 3.3和EGL 1.4。我用来构建和运行我的代码(C)的笔记本电脑利用了英特尔的HD 3000集成GPU并运行Linux。因此我使用Mesa 3D库。在我的程序中,我在X11窗口中创建并绑定OpenGL 3.3核心配置文件兼容上下文,由后来返回的glGetString(GL_VERSION)
," 3.3(核心配置文件)Mesa 13.0.6"字符串确认。
接下来,我使用EGL加载OpenGL规范的各种功能(我选择不使用像GLEW这样的库)。在这之后,我开始设置OpenGL状态来渲染一个普通的三角形。我初始化一个浮点数组,构成我的三角形的3个硬编码顶点。然后,我初始化并绑定顶点数组对象,然后初始化并绑定顶点缓冲区对象。最后,我将顶点数组传递给glBufferData,以将顶点数据与顶点缓冲区对象链接起来。
unsigned int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
unsigned int vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
然后,我初始化一个基本的顶点和片段着色器。两者编译成功,我的着色器程序成功链接,并成功验证。
#version 330 core
layout (location = 0) in vec3 p;
void main(){
gl_Position = vec4(p, 0.0);
}
#version 330 core
out vec4 color;
void main(){
color = vec4(0.0, 0.0, 0.0, 1.0);
}
然后我继续告诉GL如何解释我的顶点数据;
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
glEnableVertexAttribArray(0);
最后,我进入我的程序主循环,负责绘制和交换帧缓冲区,其中bufferloop为struct timespec bufferloop = (struct timespec){0, 250000};
while(app.running){
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
eglSwapBuffers(egldisplay, eglsurface);
nanosleep(&bufferloop, (void *)0);
}
我得到的只是一个白色的屏幕;我的三角形无处可寻。我不能为我的生活决定问题是什么。我已经在代码中粘贴了printf("%d\n", glGetError());
,并且没有出现任何错误。
glDrawArrays(GL_TRIANGLES, 0, 3);
在没有窥视的情况下失败了。
答案 0 :(得分:2)
在你的顶点着色器中,w
组件应该是1而不是0.来自OpenGL红皮书here的一个很好的描述描述了如何使用w
。简言之:
OpenGL命令通常处理二维和三维顶点,但事实上所有顶点都被处理为包含四个坐标的三维齐次顶点。每个列向量(x,y,z,w)T表示一个齐次顶点,如果其中至少有一个元素非零。
只要w非零,均匀顶点(x,y,z,w)T对应于三维点(x / w,y / w,z / w)T。如果w = 0.0,则它对应于没有欧几里德点,而是对应于无限远处的某个理想化点。"要理解无穷远处的这一点,请考虑点(1,2,0,0),并注意点的顺序(1,2,0,1),(1,2,0,0.01)和(1) ,2.0,0.0,0.0001),对应于欧几里德点(1,2),(100,200)和(10000,20000)。该序列表示沿着2x = y线快速向无限远移动的点。因此,您可以将(1,2,0,0)视为该线方向上无穷远处的点。