1

I want to create a pyroclastic volume and store it in a 3D-Texture. This is no Problem when I do this on the CPU. But since the CPU is to slow for my application I want to create the 3D-Texture on the GPU with the help of layered rendering.

The problem is now that my always gets filled with zeros. No random data just always zeros. That is how the relevant code snippets look at the moment:

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);
}

And the shaders:

// 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;
}

What am I doing wrong/missing?

Pikkostack
  • 540
  • 1
  • 9
  • 23
  • This might not be the problem, but are you missing a `glEnableVertexAttribArray` call next to the `glVertexAttribPointer` call? – BDL Jul 14 '16 at 09:47
  • What exactly do you mean? I actually have a `glEnableVertexAttribArray` call in my draw function. Or am I misunderstanding you? – Pikkostack Jul 14 '16 at 15:07
  • Yeah, sorry. My comment was nonsense :( – BDL Jul 14 '16 at 16:26

1 Answers1

3
layout (max_vertices = 4) out;

Why did you lie to OpenGL? That line tells OpenGL that your GS will emit at most 4 vertices. Yet, your GS will emit 4 * 32 vertices.

Also, you've forgotten that gl_Layer is a geometry shader output variable. And as such, its value becomes undefined when you call EmitVertex. So you will need to set it every time you emit a vertex.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • It seems that I missunderstood that points. Thank you for that! But this still doesn't solve my problem. Everything is like before. Texture full of zeros and absolutely no errors generated by OpenGL. I edited my starting post with my new geometry shader since you can't post code in comments. – Pikkostack Jul 14 '16 at 15:01