Jump to content
  • Advertisement
Sign in to follow this  
EonStrife

FBO, help !

This topic is 3810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement

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



I didn't look at the code in detail, but here you are forgeting to call glTexParameter. By default, MIN_FILTER is GL_LINEAR_MIPMAP_NEAREST so you need to either generate mipmaps with glGenerateMipmapsEXT or use GL_LINEAR.

Share this post


Link to post
Share on other sites
Thanks.
Something is drawn, but the result of the glGetTexImage is still wrong.

My program works like this, I bind a texture to be read in Cg as reference, and I attach another texture to FBO as rendered target. After finishing the rendering, I retrieve the resulting texture from FBO and 'merge' it with the aforementioned reference texture, and do the process again. Here's the rundown of my program (just ignore the one I wrote in the previous post):



GLuint query, texReferred, texTarget;
GLuint fbo;
GLuint sampleCount=1;
GLfloat depthTexRef[SIZE*SIZE*4]={0.0}, depthTexture2[SIZE*SIZE*4];

glGenFramebuffersEXT(1, &fbo);
glGenQueries(1, &query);

GLUI_Master.auto_set_viewport();
glViewport (0, 0, SIZE, SIZE);

glEnable(GL_TEXTURE_2D);

glGenTextures(1, &texTarget); //this one as rendered target, will be bound to fbo
glBindTexture(GL_TEXTURE_2D, texTarget);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glGenTextures(1, &texReferred); //this one will be used as reference for the Cg program
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);
.
.
.

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

for(int direction=0; direction&lt;3; direction++)
{
sampleCount=1;
for(int i=0; i&lt;SIZE*SIZE*4; i++)
depthTexRef=0.0;


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-0.5, 0.5, -0.5, 0.5, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(...)
model.transformModel();
cgGLSetStateMatrixParameter(modelViewProj, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);

while(sampleCount!=0)
{
glBindTexture(GL_TEXTURE_2D, texReferred);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SIZE, SIZE, 0, GL_RGBA, GL_FLOAT, depthTexRef);
cgGLSetTextureParameter(cgTextureRef, texReferred);
cgGLEnableTextureParameter(cgTextureRef);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glBindTexture(GL_TEXTURE_2D, texTarget);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, SIZE,SIZE, 0, GL_RGBA, GL_FLOAT, NULL);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texTarget, 0);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glBindTexture(GL_TEXTURE_2D, texReferred);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBeginQuery(GL_SAMPLES_PASSED, query);
model.drawModel();
glEndQuery(GL_SAMPLES_PASSED);
glGetQueryObjectuiv(query, GL_QUERY_RESULT, &sampleCount);

cgGLDisableTextureParameter(cgTextureRef);

if(sampleCount!=0)
{
glBindTexture(GL_TEXTURE_2D, texTarget);
glGetTexImage(GL_TEXTURE_2D,0, GL_RGBA, GL_FLOAT, depthTexture2); //the returned result is not quite right, even if I comment the model.drawModel(); line, it will still return some random values
//.
//do some process here
//.

//merge the rendered texture with reference texture
for(GLint i=0; i&lt;SIZE*SIZE; i++)
if(depthTexRef[i*4]&lt;depthTexture2[i*4])
depthTexRef[i*4]=depthTexture2[i*4];
}

}
}

glDisable(GL_TEXTURE_2D);

cgGLDisableProfile(cgVertexProfile);
cgGLDisableProfile(cgFragmentProfile);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!