简单顶点着色器的 OpenGL 输出正常但导致黑屏
OpenGL output of simple vertex shader OK but results in a black screen
是的,这是另一个“OpenGL 中的黑屏,求救!” post。我已经尽职调查,这是我迄今为止尝试诊断的内容:
- 使用 GLAD/GLFW
在 window 初始化期间检查所有错误
- 在编译和程序链接期间检查任何着色器错误
- 在整个应用程序中的每个 GL 命令后检查 GL 错误。
- 使用 Renderdoc 检查正在执行的 gl 命令列表。
- 使用 glClear 清除屏幕颜色(是的,这完全没问题,所以大概上下文没问题)
我的程序非常简单,它设置一个缓冲区来渲染一个三角形(实际上有更多的脚手架,因为这是从我以前在 d3d11 中使用的渲染器改编而来的,但我不断地削减它直到它是基本上只是教程代码)。在 Renderdoc 中你可以看到顶点位置没有问题,而且它似乎明白片段着色器也被链接和执行,但我只看到黑屏。
如果有人知道任何陷阱或调试步骤,请务必向我提出您的想法。我将 post 我的主要渲染代码、着色器和来自 renderdoc 的几个屏幕,所以你可以看到我并不疯狂。我也知道这里有些东西对每帧都没有意义。这就像我可以对其进行完整性检查一样简单。我的着色器加载代码和 window 初始化代码是沼泽标准,所以我不会费心 post 它,但如果有人认为它会有所帮助,我很乐意。
主循环
glViewport(0, 0, 300, 300);
ASSERT(glGetError() == GL_NO_ERROR);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
ASSERT(glGetError() == GL_NO_ERROR);
glBindVertexArray(VertexArrayID);
ASSERT(glGetError() == GL_NO_ERROR);
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
ASSERT(glGetError() == GL_NO_ERROR);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
ASSERT(glGetError() == GL_NO_ERROR);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
ASSERT(glGetError() == GL_NO_ERROR);
glEnableVertexAttribArray(0);
ASSERT(glGetError() == GL_NO_ERROR);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
ASSERT(glGetError() == GL_NO_ERROR);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
ASSERT(glGetError() == GL_NO_ERROR);
glDrawArrays(GL_TRIANGLES, 0, 3);
ASSERT(glGetError() == GL_NO_ERROR);
glDisableVertexAttribArray(0);
ASSERT(glGetError() == GL_NO_ERROR);
glfwPollEvents();
glfwSwapBuffers(glfwGetCurrentContext());
垂直着色器
#version 330 core
layout(location = 0) in vec3 inPos;
layout(location = 0) out vec4 outPos;
void main(){
outPos.xyz = inPos;
outPos.w = 1.0;
}
片段着色器
#version 330 core
layout(location = 0) out vec3 color;
void main(){
color = vec3(1,0,0);
}
您需要在顶点着色器中编写gl_Position
。 gl_Position
不能替换为自定义输出变量(如片段着色器中的 gl_FragColor
):
#version 330 core
layout(location = 0) in vec3 inPos;
void main()
{
gl_Position.xyz = vec4(inPos, 1.0);
}
见OpenGL Shading Language 4.60 Specification - 7.1.1. Vertex Shader Special Variables
请注意,顶点着色器的输出是下一个着色器阶段(在您的情况下是片段着色器)的输入,但是 [=16] 中的后续步骤需要顶点位置 (gl_Position
) =].
是的,这是另一个“OpenGL 中的黑屏,求救!” post。我已经尽职调查,这是我迄今为止尝试诊断的内容:
- 使用 GLAD/GLFW 在 window 初始化期间检查所有错误
- 在编译和程序链接期间检查任何着色器错误
- 在整个应用程序中的每个 GL 命令后检查 GL 错误。
- 使用 Renderdoc 检查正在执行的 gl 命令列表。
- 使用 glClear 清除屏幕颜色(是的,这完全没问题,所以大概上下文没问题)
我的程序非常简单,它设置一个缓冲区来渲染一个三角形(实际上有更多的脚手架,因为这是从我以前在 d3d11 中使用的渲染器改编而来的,但我不断地削减它直到它是基本上只是教程代码)。在 Renderdoc 中你可以看到顶点位置没有问题,而且它似乎明白片段着色器也被链接和执行,但我只看到黑屏。
如果有人知道任何陷阱或调试步骤,请务必向我提出您的想法。我将 post 我的主要渲染代码、着色器和来自 renderdoc 的几个屏幕,所以你可以看到我并不疯狂。我也知道这里有些东西对每帧都没有意义。这就像我可以对其进行完整性检查一样简单。我的着色器加载代码和 window 初始化代码是沼泽标准,所以我不会费心 post 它,但如果有人认为它会有所帮助,我很乐意。
主循环
glViewport(0, 0, 300, 300);
ASSERT(glGetError() == GL_NO_ERROR);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
ASSERT(glGetError() == GL_NO_ERROR);
glBindVertexArray(VertexArrayID);
ASSERT(glGetError() == GL_NO_ERROR);
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
ASSERT(glGetError() == GL_NO_ERROR);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
ASSERT(glGetError() == GL_NO_ERROR);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
ASSERT(glGetError() == GL_NO_ERROR);
glEnableVertexAttribArray(0);
ASSERT(glGetError() == GL_NO_ERROR);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
ASSERT(glGetError() == GL_NO_ERROR);
glVertexAttribPointer(
0,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)0
);
ASSERT(glGetError() == GL_NO_ERROR);
glDrawArrays(GL_TRIANGLES, 0, 3);
ASSERT(glGetError() == GL_NO_ERROR);
glDisableVertexAttribArray(0);
ASSERT(glGetError() == GL_NO_ERROR);
glfwPollEvents();
glfwSwapBuffers(glfwGetCurrentContext());
垂直着色器
#version 330 core
layout(location = 0) in vec3 inPos;
layout(location = 0) out vec4 outPos;
void main(){
outPos.xyz = inPos;
outPos.w = 1.0;
}
片段着色器
#version 330 core
layout(location = 0) out vec3 color;
void main(){
color = vec3(1,0,0);
}
您需要在顶点着色器中编写gl_Position
。 gl_Position
不能替换为自定义输出变量(如片段着色器中的 gl_FragColor
):
#version 330 core
layout(location = 0) in vec3 inPos;
void main()
{
gl_Position.xyz = vec4(inPos, 1.0);
}
见OpenGL Shading Language 4.60 Specification - 7.1.1. Vertex Shader Special Variables
请注意,顶点着色器的输出是下一个着色器阶段(在您的情况下是片段着色器)的输入,但是 [=16] 中的后续步骤需要顶点位置 (gl_Position
) =].