OpenGL彩色广场

时间:2015-10-09 15:52:06

标签: c++ opengl matrix glfw glm-math

我想在具有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()。这些已经过测试并证明可行。问题出在其他地方,但我无法弄清楚在哪里。

1 个答案:

答案 0 :(得分:2)

如果您在 glUseProgram(theProgram)之后的更新循环中移动 glUniformMatrix4fv()调用,则应该可以使用(仅在我的电脑上工作)。

此外,您可以将 glUseProgram(theProgram) glUniformMatrix4fv()移出渲染循环,这样就无法在每一帧执行。

如果您不想每个glUseProgram更新校服,请查看Uniform Buffer Objectrelated thread on SO)。您可以在着色器程序之间共享统一缓冲区对象,并根据需要进行更新。