PDA

View Full Version : FBO and multitexture combiners



renaissanz
07-15-2006, 01:04 PM
Hi, trying to use a combination of FBO and texture combiners. Basic principle is:

create FBO
create textures, attach to FBO
loop: first glCopyTexImage2D to get pre-RGBA data into a texture, clear buffers, render to FBO, glCopyTexImage2D to get post-RGBA data into a texture, then use a texture combiner to interpolate a result.

Here's the code:

init:

if(m_hFrameBuffer != 0)
glDeleteFramebuffersEXT(1, &m_hFrameBuffer);
glGenFramebuffersEXT(1, &m_hFrameBuffer);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_hFrameBuffer);

// before the volume is rendered
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
if(m_uiBeforeTexture == 0)
glGenTextures(1, &m_uiBeforeTexture);
glBindTexture(GL_TEXTURE_2D, m_uiBeforeTexture);
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA8,
glReadWidth,
glReadHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0 );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_uiBeforeTexture, 0 );

// after the volume is rendered
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
if(m_uiAfterTexture == 0)
glGenTextures(1, &m_uiAfterTexture);
glBindTexture(GL_TEXTURE_2D, m_uiAfterTexture);
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA8,
glReadWidth,
glReadHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
0 );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );

glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_uiAfterTexture, 0 );

// check that the frame buffer was correctly initialized
GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );

switch( status )
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
Log("Attached frame buffer!");
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
Log("Frame buffers are unsupported!");
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
Log("Frame buffer missing attachment!");
break;
default:
Log("Failed to attach frame buffer! Error = " + IntToStr(status));
break;
}

// go back to the default frame buffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);loop:

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_hFrameBuffer);

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_uiBeforeTexture);

if(i == 0)
{
unsigned char * beforeBuffer = new unsigned char[glReadWidth * glReadHeight * 4];
memset(beforeBuffer, 0x0, 4 * glReadWidth * glReadHeight);
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA8,
glReadWidth,
glReadHeight,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
beforeBuffer );
delete [] beforeBuffer;
}
else
{
glCopyTexImage2D( GL_TEXTURE_2D,
0,
GL_RGBA8,
0,
0,
glReadWidth,
glReadHeight,
0);
}
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_uiBeforeTexture, 0 );

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
RenderVolume(start, end, multiRenderFlag);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

...<render planes of volumetric data>...

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_hFrameBuffer);
//================================================== ========
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_uiAfterTexture);
glCopyTexImage2D( GL_TEXTURE_2D, // target
0, // texture
GL_RGBA8, // internal format
0, // x
0, // y
glReadWidth, // width
glReadHeight, // height
0 ); // border
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_2D, m_uiAfterTexture, 0 );

GLfloat constAlpha[] = {1.0f, 0.0f, 0.0f, (20.0f - (GLfloat)i) / 19.0f};

glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constAlpha);

glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE0);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);

glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_TEXTURE1);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);

glTexEnvf(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_CONSTANT);
glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, m_uiAfterTexture);

glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f);

glTexCoord2f(-1.0f, -1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);

glTexCoord2f( 1.0f, -1.0f);
glVertex3f(2.0f, 0.0f, 0.0f);

glTexCoord2f( 1.0f, 1.0f);
glVertex3f(2.0f, 1.5f, 0.0f);

glTexCoord2f(-1.0f, 1.0f);
glVertex3f(0.0f, 1.5f, 0.0f);
glEnd();

glDisable(GL_TEXTURE_2D);

float lineWidth;
glGetFloatv(GL_LINE_WIDTH, &amp;lineWidth);

glLineWidth(6.0f);
glBegin(GL_LINE_LOOP);
glNormal3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(2.0f, 0.0f, 0.0f);
glVertex3f(2.0f, 1.5f, 0.0f);
glVertex3f(0.0f, 1.5f, 0.0f);
glEnd();

glLineWidth(lineWidth);

glEnable(GL_TEXTURE_2D);

glFlush();
SwapBuffers(hdc);As you can see, right there at the end I'm mapping what should be the end result of the texture combiner onto a
quad so I can see what's going on. So far, nothing but black. Blech!

Anybody have any nuggets of wisdom to share? I'm flying by the seat of my pants, so I'm sure I must be doing something
wrong.

Thanks,
Matt