如何修复 OpenGL 3.3 中的黑屏输出
How to fix black screen output in OpenGL 3.3
我在使用 OpenGL 和 C++ 的项目中遇到黑屏。关于在屏幕上渲染红色三角形时出错的地方,我需要帮助。
我已经尝试检查顶点和片段着色器中的错误。
#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include <string>
using namespace std;
unsigned int CreateShader(int type, const string shaderSource) {
unsigned int shader = glCreateShader(type);
const char *src = shaderSource.c_str();
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
int result;
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE) {
int length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
char *message = (char*)alloca(length * sizeof(char));
glGetShaderInfoLog(shader, length, &length, message);
cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex shader " : "fragment shader ") << endl;
cout << message << endl;
}
return shader;
}
unsigned int CreateProgram(const string vertexShader, const string fragmentShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CreateShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CreateShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glDeleteShader(vs);
glDeleteShader(fs);
glLinkProgram(program);
glValidateProgram(program);
return program;
}
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window = glfwCreateWindow(800, 600, "window", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
if (glewInit() != GLEW_OK) {
cout << "Glew initialization Failed! " << endl;
glfwTerminate();
return -1;
}
float positions[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
};
cout << "Made By Rial Seebran" << endl;
cout << glfwGetVersionString() << endl;
unsigned int VAO;
unsigned int VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
const string vertexShader =
"#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main() {\n"
"gl_Position = vec4(position, 0.0f);\n"
"}\n";
const string fragmentShader =
"#version 330 core\n"
"layout (location = 0) out vec4 color;\n"
"void main() {\n"
"color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
"}\n";
unsigned int program = CreateProgram(vertexShader, fragmentShader);
while (!glfwWindowShouldClose(window)) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glBindVertexArray(VAO);
glDrawArrays(GL_ARRAY_BUFFER, 0, 3);
glBindVertexArray(0);
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
我希望在指定的坐标处绘制一个带有蓝色背景的红色三角形。
glDrawArrays
的第一个参数必须是原始类型。
它必须是 GL_TRIANGLES
而不是 GL_ARRAY_BUFFER
:
glDrawArrays(GL_ARRAY_BUFFER, 0, 3);
glDrawArrays(GL_TRIANGLES, 0, 3);
OpenGL 枚举常量 GL_ARRAY_BUFFER
不是此参数的可接受值,将导致 GL_INVALID_ENUM
错误(该错误可通过 glGetError
获取)。
当剪辑 space 坐标转换为标准化设备 space 时,x
、y
和 z
分量除以 w
组件。
这意味着 gl_Position
的 w
组件必须设置为 1.0 而不是 0.0:
gl_Position = vec4(position, 0.0f);
gl_Position = vec4(position, 1.0);
Glew 可以通过 glewExperimental = GL_TRUE;
启用其他扩展。看到 GLEW documentation 上面写着:
GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, the glewExperimental
global switch can be turned on by setting it to GL_TRUE
before calling glewInit()
, which ensures that all extensions with valid entry points will be exposed.
glewExperimental = GL_TRUE;
if ( glewInit() != GLEW_OK ) {
cout << "Glew initialization Failed! " << endl;
glfwTerminate();
return -1;
}
我在使用 OpenGL 和 C++ 的项目中遇到黑屏。关于在屏幕上渲染红色三角形时出错的地方,我需要帮助。
我已经尝试检查顶点和片段着色器中的错误。
#include <GL\glew.h>
#include <GL\GL.h>
#include <GLFW\glfw3.h>
#include <iostream>
#include <string>
using namespace std;
unsigned int CreateShader(int type, const string shaderSource) {
unsigned int shader = glCreateShader(type);
const char *src = shaderSource.c_str();
glShaderSource(shader, 1, &src, NULL);
glCompileShader(shader);
int result;
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if (result == GL_FALSE) {
int length;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &length);
char *message = (char*)alloca(length * sizeof(char));
glGetShaderInfoLog(shader, length, &length, message);
cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex shader " : "fragment shader ") << endl;
cout << message << endl;
}
return shader;
}
unsigned int CreateProgram(const string vertexShader, const string fragmentShader) {
unsigned int program = glCreateProgram();
unsigned int vs = CreateShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CreateShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glDeleteShader(vs);
glDeleteShader(fs);
glLinkProgram(program);
glValidateProgram(program);
return program;
}
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow *window = glfwCreateWindow(800, 600, "window", NULL, NULL);
glfwMakeContextCurrent(window);
glewInit();
if (glewInit() != GLEW_OK) {
cout << "Glew initialization Failed! " << endl;
glfwTerminate();
return -1;
}
float positions[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
};
cout << "Made By Rial Seebran" << endl;
cout << glfwGetVersionString() << endl;
unsigned int VAO;
unsigned int VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
const string vertexShader =
"#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main() {\n"
"gl_Position = vec4(position, 0.0f);\n"
"}\n";
const string fragmentShader =
"#version 330 core\n"
"layout (location = 0) out vec4 color;\n"
"void main() {\n"
"color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n"
"}\n";
unsigned int program = CreateProgram(vertexShader, fragmentShader);
while (!glfwWindowShouldClose(window)) {
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glBindVertexArray(VAO);
glDrawArrays(GL_ARRAY_BUFFER, 0, 3);
glBindVertexArray(0);
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
我希望在指定的坐标处绘制一个带有蓝色背景的红色三角形。
glDrawArrays
的第一个参数必须是原始类型。
它必须是 GL_TRIANGLES
而不是 GL_ARRAY_BUFFER
:
glDrawArrays(GL_ARRAY_BUFFER, 0, 3);
glDrawArrays(GL_TRIANGLES, 0, 3);
OpenGL 枚举常量 GL_ARRAY_BUFFER
不是此参数的可接受值,将导致 GL_INVALID_ENUM
错误(该错误可通过 glGetError
获取)。
当剪辑 space 坐标转换为标准化设备 space 时,x
、y
和 z
分量除以 w
组件。
这意味着 gl_Position
的 w
组件必须设置为 1.0 而不是 0.0:
gl_Position = vec4(position, 0.0f);
gl_Position = vec4(position, 1.0);
Glew 可以通过 glewExperimental = GL_TRUE;
启用其他扩展。看到 GLEW documentation 上面写着:
GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, the
glewExperimental
global switch can be turned on by setting it toGL_TRUE
before callingglewInit()
, which ensures that all extensions with valid entry points will be exposed.
glewExperimental = GL_TRUE;
if ( glewInit() != GLEW_OK ) {
cout << "Glew initialization Failed! " << endl;
glfwTerminate();
return -1;
}