FBO and shaders

Started by
0 comments, last by Daishim 17 years, 4 months ago
I'm running into some interesting issues when using FBO and NV_fragment_program and ARB_fragment_program. Shaders seem to go absolutely nuts when used to render to an FBO. When rendering without shaders to the FBO, everything is fine. When rendering with shaders to non-FBO, everything is fine. Combine the two, and things just go terribly wrong. The fragment program is not complex at all. Is anyone else experiencing issues with this? Framebuffer init code:

// Sets up the render targets of the render buffer for the size passed in
bool Renderer::Setup_Framebuffer(UInt Size)
{
	GLenum Status;		// Status variable for checking the readiness of the framebuffer

	// If framebuffer exists
	if(!m_Framebuffer)
		return false;

	// Create textures for color buffers
	m_Framebuffer->Color_Buffer_A_ID = Create_Texture(Size, NULL);
	m_Framebuffer->Color_Buffer_B_ID = Create_Texture(Size, NULL);

	// If color buffer textures were not created
	if(!m_Framebuffer->Color_Buffer_A_ID || !m_Framebuffer->Color_Buffer_B_ID)
		return false;				// Failed to setup framebuffer

	// Bind framebuffer
	Extensions.p_glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_Framebuffer->Framebuffer_ID);

	// Attach color buffer textures
	Extensions.p_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_Framebuffer->Color_Buffer_A_ID, 0);
	Extensions.p_glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_Framebuffer->Color_Buffer_B_ID, 0);

	// Create the render buffer object for the depth buffer
	Extensions.p_glGenRenderbuffers(1, &m_Framebuffer->Depth_Buffer_ID);

	// If render buffer was not created
	if(!m_Framebuffer->Depth_Buffer_ID)
		return false;				// Failed to setup framebuffer

	// Bind render buffer obect for depth buffer
	Extensions.p_glBindRenderbuffer(GL_RENDERBUFFER_EXT, m_Framebuffer->Depth_Buffer_ID);

	// Instruct the render buffer to act as a depth buffer
	Extensions.p_glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT32, Size, Size);
	
	// Attach render buffer to framebuffer as depth buffer
	Extensions.p_glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_Framebuffer->Depth_Buffer_ID);

	// Check the framebuffer for setup errors
	Status = Extensions.p_glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);

	// If the framebuffer is not ready
	if(Status != GL_FRAMEBUFFER_COMPLETE_EXT)
		return false;				// Failed to setup framebuffer

	// Unbind render buffer and framebuffer
	Extensions.p_glBindRenderbuffer(GL_RENDERBUFFER_EXT, NULL);
	Extensions.p_glBindFramebuffer(GL_FRAMEBUFFER_EXT, NULL);

	return true;
}


Draw code:

Extensions.p_glBindFramebuffer(GL_FRAMEBUFFER_EXT, m_Framebuffer->Framebuffer_ID);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

cgGLEnableProfile(m_Cg.Profile);

cgGLBindProgram(m_Distance_Shader.Program);

if(cgGetError() != CG_NO_ERROR)
	return false;

float Temp[2] = {5.0f / 255.0f, 0.0f};

cgGLSetParameter2fv(m_Distance_Shader.Paramter, Temp);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 1.0f, 1.0f);

Extensions.p_glActiveTexture(OGL_TEX_UNIT(1));
Extensions.p_glClientActiveTexture(OGL_TEX_UNIT(1));
glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, m_Texture_B->IDs[0]);

Extensions.p_glActiveTexture(OGL_TEX_UNIT(0));
Extensions.p_glClientActiveTexture(OGL_TEX_UNIT(0));

glBindTexture(GL_TEXTURE_2D, m_Texture_A->IDs[0]);

glBegin(GL_QUADS);
	glTexCoord2i(0, 0);
	glVertex2i(0, 0);

	glTexCoord2i(0, 1);
	glVertex2i(0, Size);

	glTexCoord2i(1, 1);
	glVertex2i(Size, Size);

	glTexCoord2i(1, 0);
	glVertex2i(Size, 0);
glEnd();

cgGLBindProgram(NULL);

Extensions.p_glActiveTexture(OGL_TEX_UNIT(1));
Extensions.p_glClientActiveTexture(OGL_TEX_UNIT(1));
glDisable(GL_TEXTURE_2D);

Extensions.p_glActiveTexture(OGL_TEX_UNIT(0));
Extensions.p_glClientActiveTexture(OGL_TEX_UNIT(0));

Extensions.p_glBindFramebuffer(GL_FRAMEBUFFER_EXT, NULL);
glDrawBuffer(GL_BACK);

glBindTexture(GL_TEXTURE_2D, m_Framebuffer->Color_Buffer_A_ID);

glBegin(GL_QUADS);
	glTexCoord2i(0, 0);
	glVertex2i(0, 0);

	glTexCoord2i(0, 1);
	glVertex2i(0, Size);

	glTexCoord2i(1, 1);
	glVertex2i(Size, Size);

	glTexCoord2i(1, 0);
	glVertex2i(Size, 0);
glEnd();

glBindTexture(GL_TEXTURE_2D, NULL);

if(!SwapBuffers(m_hdcWindow))
	return false;


Shader code (Cg):

// Determines if the distance between the current element and the reference element is at least 25
float4 main(sampler2D inTexA: TEXTURE0, sampler2D inTexB: TEXTURE1, in float2 inTexCoord: TEXCOORD0, uniform float2 inRefCoord) : COLOR
{
	float Min_Distance = 0.098039215f;			// (25 / 255), distance clamped to 1.0f
	float4 A_Position = tex2D(inTexA, inTexCoord);		// Retrieve the current element from the texture
	float4 B_Position = tex2D(inTexB, inRefCoord);		// Retrieve the reference element from the texture
	float4 Out_Color = 0;	                                // Color output vector

	// If the distance is less than the minimum distance
	if(abs(A_Position.r - B_Position.r) < Min_Distance)
		Out_Color = float4(0.0f, 0.0f, 0.0f, 0.0f);	// Output 0
	else	// Distance is greater than minimum
		Out_Color = float4(1.0f, 1.0f, 1.0f, 1.0f);	// Output white, max
	
	return Out_Color;
}


The previous code should output black for pixels with red components less than 25 from the reference pixel. This works correctly when not rendering to an FBO. It renders solid white when rendering to an FBO. However, if I change the else to Out_Color = A_Position, it works. By working, I mean that instead of solid white, the pixels that are supposed to be black (less than 25) are actually black, and the pixels that would be white (25 or greater) are the color of A_Position for that pixel. Any ideas? Thanks.

I know only that which I know, but I do not know what I know.
Advertisement
Ugh. I didn't disable the profile, I did disable the shader though, before rendering from the FBO to the framebuffer. It works fine now.

I know only that which I know, but I do not know what I know.

This topic is closed to new replies.

Advertisement