Hi,
I'm trying to do voxelization by using depth peeling techniques, the technologies involved in this are FBO, Occlusion Query, and Cg.
I accomplish this by rendering to texture in each step, and then the texture is used as reference for the next step. What's rendered to the texture is just the depth value which I computed in Vertex and Fragment Shader. To determine when to stop, I use occlusion query.
The problem is, seems that nothing is drawn to the texture bound to FBO, thus the occlusion query always return 0.
Is there anything wrong with my implementation of FBO ?
Thanks.
void voxelize()
{
GLuint query, texReferred;
GLuint fbo;
GLuint sampleCount=1;
GLfloat depthTexRef[SIZE*SIZE*3]={0.0}, depthTexture2[SIZE*SIZE*3];
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glGenQueries(1, &query);
GLUI_Master.auto_set_viewport();
glViewport (0, 0, SIZE, SIZE);
glGenTextures(1, &texReferred);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texReferred);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glPushMatrix();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
cgGLEnableProfile(cgFragmentProfile); // Enable Our Fragment Shader Profile
cgGLEnableProfile(cgVertexProfile); // Enable Our Vertex Shader Profile
// Bind Our Vertex Program To The Current State
cgGLBindProgram(cgProgramF);
cgGLBindProgram(cgProgramV);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
for(int direction=0; direction<1; direction++)
{
sampleCount=1;
for(int i=0; i<SIZE*SIZE*3; i++)
depthTexRef=0.0;
glBindTexture(GL_TEXTURE_2D, texReferred);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SIZE, SIZE, 0, GL_RGB, GL_FLOAT, depthTexRef);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-0.5, 0.5, -0.5, 0.5, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
switch(direction)
{
case DIR_FRONT:
gluLookAt(0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
break;
case DIR_RIGHT:
gluLookAt(0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
break;
case DIR_TOP:
gluLookAt(0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
break;
}
model.transformModel();
cgGLSetStateMatrixParameter(modelViewProj, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
while(sampleCount!=0)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLuint texTarget;
glGenTextures(1, &texTarget);
glBindTexture(GL_TEXTURE_2D, texTarget);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SIZE,SIZE, 0, GL_RGB, GL_FLOAT, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texTarget, 0);
glBindTexture(GL_TEXTURE_2D, texReferred);
glBeginQuery(GL_SAMPLES_PASSED, query);
model.drawModel();
glEndQuery(GL_SAMPLES_PASSED);
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &sampleCount);
cout << sampleCount << endl; //the output is 0 here, which it shouldn't happen
//post processing
if(sampleCount!=0)
{
glBindTexture(GL_TEXTURE_2D, texTarget);
glGetTexImage(GL_TEXTURE_2D,0, GL_RGB, GL_FLOAT, depthTexture2);
// glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, 0, 0);
glBindTexture(GL_TEXTURE_2D, texReferred);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, SIZE, SIZE, 0, GL_RED, GL_FLOAT, depthTexture2);
switch(direction)
{
case DIR_FRONT:
for(GLint i=0; i<SIZE; i++)
for(GLint j=0; j<SIZE;j++)
{
if(depthTexture2[(3*i+3*j*SIZE)+1]>0.0)
bound[j][(GLint)(SIZE-(depthTexture2[i*3+j*SIZE*3]*SIZE))]=1;
}
break;
case DIR_RIGHT:
break;
case DIR_TOP:
break;
}
}
}
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
glDisable(GL_TEXTURE_2D);
cgGLDisableProfile(cgVertexProfile);
cgGLDisableProfile(cgFragmentProfile);
GLUI_Master.auto_set_viewport();
glViewport (0, 0, (GLsizei) winwidth, (GLsizei) winheight);
glDeleteFramebuffersEXT(1, &fbo);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
The vertex and fragment shader.
struct VertLBMOut {
float4 color : COLOR;
float4 screen : TEXCOORD0;
float4 position : POSITION;
};
struct VertLBMIn {
float4 position : POSITION;
float4 color : COLOR;
uniform float4x4 modelViewProj;
};
VertLBMOut main(VertLBMIn IN)
{
VertLBMOut OUT;
OUT.color = IN.color;
OUT.position = mul(IN.modelViewProj, IN.position);
OUT.screen=OUT.position.xyzw/OUT.position.wwww;
OUT.screen=OUT.screen*0.5 + 0.5;
return OUT;
}
struct FragLBMOut {
float4 newDepth : COLOR;
float depth : DEPTH;
};
struct FragLBMIn {
float4 color : COLOR;
float4 screen : TEXCOORD0;
float4 position : POSITION;
uniform sampler2D depthMap;
};
FragLBMOut main(FragLBMIn IN)
{
FragLBMOut OUT;
float4 depthM;
depthM=tex2D(IN.depthMap, IN.screen.st);
if(IN.screen.z<=depthM.r)
{
OUT.newDepth.x=depthM.r;
OUT.newDepth.y=0.0;
}
else
{
OUT.newDepth.xy=IN.screen.z;
}
return OUT;
}