Pointcloud渲染,交错式VBO

时间:2014-08-30 02:33:02

标签: opengl glsl vbo point-clouds

我正在尝试渲染一个有7个组件的vbo(交织正确吗?)。 前4个是x,y,z,w(w是比例因子),其余3个用于亮度调整 在片段着色器中。

这是我创建vbo的方式:

std::vector<float> pointCloudData;
while(endOfFile != true){

    ... // a lot of textfile handling/reading before, total of 100361 coordinates read. 

    for (int i = 0; i < 4; i++){
        pointCloudData.push_back(xyzFromFile[i]); //store the read x y z w coordinate
    }
    // store extra data
    // right now im setting everything to 1.f just to see results in fragment shader!
    pointCloudData.push_back(1.f);
    pointCloudData.push_back(1.f);
    pointCloudData.push_back(1.f);
}

v_size = pointCloudData.size();

// create vbo 
glGenVertexArrays(1, &_vaoID);
    glGenBuffers(1, &_vboID);
    glBindVertexArray(_vaoID);
    glBindBuffer(GL_ARRAY_BUFFER, _vboID);
    glBufferData(GL_ARRAY_BUFFER, v_size*sizeof(GLfloat), &pointCloudData[0], GL_DYNAMIC_DRAW);
glBindVertexArray(0);

在渲染方法中:

    glBindVertexArray(_vaoID);
    glBindBuffer(GL_ARRAY_BUFFER, _vboID);
    glEnableVertexAttribArray(positionAttrib);

    GLsizei stride = sizeof(GLfloat) * 7;
    glVertexAttribPointer(positionAttrib, 4, GL_FLOAT, GL_FALSE, stride, (void*)0); // x y z
    glVertexAttribPointer(brightnessDataAttrib, 3, GL_FLOAT, GL_FALSE, stride, (void*)(4 * sizeof(GLfloat))); // remaining data

    glDrawArrays(GL_POINTS, 0, vertsToDraw); 
    glDisableVertexAttribArray(positionAttrib);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

顶点着色器:

layout(location = 0) in vec4 in_position;
layout(location = 2) in vec3 in_brightness;

out vec3 vs_brightness;
void main()
{ 
    vs_brightness = in_brightness;
    gl_Position =  ViewProjection * vs_position;
}

片段着色器:

in vec3 vs_brightness;
void main(void)
{
    diffuse = vec4(vs_brightness[1],0,0,1); // at this point i just want SOMETHING to show up
}

如果这是一种不好的方式,我怎么能以不同的方式做到这一点?如何将剩余的3个标量发送到片段着色器? (它共有3 * 100361个标量)。

1 个答案:

答案 0 :(得分:1)

这看起来很好看。但是,您永远不会启用第二个顶点属性。你需要在设置代码中的某个地方使用它:

glEnableVertexAttribArray(brightnessDataAttrib);

这假定positionAttrib为0且brightnessDataAttrib为2,与顶点着色器中的位置匹配。

虽然不是正确性问题,但您没有充分利用VAO。在设置过程中,您创建并绑定VAO,但之后不要设置在VAO中跟踪的任何状态。相反,你在绘制调用中拥有所有这些。这违背了使用VAO的目的。这个想法是它保持所有顶点设置状态,然后你可以通过简单地再次绑定VAO来获得绘制所需的所有状态。

因此在设置代码中,更好的结构如下所示:

glBindBuffer(GL_ARRAY_BUFFER, vboID);
glBufferData(GL_ARRAY_BUFFER, ...);

glBindVertexArray(vaoID);
glEnableVertexAttribArray(...);
glVertexAttribPointer(...);
glBindVertexArray(0);

glBindBuffer(GL_ARRAY_BUFFER, 0);

然后在绘图代码中,您只需要这个:

glBindVertexArray(vaoID);
glDrawArrays(...);
glBindVertexArray(0);

如果您在所有代码中使用VAO,则glBindVertexArray(0)调用并不是必需的,因为每个人都会在绘制之前绑定必要的VAO。有些人喜欢明确的unbind,以防代码的其他部分想要在没有VAO的情况下呈现。但这不是浪费。