I was wondering if it was possible to have a sprite (well, OpenGL textured quad) which would be the shape of the sprite, but fully white without having to use another white texture. You see this in shoot em ups when your bullets hit an enemy and they "flash white" for an instant.
I thought using:
glBlendFunc(GL_ONE, GL_ONE);
would do it, but it seems it makes it a little white but some colour shows though and the sprite kinda blends a bit into the background (like its a ghost).
Any ideas?
I'm not sure how to implement it,
but what you want to do is copy the alpha channel to the red, green, and blue channels.
If all else fails, use a white version of the sprite I guess.
glBlendFunc won't do what you want, because it controls how the fragments coming from the shape currently being drawn are mixed with the fragments previously stored.
I think the smart way to achieve what you want is via glLight* and glMaterial*. The lighting formula in use seems to suggest that if the ambient light is set to pure white and ambient reflectivity is set to full, you should get a complete reflection of the ambient light colour. I've never really looked at this stuff before though, so I'm quite possibly wrong. In any case values passed to glLight are not clamped, so it should be perfectly possible to create white by ramping things "too high" if necessary.
If you 'render to a texture' first just the color in 4f (1,1,1,1), and then blend in your sprite with (GL_ZERO, GL_SRC_ALPHA), I think that texture should have a white version of your sprite.
Harte: You don't want a complete reflection of the ambient light color, though, do you? You want the ambient light color iff the regular color is not of alpha 0 ... does it do that?
Harte: You don't want a complete reflection of the ambient light color, though, do you? You want the ambient light color iff the regular color is not of alpha 0 ... does it do that?
I assume it does if you use glAlphaFunc to discard all your mask pixels, which is a good thing to be doing anyway because it allows you a fair degree of order independent drawing (or even fully order independent drawing if you have no translucent sprite sections).
I will go away and attempt to test that...
EDIT: as an idea for an alternative to the effect requested which has the benefit requested - i.e. no need to upload a special "white" texture, setting the texture environment mode to blend and setting the current colour to 1, 1, 1 will invert all colours, i.e.
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glColor3f(1, 1, 1);
EDIT2: it also occurs to me that as a desperation measure, the stencil buffer could be used.
EDIT3: skip all that rubbish! Having read up on the GL_BLEND formula, the following should achieve what you want:
GLfloat Colour[4] = {1, 1, 1, 1};
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, Colour);
glColor3f(1, 1, 1);
it certainly works for me. And is fairly self explanatory.
EDIT4: or, in case it isn't, the GL_BLEND formula for calculating the colour of a new fragment is:
(1 - (texture image color))*(glColor colour) + (texture image colour)*(texture environment colour)
Which, given our settings,
= ( 1 - (texture image color))*1 + (texture image color)*1
= 1 - (texture image color) + (texture image color)
= 1
I was wondering if it was possible to have a sprite (well, OpenGL textured quad) which would be the shape of the sprite, but fully white without having to use another white texture. You see this in shoot em ups when your bullets hit an enemy and they "flash white" for an instant.
I'd use fog for that. That's how OpenLayer does it. A modified function from OL's sources:
| 1 | void SetTint( float r, float g, float b, float a) { |
| 2 | // Use linear interpolation // |
| 3 | glFogi( GL_FOG_MODE, GL_LINEAR ); |
| 4 | |
| 5 | float fogCol[] = { r, g, b, 1.0 }; |
| 6 | |
| 7 | glFogfv( GL_FOG_COLOR, fogCol ); |
| 8 | glFogf( GL_FOG_DENSITY, 1.0 ); |
| 9 | |
| 10 | glFogf( GL_FOG_START, -a ); |
| 11 | glFogf( GL_FOG_END, (1.0 - a )); |
| 12 | |
| 13 | // We don't need per-pixel fog, per-verted will do the same // |
| 14 | glHint( GL_FOG_HINT, GL_FASTEST ); |
| 15 | |
| 16 | glEnable( GL_FOG ); |
| 17 | } |
| 18 | |
| 19 | // To tint 100% to white: |
| 20 | SetTint( 1.0, 1.0, 1.0, 1.0 ); |
Harte: Nice. I didn't know what GlTexEnv did, and now I do 
Flad: Also good ... and probably more versatile?
Any analysis of the relative speeds of these techniques?
Flad's is definitely more versatile, as he is applying an arbitrary tint colour whereas I abused a hardcoded 1 in GL_BLEND to produce a 1 as the output for red, green and blue channels.
As for relative speeds, I can't imagine there'll be any significant difference.
Thomas Harte: your method looks like it's relying completely on alpha test to achieve transparency, which will make things a bit ugly at edges. For best effect, you have to keep alpha blending, while making texture color white.
Thomas Harte: your method looks like it's relying completely on alpha test to achieve transparency, which will make things a bit ugly at edges.
If I've understood everything I've read today, it isn't. GL_BLEND lives a double life, both as an alternative to GL_MODULATE, GL_DECAL, etc as ways of deciding what colour is coming from the texture and as the thing passed to glEnable to enable the alpha function specified by glBlendFunc. It does not affect the alpha test whatsoever, although I agree that the GL people have named it confusingly.
The alpha component in GL_BLEND texturing mode is calculated as the multiplication of the alpha passed to glcolor and the alpha stored in the bitmap at the relevant texel, in exactly the same way that it is calculated using GL_MODULATE as a texturing mode.
Thanks everyone! Problem solved!
How I managed to program almost a whole game without any knowledge of glTexEnvf and glFogfv is a surprise. They seem like very useful functions!
I have opted to go with glTexEnvf solution though as it seems simpler.
Thanks again everyone! I learn something new everytime I post a question!
For anyone interested, here is the result.
http://www.banality.net/stuff/ninjawhite.png
Thanks again!
Looks cool! Small note. There's a light box around those jet particles.
Excuse my lack of knowledge but... what is a "light box"?
There are square 'artifacts' that make the particle effect look blocky.
[edit]
Here are some lines that show where the blocks are most visible:
http://derezo.ebtech.net/example.png
Ah thanks! I see. Are there any ways around this or would you just have to make smaller and more particles?
The particle sprites have to be set up properly, that is, the brightness must go down to 0, and the particle must be completely inside the sprite.
I would have thought it's likely to be a part of your particle texture.
EDIT: As Tobias says! Otherwise looking good, by the way.
What about now?
http://www.banality.net/stuff/NinjaFire.png
The texture looked black but upon inspection, the edges were really really dark gray.
Thanks again! You guys rule.
William, Thomas : Thanks for the compliments! Hopefully this game will be finished for you to enjoy.
Yeah that looks much better.
It looks really nice!
Ta!