0

I want to draw a cube to the screen that has random interpolated colors with OpenGL 4.1 and on OS X Yosemite. Whenever I run this program (it compiles fine), I get nothing, just a blank, blue screen. Here's my code:

#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;
}

The problem is not with setupGLFW(), setupApple(), setupGLEW(), or getShader(). Those have been tested and proven to work. The problem lies somewhere else, but I cannot figure out where.

genpfault
  • 51,148
  • 11
  • 85
  • 139
Jerfov2
  • 5,264
  • 5
  • 30
  • 52
  • You can only have one buffer bound to `GL_ARRAY_BUFFER` at a time. – Colin Basnett Oct 09 '15 at 16:16
  • @cmbasnett where is this a problem? – Jerfov2 Oct 09 '15 at 16:17
  • @cmbasnett: glm usues radians for all angles by default since a while, so setting the perspective fov to 45 will not do what you expect it to. – derhass Oct 09 '15 at 18:42
  • @derhass I'm not the OP. :p – Colin Basnett Oct 09 '15 at 18:43
  • If i delete multiplication by MVP matrix in vertex shader i see a colored face of your cube. So the problem is MVP matrix. All is fine with buffers in this example, it's working on my machine right now. @derhass [Expressed in radians if GLM_FORCE_RADIANS is define or degrees otherwise.](http://glm.g-truc.net/0.9.4/api/a00151.html#ga283629a5ac7fb9037795435daf22560f) – Ramil Kudashev Oct 09 '15 at 19:05
  • 1
    @mlkn: That is true for 0.9.4. But glm switched to all radians by default over a year ago, [see the current version of the docs](http://glm.g-truc.net/0.9.7/api/a00174.html#gac3613dcb6c6916465ad5b7ad5a786175) – derhass Oct 09 '15 at 19:38
  • @derhass Thank you a lot for info! i'm a bit deprecated. – Ramil Kudashev Oct 09 '15 at 19:43

1 Answers1

2

If you move your glUniformMatrix4fv() call in update loop just after glUseProgram(theProgram) call code should work (just worked at my PC).

Also you could move glUseProgram(theProgram) and glUniformMatrix4fv() out of render loop so they won't be executed each frame.

If you don't want to update your uniforms every glUseProgram, take a look at Uniform Buffer Object (related thread on SO). You can share Uniform Buffer Objects between shader programs and update them on demand.

Community
  • 1
  • 1
Ramil Kudashev
  • 1,166
  • 3
  • 15
  • 19
  • I believe OpenGL stores the uniforms as part of the shader state. Either way, removing the `glUseProgram` would be better than adding `glUniformMatrix4fv` because the shader never changes. – Colonel Thirty Two Oct 09 '15 at 19:32
  • Well i thought about that, but removing `glUseProgram` gives me white rectangle face (square in screen coords). It loses color attribute and MVP matrix too (at least it seems like so). – Ramil Kudashev Oct 09 '15 at 19:39
  • s/removing the `glUseProgram`/moving the `glUseProgram` before the loop/ – Colonel Thirty Two Oct 09 '15 at 19:48
  • Very forgetfully from me, thank you! It works as intended. Added to answer. – Ramil Kudashev Oct 09 '15 at 19:52
  • 1
    @ColonelThirtyTwo That's correct, uniform values are part of the program state. So there's no need to call `glUniformMatrix4fv()` more than once if it the value doesn't change. – Reto Koradi Oct 10 '15 at 03:59