OpenGL彩色方块
Posted
技术标签:
【中文标题】OpenGL彩色方块【英文标题】:OpenGL Colored Square 【发布时间】:2015-10-09 15:52:06 【问题描述】:我想使用 OpenGL 4.1 和 OS X Yosemite 在屏幕上绘制一个具有随机插值颜色的立方体。每当我运行这个程序(它编译得很好)时,我什么也得不到,只是一个空白的蓝屏。这是我的代码:
#include <glm/gtc/matrix_transform.hpp>
#include <stdio.h>
#include "myglutils.hpp"
static const int vertices = 12 * 3;
static const GLfloat points[] =
-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,
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
;
static const GLfloat colors[] =
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f,
0.597f, 0.770f, 0.761f,
0.559f, 0.436f, 0.730f,
0.359f, 0.583f, 0.152f,
0.483f, 0.596f, 0.789f,
0.559f, 0.861f, 0.639f,
0.195f, 0.548f, 0.859f,
0.014f, 0.184f, 0.576f,
0.771f, 0.328f, 0.970f,
0.406f, 0.615f, 0.116f,
0.676f, 0.977f, 0.133f,
0.971f, 0.572f, 0.833f,
0.140f, 0.616f, 0.489f,
0.997f, 0.513f, 0.064f,
0.945f, 0.719f, 0.592f,
0.543f, 0.021f, 0.978f,
0.279f, 0.317f, 0.505f,
0.167f, 0.620f, 0.077f,
0.347f, 0.857f, 0.137f,
0.055f, 0.953f, 0.042f,
0.714f, 0.505f, 0.345f,
0.783f, 0.290f, 0.734f,
0.722f, 0.645f, 0.174f,
0.302f, 0.455f, 0.848f,
0.225f, 0.587f, 0.040f,
0.517f, 0.713f, 0.338f,
0.053f, 0.959f, 0.120f,
0.393f, 0.621f, 0.362f,
0.673f, 0.211f, 0.457f,
0.820f, 0.883f, 0.371f,
0.982f, 0.099f, 0.879f
;
int main()
if (!setupGLFW()) return 1;
setupApple();
glfwWindowHint(GLFW_SAMPLES, 4);
GLFWwindow* window = glfwCreateWindow(640, 480, "Colored Cube", NULL, NULL);
if (!window)
fprintf(stderr, "Window creation failed.\n");
glfwTerminate();
return 1;
glfwMakeContextCurrent(window);
if (!setupGLEW()) return 1;
glClearColor(0.2, 0.0, 0.8, 1.0);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
GLuint p_buffer;
glGenBuffers(1, &p_buffer);
glBindBuffer(GL_ARRAY_BUFFER, p_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
GLuint c_buffer;
glGenBuffers(1, &c_buffer);
glBindBuffer(GL_ARRAY_BUFFER, c_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, p_buffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glBindBuffer(GL_ARRAY_BUFFER, c_buffer);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
const char* vertex_shader =
"#version 410\n"
"layout(location = 0) in vec3 pos;"
"layout(location = 1) in vec3 in_color;"
"out vec3 color;"
"uniform mat4 MVP;"
"void main() "
" gl_Position = MVP * vec4(pos, 1.0);"
" color = in_color;"
"";
const char* fragment_shader =
"#version 410\n"
"in vec3 color;"
"out vec4 frag_color;"
"void main() "
" frag_color = vec4(color, 1.0);"
"";
GLuint shader = getShader(vertex_shader, fragment_shader);
GLuint MVPID = glGetUniformLocation(shader, "MVP");
//START MAKE MATRIX
glm::mat4 projection = glm::perspective(45.0, 4.0 / 3.0, 0.1, 100.0);
glm::mat4 view = glm::lookAt(glm::vec3(4.0, 3.0, -3.0), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
glm::mat4 MVP = projection * view;
//END MAKE MATRIX
glUniformMatrix4fv(MVPID, 1, GL_FALSE, &MVP[0][0]);
while (!glfwWindowShouldClose(window) && glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS)
//START DRAW
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, vertices);
//END DRAW
glfwPollEvents();
glfwSwapBuffers(window);
glfwTerminate();
return 0;
问题不在于 setupGLFW()、setupApple()、setupGLEW() 或 getShader()。这些已经过测试并证明有效。问题出在其他地方,但我不知道在哪里。
【问题讨论】:
一次只能将一个缓冲区绑定到GL_ARRAY_BUFFER
。
@cmbasnett 这是哪里的问题?
@cmbasnett:glm 一段时间以来默认使用所有角度的弧度,因此将透视 fov 设置为 45 不会达到您的预期。
@derhass 我不是 OP。 :p
@mlkn:0.9.4 也是如此。但是 glm 在一年前默认切换到所有弧度,see the current version of the docs
【参考方案1】:
如果您在 glUseProgram(theProgram) 调用代码应该可以工作(刚刚在我的电脑上工作)之后将 glUniformMatrix4fv() 调用移动到更新循环中。
您还可以将 glUseProgram(theProgram) 和 glUniformMatrix4fv() 移出渲染循环,这样它们就不会在每一帧都执行。
如果您不想在每个 glUseProgram 都更新制服,请查看 Uniform Buffer Object (related thread on SO)。您可以在着色器程序之间共享统一缓冲区对象并按需更新它们。
【讨论】:
我相信 OpenGL 将制服存储为着色器状态的一部分。无论哪种方式,删除glUseProgram
都会比添加 glUniformMatrix4fv
更好,因为着色器永远不会改变。
嗯,我想过,但删除 glUseProgram
会给我白色的矩形脸(屏幕坐标中的正方形)。它也失去了颜色属性和 MVP 矩阵(至少看起来是这样)。
s/删除循环前的glUseProgram
/移动glUseProgram
/
我很健忘,谢谢!它按预期工作。添加到答案。
@ColonelThirtyTwo 没错,统一值是程序状态的一部分。因此,如果值没有改变,则无需多次调用glUniformMatrix4fv()
。以上是关于OpenGL彩色方块的主要内容,如果未能解决你的问题,请参考以下文章
IOS OpenGL ES GPUImage 彩色模糊 GPUImageRGBOpeningFilter