Hi I am trying to render lots of axis aligned cubes, with glDrawArraysInstanced(). Each cube of fixed size can only vary on its center position and color. Also each cube only takes few different colors. So I want to potentially render millions of cubes with following per instance data:
struct CubeInfo {
Eigen::Vector3f center; // center of the cube (x,y,z)
int labelId; // label of the cube which affects its color
};
So I am using the following vertex shader:
#version 330
uniform mat4 mvp_matrix;
//regular vertex attributes
layout(location = 0) in vec3 vertex_position;
// Per Instance variables
layout(location = 1) in vec3 cube_center;
layout(location = 2) in int cube_label;
// color out to frag shader
out vec4 color_out;
void main(void) {
// Add offset cube_center
vec4 new_pos = vec4(vertex_position + cube_center, 1);
// Calculate vertex position in screen space
gl_Position = mvp_matrix * new_pos;
// Set color_out based on label
switch (cube_label) {
case 1:
color_out = vec4(0.5, 0.25, 0.5, 1);
break;
case 2:
color_out = vec4(0.75, 0.0, 0.0, 1);
break;
case 3:
color_out = vec4(0.0, 0.0, 0.5, 1);
break;
case 4:
color_out = vec4(0.75, 1.0, 0.0, 1);
break;
default:
color_out = vec4(0.5, 0.5, 0.5, 1); // Grey
break;
}
}
and the corresponding fragment shader:
#version 330
in vec4 color_out;
out vec4 fragColor;
void main()
{
// Set fragment color from texture
fragColor = color_out;
}
However color_out always takes the default gray value, even though, cube_label values are between 1 to 4. This is my problem. Am I doing something wrong in the shader above**?**
I initialized the cubeInfo vbo with random labelIds between 1-4. So I am expecting to see a colorful output than following:

This is my render code, which makes use of Qt's QGLShaderProgram and QGLBuffer wrapper:
// Enable back face culling
glEnable(GL_CULL_FACE);
cubeShaderProgram_.bind();
// Set the vertexbuffer stuff (Simply 36 vertices for cube)
cubeVertexBuffer_.bind();
cubeShaderProgram_.setAttributeBuffer("vertex_position", GL_FLOAT, 0, 3, 0);
cubeShaderProgram_.enableAttributeArray("vertex_position");
cubeVertexBuffer_.release();
// Set the per instance buffer stuff
cubeInstanceBuffer_.bind();
cubeShaderProgram_.setAttributeBuffer("cube_center", GL_FLOAT, offsetof(CubeInfo,center), 3, sizeof(CubeInfo));
cubeShaderProgram_.enableAttributeArray("cube_center");
int center_location = cubeShaderProgram_.attributeLocation("cube_center");
glVertexAttribDivisor(center_location, 1);
cubeShaderProgram_.setAttributeBuffer("cube_label", GL_INT, offsetof(CubeInfo,labelId), 1, sizeof(CubeInfo));
cubeShaderProgram_.enableAttributeArray("cube_label");
int label_location = cubeShaderProgram_.attributeLocation("cube_label");
glVertexAttribDivisor(label_location, 1);
cubeInstanceBuffer_.release();
// Do Instanced Renering
glDrawArraysInstanced(GL_TRIANGLES, 0, 36, displayed_num_cubes_ );
cubeShaderProgram_.disableAttributeArray("vertex_position");
cubeShaderProgram_.disableAttributeArray("cube_center");
cubeShaderProgram_.disableAttributeArray("cube_label");
cubeShaderProgram_.release();
Apart from my primary question above (color problem), is this a good way to do Minecraft?
Update
If I change my CubeInfo.labelId attribute from int to float, and the corresponding vertex shader variable cube_label to also float, it Works!!. Why is it so? This page says GLSL suppoers int type. For me, I would prefer labelId/cube_label to be some int/short.
Update2:
Even if i just change to GL_FLOAT instead of GL_INT in the following line of my render code, I get proper colors.
cubeShaderProgram_.setAttributeBuffer("cube_label", GL_INT, offsetof(CubeInfo,labelId), 1, sizeof(CubeInfo));