0
votes

I'm very new to OpenGL and at the moment I'm trying to understand VAO and VBO.

The VAO is simply a collection of VBO.

Each VBO is an attribute of an object, coordinates of vertices of the object, color at each object's vertex, etc.

In the code below, the Vertex struct define 2 properties of a vertex, which is position and color of the vertex. Therefore, 2 VBOs are needed to store these information.

My problem is: I'm able to draw the triangle on the screen, but the color at each vertex doesn't seem to be drawn. Why does this happen?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>

// create vertex buffer
GLuint vertexbuffer;
struct Vertex{
    GLdouble position[3];
    GLfloat color[3];
};
static const GLfloat vertex_data[] = {
    -0.7f, -0.7f, 0.0f,
    0.7f, -0.7f, 0.0f,
    0.0f, 1.0f, 0.0f
};

void SetupGeometry(){
    const struct Vertex triangle[3] = {
        {{-0.7, -0.7, 0.0}, {1.0f, 0.0f, 0.0f}},
        {{0.7, -0.7, 0.0}, {0.0f, 1.0f, 0.0f}},
        {{0.0, 1.0, 0.0}, {0.0f, 0.0f, 1.0f}}
    };

    //GLuint VertexArrayID;
    //glGenVertexArrays(1, &VertexArrayID);
    //glBindVertexArray(VertexArrayID);

    //generate 1 buffer, put the resulting identifier in vertex buffer
    glGenBuffers(1, &vertexbuffer);

    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

    // give our vertices to OpenGL
    glBufferData(GL_ARRAY_BUFFER, 3*sizeof(struct Vertex), triangle, GL_STATIC_DRAW);

    // GLuint index, GLuint size, GLenum type, GLboolean normalized, GLsizei stride, const void *offset
    glVertexAttribPointer(0, 3, GL_DOUBLE, GL_FALSE, sizeof(struct Vertex), (void*) offsetof(struct Vertex, position));

    // any newly created VAO disables array access for all attributes
    // array access is enabled by binding the VAO in SetupGeometry and calling:
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), (void*) offsetof(struct Vertex, color));
    glEnableVertexAttribArray(1);
}

void SetupShaders(void){

}

void Render(int i){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDrawArrays(GL_LINE_LOOP, 0, 3);
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){
    if((key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) && action != GLFW_PRESS){
        glfwSetWindowShouldClose(window, GL_TRUE);
    }
}

int main( void ) {
    /* Create a windowed mode window and its OpenGL context */
    GLFWwindow* window;
    if( !glfwInit() ) {
            printf("Failed to start GLFW\n");
            exit( EXIT_FAILURE );
    }
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window) {
        glfwTerminate();
        printf("GLFW Failed to start\n");
        return -1;
    }
    /* Make the window's context current */
    glfwMakeContextCurrent(window); // IMPORTANT: Must be done so glew recognises OpenGL
    glfwWindowHint(GLFW_SAMPLES, 4);
    int err = glewInit();
    if (glewInit() != GLEW_OK) {
        /* Problem: glewInit failed, something is seriously wrong. */
        fprintf(stderr, "Error initializing GLEW: %s\n", glewGetErrorString(err));
    }
    fprintf(stderr, "Glew done\n");
    fprintf(stderr, "GL VERSION INFO %s\n", glGetString(GL_VERSION));
    glfwSetKeyCallback(window, key_callback);

    SetupGeometry();
    while(!glfwWindowShouldClose(window)){
        Render(0);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}
1
You don't have to have a different VBO for each vertex attribute. You can have a single struct as a Vertex and have a single VBO for all the vertices. I appreciate that, that doesn't answer your question; just thought you should know.Benjamin James Drury
Thank you! I don't want to be a lazy fox so I just want to make things clear before diving deeper :)Trung Bún
A VAO is not a collection of VBO. A VAO is actually a description of how to unpack the data in a collection of VBOs. You do not need to use multiple VBOs if you have multiple attributes, you can put all attributes in one VBO if you want. See: stackoverflow.com/questions/21652546/…Dietrich Epp
This is the same problem as another one I just answered earlier today: stackoverflow.com/questions/29426874/….Reto Koradi

1 Answers

1
votes

You don't seem to have included any shaders. You'll need to use a fragment shader to set the colour values for the triangle. This link should help you.