Multiply blending in OpenGL
Kitty Cat

I asked in #allegro the other day, and despite getting an answer from Bob, it's still not working right. I need to figure out how to do multiply blending in OpenGL so I can properly overlay a lightmap on a polygon. Yeah I know I should use multitexturing, but besides wanting to support cards that may not have it (I don't think mine does), the engine is already setup to do a double-pass for lighting. When I asked on IRC, I was told:
glBlendFunc(GL_DST_COLOR, GL_ZERO);however that didn't work. Doing this, however:
glBlendFunc(GL_ZERO, GL_DST_COLOR);somewhat works, but not fully. That just applies the lightmap's color to the polygon, but doesn't actually do the lighting (eg. it doesn't darken anything, just colorizes).

Grepping around the gl headers for multiply, google searches for opengl multiply blending, and forum searches for the same have turned up nothing. Can someone tell me what I'm doing wrong?


Actually, the second one should be "GL_SRC_COLOR". I'm not sure that OpenGL even allows the dest color to be multiplied by itself like that.

But yes, the first one ought to work.

Did you glEnable(GL_BLEND);? A common mistake with many OpenGL states.

Kitty Cat

glEnable(GL_BLEND);is called, and these are the results:

No lightmaps:



If I could subtract the inverse blend color, that might work too, but a tutorial on using Q2 lightmaps says that the lightmap should be multiply-blended on top of the polygon face.

Actually.. you know I'm not even sure if the lightmap is even really working. When I try to display just the lightmap, I get a level full of solid brown (no light or color variation at all). So maybe DST_COLOR, SRC_COLOR does work, but the lightmap just isn't being used right.


So maybe DST_COLOR, SRC_COLOR does work, but the lightmap just isn't being used right.

DST_COLOR, SRC_COLOR will compute:

final = texture * fb + fb * texture

You want:

final = texture * fb

Which is done either by:

DST_COLOR, ZERO (final = texture * fb)
ZERO, SRC_COLOR (final = fb * texture)

If you didn't enable blending, then obviusly it will not work.


What does the lightmap look like?

Kitty Cat

Originally it was just solid brown. However, playing around with the texture settings (enabling wrapping instead of clamping), I get this to appear. This image shows just the "lightmap", and not the texture underneath.

That does not at all look right.


Oh, I should add that Quake plays with the gamma setting to lighten up the game. Most likely, the textures are inverse-gamma-corrected to compensate.

So if you don't also change the gamma ramps, you won't get the same effect.


That does not at all look right.

Is that the image you loaded? That doesn't look like a resonable light map.

Are you loading it or generating it by hand?

Also, since it's a light map, you may want to consider using an Intensity or Luminance format, rather than an RGB one. They take up much less room (on hardware that can support them).


That doesn't look like a resonable light map.

It might be a colored lightmap. Arguably, colored lightmaps have limited uses, but still... :)

Kitty Cat

That's the lightmap the engine takes from the Quake 2 demo pak. As an update, I finally got it working. The original source used min/max where the proper header wasn't included in Linux. I created static inline versions using Bob's branchless method, but failed to realize min/max could be, and were, used on floats. It was getting the wrong image all along. So I made simple defines that dealt with any number type, and it all looks pretty now. Though it seems the gamma needs to be played with a bit (the game palette's intensity is doubled, so that's what I'm going to try to do to the lightmap). I'll post a screeny when I do.


Glad you got it working!

[Insert secret purpose for post]So Kitty Cat can post pretty screenies![/Insert secret purpose for post]

Kitty Cat

Ok. I'm not sure what to do about the lightmap. When I run it it looks properly lit to me, but I dunno. Here's a screenie:



Sweet screenie ...

Thread #359405. Printed from