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, &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