Lightmapping with multitexturing

I’m trying to speed my lightmapping engine up a little by using multitexturing. After reading about the multitexturing extension in the OpenGL SuperBible it seamed so easy to use. But I guess I’ve missed something, it’s not working …

This is how I try to do it:

void Quad::draw(){

// Old singletexturing working code.

/* LightMap->setCurrent();
glDisable(GL_BLEND);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(0,0);
glVertex3fv((float *) &v0);
glTexCoord2f(1,0);
glVertex3fv((float *) &v1);
glTexCoord2f(0,1);
glVertex3fv((float *) &v2);
glTexCoord2f(1,1);
glVertex3fv((float *) &v3);
glEnd();

BaseTexture->setCurrent();
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
glBegin(GL_TRIANGLE_STRIP);
	glTexCoord2f(0,0);
	glVertex3fv((float *) &v0);
	glTexCoord2f(1,0);
	glVertex3fv((float *) &v1);
	glTexCoord2f(0,1);
	glVertex3fv((float *) &v2);
	glTexCoord2f(1,1);
	glVertex3fv((float *) &v3);
glEnd();

*/

// My new multitexturing code producing nothing but black screen

glActiveTexture(GL_TEXTURE0_ARB);
glDisable(GL_BLEND);
LightMap->setCurrent();


glActiveTexture(GL_TEXTURE1_ARB);
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
BaseTexture->setCurrent();

glBegin(GL_TRIANGLE_STRIP);
	glMultiTexCoord2f(GL_TEXTURE0_ARB,0,0);
	glMultiTexCoord2f(GL_TEXTURE1_ARB,0,0);
	glVertex3fv((float *) &v0);
	glMultiTexCoord2f(GL_TEXTURE0_ARB,1,0);
	glMultiTexCoord2f(GL_TEXTURE1_ARB,1,0);
	glVertex3fv((float *) &v1);
	glMultiTexCoord2f(GL_TEXTURE0_ARB,0,1);
	glMultiTexCoord2f(GL_TEXTURE1_ARB,0,1);
	glVertex3fv((float *) &v2);
	glMultiTexCoord2f(GL_TEXTURE0_ARB,1,1);
	glMultiTexCoord2f(GL_TEXTURE1_ARB,1,1);
	glVertex3fv((float *) &v3);
glEnd();

}

The full source + executable can be found here .

You don’t need to a activate Blending for multitexturing to work. What you do need to specify an alpha channel.
-Trotsky

You simply need to modulate the two textures together.

if you texture is Rt,Gt,Bt and your lightmap is Rl,Gl,Bl, then if you ask for modulation the color you get is :

RtRl,GtGl,Bt*Bl

it is also true if you lightmap is greyscale.

RtL, GtL, Bt*L

Thanks, but I’m not getting it to work.

Is it this you mean:
glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);

yes it is what I mean. Are you setting the modulation for your lightmap or your object texture?

My object texture. But switching makes no difference. After turning the blending off my lightmap is visible, but not my basetexture.

Could you post a piece of working lightmapping code?

[This message has been edited by Humus (edited 08-25-2000).]

You have to set it for the lightmap.

for your object texture use GL_REPLACE if you don’t need to blend it with anything else. GL_REPLACE will simply take the color of the texture and apply it to the polygon.

I don’t know if you read the Red book, but the all the example uses GL_MODULATE for the base texture, but this is simply they use the opengl lighting equation. You see, texture mapping is done after the lighting, so you need to modulate your texture to see the effect of lighting. But in your case, you are probably not using opengl lighting, so use GL_REPLACE, it will give you a little performance boost because there will not be any multiplication for that sequence.

And then, for your lightmap, you use GL_MODULATE. This will modulate the color of the object with the color/luminance value(s) in your lightmap.

so, pseudo code

set texture options for unit 1
glTexEn( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE )
create the base texture object

set texture options for unit 2
glTexEn( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE )
create the lightmap texture

draw your stuff!

[This message has been edited by Gorg (edited 08-25-2000).]

[This message has been edited by Gorg (edited 08-25-2000).]

Hmm … it aint working …
This is the code right now, can you see any errors here?

glActiveTexture(GL_TEXTURE0_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
BaseTexture->setCurrent();

glActiveTexture(GL_TEXTURE1_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
LightMap->setCurrent();

glBegin(GL_TRIANGLE_STRIP);
glMultiTexCoord2f(GL_TEXTURE0_ARB,0,0);
glMultiTexCoord2f(GL_TEXTURE1_ARB,0,0);
glVertex3fv((float *) &v0);
glMultiTexCoord2f(GL_TEXTURE0_ARB,1,0);
glMultiTexCoord2f(GL_TEXTURE1_ARB,1,0);
glVertex3fv((float *) &v1);
glMultiTexCoord2f(GL_TEXTURE0_ARB,0,1);
glMultiTexCoord2f(GL_TEXTURE1_ARB,0,1);
glVertex3fv((float *) &v2);
glMultiTexCoord2f(GL_TEXTURE0_ARB,1,1);
glMultiTexCoord2f(GL_TEXTURE1_ARB,1,1);
glVertex3fv((float *) &v3);
glEnd();

Sorry got a little bit messed up in my pseudo-code so forget about it, you should set your texture current and then set the glTexEnv. I am assuming that setCurrent call glBindTexture.

This is because the glTexEnv only works for the texture that is binded for rendering.

glActiveTexture(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
BaseTexture->setCurrent();
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

glActiveTexture(GL_TEXTURE1_ARB);
glEnabled(GL_TEXTURE_2D);
LightMap->setCurrent();
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

You also have to glEnable(GL_TEXTURE_*) for each texture unit to tell the unit what kind of texturing should be done.

Don’t worry, we’ll make it work!!

[This message has been edited by Gorg (edited 08-25-2000).]

Hallelujah! It works now. And you know what my stupid little error was? Never called glEnable(GL_TEXTURE_2D) for the second TMU …

Nice, got a speed improvement at 20% (I was hoping for more …) over dualpass.

Now, just one little question remains. In my multipass renderer i used glBlendFunc(GL_DST_COLOR,GL_SRC_COLOR), which gives me the color (2RbRl, 2GbGl, 2BbBl) so any light value above 0.5 will brigthen the pixel, how can I reproduce that with multitexturing?

before calling glTexImage2d for your lightmap, do this

glPixelTransferf( GL_RED_SCALE, 2.0 );
glPixelTransferf( GL_GREEN_SCALE, 2.0 );
glPixelTransferf( GL_BLUE_SCALE, 2.0 );
//Alpha if you have one also
This will make all your colors in you lightmap in memory have twice the value they have on disk.

Just don’t forget to put the values back to 1.0 for you next texture!

I generate my lightmaps dynamically by doing raytracing and applying the OpenGL lighting equation at all texel in the lightmap. But scaling all colors in the lightmap that way isn’t what I wanted. You can still not get a pixel brighter than it is on the basetexture, you’ll only saturate the colors. You have only a the 0…1 interval. With multipass and blending function glBlend(GL_DST_COLOR,GL_SRC_COLOR) you get an interval of “0…2”, actually still 0…1 but everything above 0.5 brightens the color. This way you’ll get a “active filter”, contrary the normal “passive filter” when lightmapping.

There has to be a way to do it with multitexturing.

[This message has been edited by Humus (edited 08-26-2000).]

I see. hmm. I must admit I have no clue this time.

If only we could use blending with multitexuring. but from the documentation, blending only applies to the fragment and the framebuffer, and doesn’t seem to fit in the middle of the multi texture pipeline.

I guess you could try that(I am far away from my development tools right now, so I cannot test anything), you have nothing to lose:

When you setCurrent your lightmap,

glEnable( GL_BLEND )
glBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );

Like I said, I don’t know what will happen. Let me know if you try it.

I read about it over at nehe. I’ve found out that blending only applies at the first TMU. It seams that I need the GL_EXT_texture_env_combine extension to do more than GL_MODULATE between the texturing units. Sadly enough, it’s not supported by my G400

Originally posted by Humus:
I read about it over at nehe. I’ve found out that blending only applies at the first TMU. It seams that I need the GL_EXT_texture_env_combine extension to do more than GL_MODULATE between the texturing units. Sadly enough, it’s not supported by my G400

I thing that GL_ARB_texture_env_add or the older GL_EXT_texture_env_add can do the job, too. What about these extensions on your G400?

No, not available … these are the extension I have:

GL_ARB_multitexture
GL_SGIS_multitexture
GL_Autodesk_facet_normal
GL_EXT_abgr
GL_EXT_bgra
GL_EXT_compiled_vertex_array
GL_EXT_packed_pixels
GL_EXT_stencil_wrap
GL_EXT_texture_edge_clamp
GL_EXT_vertex_array
GL_KTX_buffer_region
GL_WIN_swap_hint
WGL_EXT_swap_control

Well … I’m probably gonna buy a new card anyway.