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

IOS OpenGL ES 图像扩展边缘彩色模糊 GPUImageRGBDilationFilter

Java中OpenCV和OpenGL与俄罗斯方块游戏的连接

使用着色器渲染“顶点彩色”三角形时的OpenGL“黑屏”

受彩色矩形影响的所有纹理颜色 - OpenGL

尝试在大位图上使用 OpenGL 纹理压缩 - 得到白色方块