您好我正在尝试使用glDrawArraysInstanced()渲染大量的轴对齐的多维数据集。每个固定尺寸的立方体只能在其中心位置和颜色上有所不同。而且每个立方体只需要几种不同的颜色。所以我想可能使数以百万计的立方体,每个实例的数据如下:OpenGL实例渲染每个实例的颜色和偏移量
struct CubeInfo {
Eigen::Vector3f center; // center of the cube (x,y,z)
int labelId; // label of the cube which affects its color
};
所以我用下面的顶点着色器:
#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;
}
}
和相应的片段着色器:
#version 330
in vec4 color_out;
out vec4 fragColor;
void main()
{
// Set fragment color from texture
fragColor = color_out;
}
但是color_out始终采用默认的灰度值,即使cube_label值介于1到4之间。这是我的问题。我在做什么错误在上面的着色器中**?**
我初始化立方体信息vbo与1-4之间的随机labelIds。因此,我期待看到一个丰富多彩的产量比以下:
这是我的渲染代码,这使得使用Qt的QGLShaderProgram和QGLBuffer包装的:
// 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();
除了我上面的首要问题(色差问题),这是做Minecraft的好方法吗?
更新 如果我改变我的CubeInfo.labelId
属性从int
到float
,以及相应的顶点着色器变量cube_label
也float
,它工作 !!。为什么这样? This page说GLSL suppoers int类型。对于我来说,我更喜欢labelId/cube_label是一些int/short。
UPDATE2:
即使我只是改变GL_FLOAT,而不是在GL_INT下面一行我的渲染代码,我得到应有的颜色。
cubeShaderProgram_.setAttributeBuffer("cube_label", GL_INT, offsetof(CubeInfo,labelId), 1, sizeof(CubeInfo));
它没有Qt的工作吗?我会指出这个问题... – lpapp
我认为问题是cube_label和CubeInfo.labelId的int类型。查看我的更新。为什么int类型不起作用? – iNFINITEi