2016-07-14 268 views
1

我想創建一個火山碎屑卷並將其存儲在3D紋理中。當我在CPU上這樣做時,這不是問題。但是由於CPU對於我的應用程序來說速度很慢,我希望在分層渲染的幫助下在GPU上創建3D紋理。OpenGL分層渲染只渲染零點

現在的問題是,我總是被零填充。沒有隨機數據只是總是零。這是相關的代碼片斷如何看待目前的樣子:

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

我在做什麼錯誤/丟失?

+0

這可能不是問題,但是您在'glVertexAttribPointer'調用旁邊是否缺少'glEnableVertexAttribArray'調用? – BDL

+0

你究竟是什麼意思?我的draw函數實際上有一個'glEnableVertexAttribArray'調用。或者我誤解了你? – Pikkostack

+0

對,對不起。我的評論是廢話:( – BDL

回答

3
layout (max_vertices = 4) out; 

你爲什麼要騙來的OpenGL?該行告訴OpenGL您的GS最多會發出4個頂點。然而,你的GS會發出4 * 32個頂點。

此外,您忘記了gl_Layer是幾何着色器輸出變量。因此,當您致電EmitVertex時,其價值變得不明確。所以每次你發射一個頂點時你都需要設置它。

+0

似乎我誤解了這一點,謝謝你!但這仍然不能解決我的問題,一切都像以前一樣,紋理充滿了零點,絕對沒有OpenGL產生的錯誤。由於您無法在註釋中發佈代碼,因此我使用新的幾何着色器開始發佈。 – Pikkostack