OpenGL GLFW简单立方体不渲染
Posted
技术标签:
【中文标题】OpenGL GLFW简单立方体不渲染【英文标题】:OpenGL GLFW simple cube not rendering 【发布时间】:2017-04-06 20:56:21 【问题描述】:看在上帝的份上,谁能告诉我这段代码有什么问题,它没有显示一个带有简单顶点和片段着色器的简单立方体, 看来我已经正确初始化 gl 和 GLFW,创建着色器编译并链接它们,创建模型视图投影矩阵,并将它们传递给着色器,我不明白为什么它不渲染。
#include <iostream>
#include <fstream>
#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <glm\glm.hpp>
#include <glm\gtc\matrix_transform.hpp>
#include <glm\gtc\type_ptr.hpp>
using namespace std;
using namespace glm;
int g_gl_width = 800;
int g_gl_height = 600;
GLFWwindow* g_window = NULL;
void glfw_error_callback(int error, const char* description)
cerr << description << endl;
void glfw_window_size_callback(GLFWwindow* window, int width, int height)
g_gl_width = width;
g_gl_height = height;
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
int main(int argc, char * argv [])
glfwSetErrorCallback(glfw_error_callback);
if (!glfwInit())
cerr << "ERROR: could not start GLFW3\n" << endl;
return false;
g_window = glfwCreateWindow(
g_gl_width, g_gl_height, "Extended Init.", NULL, NULL
);
if (!g_window)
cerr << "ERROR: could not open window with GLFW3\n" << endl;
glfwTerminate();
return false;
glfwSetWindowSizeCallback(g_window, glfw_window_size_callback);
glfwMakeContextCurrent(g_window);
glfwSetMouseButtonCallback(g_window, mouse_button_callback);
glfwSetScrollCallback(g_window, scroll_callback);
glfwWindowHint(GLFW_SAMPLES, 4);
glewExperimental = GL_TRUE;
glewInit();
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
cout << "Renderer: " << renderer;
cout << "OpenGL version supported: " << version;
glEnable(GL_DEPTH_TEST); // enable depth-testing
glDepthFunc(GL_LESS); // depth-testing interprets a smaller value as "closer"
glEnable(GL_CULL_FACE); // cull face
glCullFace(GL_BACK); // cull back face
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glViewport(0, 0, g_gl_width, g_gl_height);
GLfloat points[] =
-1.0f, -1.0f, -1.0f, // triangle 1 : begin
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f, // triangle 1 : end
1.0f, 1.0f, -1.0f, // triangle 2 : begin
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f, // triangle 2 : end
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f
;
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(
GL_ARRAY_BUFFER,
3 * 36 * sizeof(GLfloat),
points,
GL_STATIC_DRAW
);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
const char* vertex_shader =
"#version 410\n"
"layout(location = 0) in vec3 vertex_position;\n"
"uniform mat4 model, view, projection;\n"
"void main() \n"
" gl_Position = projection * view * model * vec4(vertex_position, 1.0);\n"
"\n";
const char* fragment_shader =
"#version 410\n"
"void main() \n"
" gl_FragColor = vec4(1.0f, 0.0f, 0.0f, 1.0);\n"
"\n";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
GLuint shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
mat4 projection = glm::perspective(90.0f, (float)(g_gl_width / g_gl_height), 0.1f, 100.0f);
mat4 view = glm::mat4(1.0f);
view = glm::translate(view, vec3(0.0f, 0.0f, 0.0f));
view = glm::rotate(view, 0.0f, vec3(0.0f, 0.0f, 1.0f));
view = glm::rotate(view, 0.0f, vec3(0.0f, 1.0f, 0.0f));
view = glm::rotate(view, 0.0f, vec3(1.0f, 0.0f, 0.0f));
mat4 model = glm::mat4(1.0f);
model = glm::translate(model, vec3(0.0f, 0.0f, 0.0f));
model = glm::rotate(model, 0.0f, vec3(0.0f, 0.0f, 1.0f));
model = glm::rotate(model, 0.0f, vec3(0.0f, 1.0f, 0.0f));
model = glm::rotate(model, 0.0f, vec3(1.0f, 0.0f, 0.0f));
int model_mat_location = glGetUniformLocation(shader_programme, "model");
glUniformMatrix4fv(model_mat_location, 1, GL_FALSE, glm::value_ptr(model));
int view_mat_location = glGetUniformLocation(shader_programme, "view");
glUniformMatrix4fv(view_mat_location, 1, GL_FALSE, glm::value_ptr(view));
int proj_mat_location = glGetUniformLocation(shader_programme, "projection");
glUniformMatrix4fv(proj_mat_location, 1, GL_FALSE, glm::value_ptr(projection));
glUseProgram(shader_programme);
while (!glfwWindowShouldClose(g_window))
glfwMakeContextCurrent(g_window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, g_gl_width, g_gl_height);
glBindVertexArray(vao);
glUseProgram(shader_programme);
glDrawArrays(GL_TRIANGLES, 0, 36);
if (GLFW_PRESS == glfwGetKey(g_window, GLFW_KEY_ESCAPE))
glfwSetWindowShouldClose(g_window, 1);
glfwPollEvents();
glfwSwapBuffers(g_window);
glfwTerminate();
return 0;
编辑:
我还想指出我在代码中还有另一个错误
mat4 view = glm::mat4(1.0f);
glm::translate(view, vec3(0.0f, 0.0f, 0.0f));
glm::rotate(view, 0.0f, vec3(0.0f, 0.0f, 1.0f));
glm::rotate(view, 0.0f, vec3(0.0f, 1.0f, 0.0f));
glm::rotate(view, 0.0f, vec3(1.0f, 0.0f, 0.0f));
应该是:
mat4 view = glm::mat4(1.0f);
view = glm::translate(view, vec3(0.0f, 0.0f, 0.0f));
view = glm::rotate(view, 0.0f, vec3(0.0f, 0.0f, 1.0f));
view = glm::rotate(view, 0.0f, vec3(0.0f, 1.0f, 0.0f));
view = glm::rotate(view, 0.0f, vec3(1.0f, 0.0f, 0.0f));
还有模特。
【问题讨论】:
【参考方案1】:问题可能出在这段代码中。
int model_mat_location = glGetUniformLocation(shader_programme, "model");
glUniformMatrix4fv(model_mat_location, 1, GL_FALSE, glm::value_ptr(model));
int view_mat_location = glGetUniformLocation(shader_programme, "view");
glUniformMatrix4fv(view_mat_location, 1, GL_FALSE, glm::value_ptr(view));
int proj_mat_location = glGetUniformLocation(shader_programme, "projection");
glUniformMatrix4fv(proj_mat_location, 1, GL_FALSE, glm::value_ptr(projection));
glUseProgram(shader_programme);
您需要致电glUseProgram
在您尝试对统一值进行任何更改。 location
变量是为每个着色器独立分配的,这意味着对于程序 1,位置将在 [0,1,2,3,...] 范围内,对于程序 2,位置也将在范围 [0,1,2,3,...]。因此,在没有活动程序的情况下调用 glUniform*
意味着 OpenGL 不知道您正在为哪个程序更新制服,因此不知道如何应用您传递的值。
此外,您可能还需要更改此代码:
mat4 view = glm::mat4(1.0f);
glm::translate(view, vec3(0.0f, 0.0f, 0.0f));
glm::rotate(view, 0.0f, vec3(0.0f, 0.0f, 1.0f));
glm::rotate(view, 0.0f, vec3(0.0f, 1.0f, 0.0f));
glm::rotate(view, 0.0f, vec3(1.0f, 0.0f, 0.0f));
虽然此代码基本上没有任何问题,但这会将相机放在立方体内。启用人脸剔除后,您可能实际上看不到任何东西,因为所有的人脸都背对着您。出于测试目的,请考虑使用glm::lookAt
。
mat4 view = glm::lookAt(vec3(3, 3, 1), vec3(0, 0, 0), vec3(0, 1, 0));
【讨论】:
非常感谢,我添加了您的两个建议,并且成功了!以上是关于OpenGL GLFW简单立方体不渲染的主要内容,如果未能解决你的问题,请参考以下文章