为什么 OpenGL 不渲染我的红色三角形?
Why isn't OpenGL rendering my red triangle?
经过几次测试我仍然没有看到我的红色三角形,我做错了什么?这很有趣,因为这不是我第一次使用 OpenGL,而且我很确定我没有错过任何设置步骤。这是一个代码片段:
GLFWwindow* window;
glfwSetErrorCallback(onError);
if ( !glfwInit() ) {
std::cout << "glfwInit() failed." << std::endl;
return;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow( GetWindowWidth(), GetWindowHeight(), "The Game", NULL, NULL );
if ( !window )
{
std::cout << "couldn't create a proper window, exiting." << std::endl;
glfwTerminate();
return;
}
glfwSetKeyCallback( window, handleKeysEvents );
glfwMakeContextCurrent( window );
gladLoadGL(); // no glfwGetProcAddress required
glfwSwapInterval(1);
/// init opengl things ...
GLuint VAO, VBO, program;
GLuint VertexShader, FragmentShader;
VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, &vertex_shader_text, NULL);
glCompileShader(VertexShader);
GLint isCompiled = 0;
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &maxLength);
std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(VertexShader, maxLength, &maxLength, &errorLog[0]);
for ( int i = 0; i < errorLog.size(); ++i )
std::cout << errorLog[i];
glDeleteShader(VertexShader); // Don't leak the shader.
return;
}
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &fragment_shader_text, NULL);
glCompileShader(FragmentShader);
isCompiled = 0;
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(FragmentShader, maxLength, &maxLength, &errorLog[0]);
for ( int i = 0; i < errorLog.size(); ++i )
std::cout << errorLog[i];
glDeleteShader(FragmentShader); // Don't leak the shader.
return;
}
program = glCreateProgram();
glAttachShader(program, VertexShader);
glAttachShader(program, FragmentShader);
glLinkProgram(program);
// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
std::cout << "ERROR IN LINKING PROGRAM." << std::endl;
GLint maxLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
// We don't need the program anymore.
glDeleteProgram(program);
// Don't leak shaders either.
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
// Use the infoLog as you see fit.
for ( int i = 0; i < infoLog.size(); ++i )
std::cout << infoLog[i];
// In this simple program, we'll just leave
return;
}
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glBufferData(GL_VERTEX_ARRAY, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindVertexArray(0);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
while( !glfwWindowShouldClose(window) )
{
Float wWidth = GetWindowWidth();
Float wHeight = GetWindowHeight();
glViewport(0, 0, (GLsizei)wWidth, (GLsizei)wHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
std::cout << "closing the game." << std::endl;
return;
这是着色器:
顶点着色器:
#version 460 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos, 1.0f);
}
和片段着色器:
#version 460 core
out vec4 FragCol;
void main()
{
FragCol = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
创建了 OpenGL 上下文,实际上用特定颜色清除屏幕效果很好。我只是在屏幕上看不到我的三角形,有什么建议吗?
GL_VERTEX_ARRAY
is not a valid buffer type. GL_VERTEX_ARRAY
is a client-side capability (fixed function attribute, legacy OpenGL). The buffer type for vertex attributes is GL_ARRAY_BUFFER
:
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
经过几次测试我仍然没有看到我的红色三角形,我做错了什么?这很有趣,因为这不是我第一次使用 OpenGL,而且我很确定我没有错过任何设置步骤。这是一个代码片段:
GLFWwindow* window;
glfwSetErrorCallback(onError);
if ( !glfwInit() ) {
std::cout << "glfwInit() failed." << std::endl;
return;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow( GetWindowWidth(), GetWindowHeight(), "The Game", NULL, NULL );
if ( !window )
{
std::cout << "couldn't create a proper window, exiting." << std::endl;
glfwTerminate();
return;
}
glfwSetKeyCallback( window, handleKeysEvents );
glfwMakeContextCurrent( window );
gladLoadGL(); // no glfwGetProcAddress required
glfwSwapInterval(1);
/// init opengl things ...
GLuint VAO, VBO, program;
GLuint VertexShader, FragmentShader;
VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, &vertex_shader_text, NULL);
glCompileShader(VertexShader);
GLint isCompiled = 0;
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &maxLength);
std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(VertexShader, maxLength, &maxLength, &errorLog[0]);
for ( int i = 0; i < errorLog.size(); ++i )
std::cout << errorLog[i];
glDeleteShader(VertexShader); // Don't leak the shader.
return;
}
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &fragment_shader_text, NULL);
glCompileShader(FragmentShader);
isCompiled = 0;
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(FragmentShader, maxLength, &maxLength, &errorLog[0]);
for ( int i = 0; i < errorLog.size(); ++i )
std::cout << errorLog[i];
glDeleteShader(FragmentShader); // Don't leak the shader.
return;
}
program = glCreateProgram();
glAttachShader(program, VertexShader);
glAttachShader(program, FragmentShader);
glLinkProgram(program);
// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
std::cout << "ERROR IN LINKING PROGRAM." << std::endl;
GLint maxLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
// We don't need the program anymore.
glDeleteProgram(program);
// Don't leak shaders either.
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
// Use the infoLog as you see fit.
for ( int i = 0; i < infoLog.size(); ++i )
std::cout << infoLog[i];
// In this simple program, we'll just leave
return;
}
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glBufferData(GL_VERTEX_ARRAY, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindVertexArray(0);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
while( !glfwWindowShouldClose(window) )
{
Float wWidth = GetWindowWidth();
Float wHeight = GetWindowHeight();
glViewport(0, 0, (GLsizei)wWidth, (GLsizei)wHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
std::cout << "closing the game." << std::endl;
return;
这是着色器:
顶点着色器:
#version 460 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos, 1.0f);
}
和片段着色器:
#version 460 core
out vec4 FragCol;
void main()
{
FragCol = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
创建了 OpenGL 上下文,实际上用特定颜色清除屏幕效果很好。我只是在屏幕上看不到我的三角形,有什么建议吗?
GL_VERTEX_ARRAY
is not a valid buffer type. GL_VERTEX_ARRAY
is a client-side capability (fixed function attribute, legacy OpenGL). The buffer type for vertex attributes is GL_ARRAY_BUFFER
:
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);