OpenGL分层渲染仅渲染零

时间:2016-07-14 08:43:40

标签: opengl rendering framebuffer 3d-texture

我想创建一个火山碎屑卷并将其存储在3D纹理中。当我在CPU上执行此操作时,这不是问题。但由于CPU对我的应用程序来说速度慢,我想借助分层渲染在GPU上创建3D纹理。

现在的问题是我总是被零填满。没有随机数据总是零。这就是相关代码片段当前的样子:

void init()
{
// ....

GLfloat data[] =
{
  0.0f, 0.0f, 0.0f,
};

VBO = VertexBufferObject::create();
VBO->bind(GL_ARRAY_BUFFER);
VBO->setNewData(3 * sizeof(float), data, GL_STREAM_DRAW);
VBO->unbind();

glGenFramebuffers(1, &densityFBO);
glBindFramebuffer(GL_FRAMEBUFFER, densityFBO);
glGenTextures(1, &densityFBOTex);
glBindTexture(GL_TEXTURE_3D, densityFBOTex);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, 256, 256, 32, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_3D, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, densityFBOTex, 0);
qDebug() << glCheckFramebufferStatus(GL_FRAMEBUFFER); // returns complete
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void createDensityTextureOnGPU()
{
   glBindFramebuffer(GL_FRAMEBUFFER, densityFBO);
   GLint vp[4];
   glGetIntegerv(GL_VIEWPORT, vp);
   glViewport(0, 0, 256, 256);
   glClear(GL_COLOR_BUFFER_BIT);

   shader->start();
   draw();
   shader->stop();

   glBindFramebuffer(GL_FRAMEBUFFER, 0);
   glViewport(vp[0], vp[1], vp[2], vp[3]);
}

void draw()
{
   glEnableVertexAttribArray(0);
   VBO->bind(GL_ARRAY_BUFFER);
   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
   glDrawArrays(GL_POINTS, 0, 1);
   VBO->unbind(GL_ARRAY_BUFFER);
   glDisableVertexAttribArray(0);
}

着色器:

// VERTEX
#version 440 compatibility

layout(location = 0) in vec3 vertexPosition;

out vec3 vPosition;

void main()
{
    vPosition = vertexPosition;
    gl_Position = vec4(vertexPosition, 1.0);
}

// GEOMETRY
#version 440 compatibility

layout (points) in;
layout (triangle_strip) out;
layout (max_vertices = 128) out;

in vec3 vPosition[1];

void main()
{
    for (int i = 0; i < 32; ++i)
    {

        gl_Layer = i;
        gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);
        EmitVertex();
        gl_Layer = i;
        gl_Position = vec4(1.0, -1.0, 0.0, 1.0);
        EmitVertex();
        gl_Layer = i;
        gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);
        EmitVertex();
        gl_Layer = i;
        gl_Position = vec4(1.0, 1.0, 0.0, 1.0);
        EmitVertex();

        EndPrimitive();
    }
}

// FRAGMENT
#version 440 compatibility

layout (location = 0) out float fragColor;

void main()
{
    fragColor = 0.5;
}

我做错了什么/失踪了?

1 个答案:

答案 0 :(得分:3)

layout (max_vertices = 4) out;

你为什么骗OpenGL?该行告诉OpenGL你的GS将发出最多4个顶点。然而,你的GS会发出4 * 32个顶点。

另外,您忘记了gl_Layer是几何着色器输出变量。因此,当您致电EmitVertex时,其值将变为未定义。因此,每次发射顶点时都需要设置它。