user1479670
user1479670

Reputation: 1281

How to color triangles with indexed vertices

I have an application which draws a tetrahedron with

glDrawElements(GL_TRIANGLES,...)

I would now like to color the tetrahedron's faces with a single flat color each.

If i understand correctly, i have to triplicate my 4 vertices so that every face has 'unique' vertices to which the same color value can be assigned.

Currently i handle the vertices and their indices like this

    glGenBuffers(1, &position_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, position_buffer);
    glBufferData(GL_ARRAY_BUFFER,
                 sizeof(vertex_positions),
                 vertex_positions,
                 GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(0);

    glGenBuffers(1, &index_buffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,
                 sizeof(vertex_indices),
                 vertex_indices,
                 GL_STATIC_DRAW);

In the vertex shader the vertices are accessed with

 in vec4 position;

Should i pass the colors in an additional GL_ARRAY_BUFFER?

If yes, can i use the same GL_ELEMENT_ARRAY_BUFFER (and use glEnableVertexAttribArray(1))?

How can i then access the colors from inside the vertex shader?

Upvotes: 3

Views: 1728

Answers (1)

Rabbid76
Rabbid76

Reputation: 210877

Should i pass the colors in an additional GL_ARRAY_BUFFER?

In general you have to possibilities,

either you have 2 buffers, a separated vertex buffer and color buffer:

GLuint vertex_attr_inx = 0;
GLuint color_attr_inx = 1;

GLfloat vertex_positions[] = .... ; // x0, y0, z0, x1, y1, z1, ...
GLfloat vertex_colors[]    = .... ; // R0, G0, B0, A0, R1, G1, B1, A1, ... 

GLuint vbo[2];
glGenBuffers(2, vbo);

glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_positions), vertex_positions, GL_STATIC_DRAW);
glVertexAttribPointer(vertex_attr_inx, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(vertex_attr_inx);

glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_colors), vertex_colors, GL_STATIC_DRAW);
glVertexAttribPointer(color_attr_inx, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(color_attr_inx);

Or you have a combind buffer for the vertex psoitions and color attributes:

GLfloat vertex_attributes[] = ; // x0, y0, z0, R0, G0, B0, A0, x1, y1, z1, R1, G1, B1, A1, ...

GLsizei attrSize  = 7*sizeof(float); // 7 -> x, y, z, R, G, B, A
GLsizei colorOffs = 3*sizeof(float);

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_attributes), vertex_attributes, GL_STATIC_DRAW);

glVertexAttribPointer(vertex_attr_inx, 3, GL_FLOAT, GL_FALSE, attrSize, 0);
glEnableVertexAttribArray(vertex_attr_inx);

glVertexAttribPointer(color_attr_inx, 4, GL_FLOAT, GL_FALSE, attrSize, colorOffs);
glEnableVertexAttribArray(color_attr_inx);


In the vertex shader you have to use to 2 attributes.

I recommend to use layout locations to specify the attribute indices (requires at least GLSL Version 3.30; this should be the case, since you tagged the question "opengl-4"):

#version 330

layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

Of course you can also queries the attribute locations, for earlier versions of OpenGL/GLSL (blow OpenGL 3.3 and GLSL 3.30):

in vec4 position;
in vec4 color;

GLuint vertex_attr_inx = glGetAttribLocation( shaderProgram, "position" );
GLuint color_attr_inx  = glGetAttribLocation( shaderProgram, "color" );



If yes, can i use the same GL_ELEMENT_ARRAY_BUFFER?

The index buffer (GL_ELEMNT_ARRAY_BUFFER) would be the same in both cases. You can use the code of your questions as it is.

glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertex_indices), vertex_indices, GL_STATIC_DRAW);

Upvotes: 3

Related Questions