Render to texture and multi texturing

Hi,

I am currently working on creating a output that uses both render to texture and multi texturing w/ texture combination.

Here are my steps,

  • I have texture 1 and texture 2 which I draw using render to texture and create rt1

  • I assign a texture 3 to TEXTURE0 and and rt1 to TEXTURE1 and use multi texture to create a new output. However, I am redirecting this output again to a new texture using render to texture to generate rt2

I am able to verify my rt1. However I am not able to create rt2. I have to disable multi texturing to make render to texture work in my step 2.

This is my first time playing with multi texturing.

I would like to know if what I am trying to do is feasible.

It would be great if someone here can throw some insights in what could be wrong with my procedure or if there is something that I am missing here.

Thank you.

Unless you are doing this for a device that doesn’t support shaders, I would highly recommend taking a look at them. These sort of things tend to be a lot easier to get a grasp on using shaders.

And yes, it is definitely feasible.

What extensions/GL version are you using for render to texture?

@Mikkel

The GPU I am using doesnt support shaders. So I dont have a choice.

@ Y-tension

I am using version 2.1

Thanks.

…Version 2.1 supports shaders. Do you mean “it doesn’t support shaders in hardware”? like Mesa3D or something?

Are you using framebuffer objects or pbuffers for render to texture?

If it supports shaders in hardware, it’s almost granted that it supports the better framebuffer object extension.

If you use pbuffers, first unbind the pbuffer context before binding its framebuffer as a texture. That is rt2 must be on a different context than rt1, or it will spawn an error.

If you use framebuffer objects I think the only requirement is that you don’t read from and write to the same texture simultaneously.

On another note, if you use NVIDIA’s GL emulator to boost your version to 2.1 on an older card, be aware that framebuffer objects don’t work too well(I couldn’t get them to work anyway, if you have any luck please notify). Use pbuffers instead.

Thank you.

I am currently using my PC which has a ATI chip that supports shaders. However, my end hardware doesnt support shaders.
So I am not using shaders for this.

I think its easier to have this discussion if I can provide the source code here,

create_textures();
standard_open_gl_setup(); //sets up ortho and viewport etc.

glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

/----------------------------------------------------------
Generate frame buffer
----------------------------------------------------------
/
width = 512;
height = 512;

glGenTextures( 1, &fb_tex_one );
glBindTexture( GL_TEXTURE_2D, fb_tex_one );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glGenFramebuffersEXT( 1, &fb_one );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb_one );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, fb_tex_one, 0 );

/----------------------------------------------------------
Draw to framebuffer one
----------------------------------------------------------
/
glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT );

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb_one );

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0f, 512.0f, 512.0f, 0.0f, -1.0f, 1.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, 512, 512 );

glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );

glBindTexture( GL_TEXTURE_2D, bkgd_hnd_rw );
glBegin( GL_QUADS );
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 512.0f, 512.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 512.0f, 0.0f );
glTexCoord2f( 0.0f, 0.0f ); glVertex2f( 0.0f, 0.0f );
glTexCoord2f( 0.0f, 1.0f ); glVertex2f( 0.0f, 512.0f );
glEnd();

glBindTexture( GL_TEXTURE_2D, checkerbox_hnd_rb );
glBegin( GL_QUADS );
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 384.0f, 384.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 384.0f, 128.0f );
glTexCoord2f( 0.0f, 0.0f ); glVertex2f( 128.0f, 128.0f );
glTexCoord2f( 0.0f, 1.0f ); glVertex2f( 128.0f, 384.0f );
glEnd();

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
glPopAttrib();

/----------------------------------------------------------
Draw to frame buffer 2 using multi texture
----------------------------------------------------------
/
glGenTextures( 1, &fb_tex_two );
glBindTexture( GL_TEXTURE_2D, fb_tex_two );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glGenFramebuffersEXT( 1, &fb_two );
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb_two );
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, fb_tex_two, 0 );

glPushAttrib( GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_COLOR_BUFFER_BIT );

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fb_two );

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0f, 512.0f, 512.0f, 0.0f, -1.0f, 1.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, 512, 512 );

glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT );

glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, bkgd_hnd_rw);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, fb_tex_one);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PREVIOUS);

/* what i am trying here is to create a texture
that has the RGB component of fb_tex_one and alpha value
of bkgd_hnd_rw, I might be wrong with my glTexEnvf combinations */

glBegin(GL_QUADS);
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 1.0f);
glMultiTexCoord2f(GL_TEXTURE1, 1.0f, 1.0f);
glVertex2f( 512.0f, 512.0f );
glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 1.0f);
glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 1.0f);
glVertex2f( 0.0f, 512.0f );
glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f);
glMultiTexCoord2f(GL_TEXTURE1, 0.0f, 0.0f);
glVertex2f( 0.0f, 0.0f );
glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 0.0f);
glMultiTexCoord2f(GL_TEXTURE1, 1.0f, 0.0f);
glVertex2f( 512.0f, 0.0f );
glEnd();

glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
glDisable( GL_TEXTURE_2D );
glPopAttrib();

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, fb_tex_one);

glBegin( GL_QUADS );
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 512.0f, 512.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 512.0f, 0.0f );
glTexCoord2f( 0.0f, 0.0f ); glVertex2f( 0.0f, 0.0f );
glTexCoord2f( 0.0f, 1.0f ); glVertex2f( 0.0f, 512.0f );
glEnd();

/----------------------------------------------------------
Draw to screen, from framebuffer
----------------------------------------------------------
/
width = 512;
height = 512;
glViewport( 0, 0, width, height );
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( 0.0f, 512.0f, 512.0f, 0.0f, -1.0f, 1.0f );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glViewport( 0, 0, width, height );

glEnable( GL_TEXTURE_2D );
glEnable(GL_BLEND);
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glPushMatrix();
glTranslatef( 256.0f, 256.0f, 0.0f );
glScalef(128.0f, 128.0f, 1.0f );
glBindTexture( GL_TEXTURE_2D, checkerbox_hnd_ug );
glBegin( GL_QUADS );
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 1.0f, -1.0f );
glEnd();
glPopMatrix();

glEnable( GL_TEXTURE_2D );
glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
glBindTexture( GL_TEXTURE_2D, fb_tex_two );
glPushMatrix();
glTranslatef( 256.0f, 256.0f, 0.0f );
glScalef(128.0f, 128.0f, 1.0f );
glBegin( GL_QUADS );
glTexCoord2f( 1.0f, 1.0f ); glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 0.0f, 1.0f ); glVertex2f( -1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f ); glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex2f( 1.0f, -1.0f );
glEnd();
glDisable( GL_TEXTURE_2D );
glPopMatrix();
glBindTexture( GL_TEXTURE_2D, 0 );
glDeleteFramebuffersEXT( 1, &fb_one );
glDeleteTextures( 1, &fb_tex_one );
glDeleteFramebuffersEXT( 1, &fb_two );
glDeleteTextures( 1, &fb_tex_two );

I am not able to get my second render to texture work. The end image is a single colored texture.

I am currently using my PC which has a ATI chip that supports shaders. However, my end hardware doesnt support shaders.

If your “end hardware” doesn’t support shaders, it certainly doesn’t support EXT_FBO.

So you’ll have to use PBuffers and WGL_ARB_render_texture. Good luck with that…

…As Reiheart said! Don’t expect this to work on old hardware. I had some spare time and tried to implement a WGL_ARB_render_texture approach on my old geforce 3 and it’s a nightmare. I don’t envy those Doom 3 developers!

It’s a lot of code and not the whole of it I understand, so I can’t give a definite answer(I don’t have too much time right now). On first glance framebuffers seem to be set up correctly, so maybe it’s a TexEnv setting, as you write on the comments?