Want to rewrite the pixel buffer

Started by
6 comments, last by 21st Century Moose 11 years, 9 months ago
Hello there,

I am trying to do some post rendering effect like a color shift to red when the character dies, or maybe a shift to black to make it darker. Here's the piece of code I have cooked up:

----
float normalColor[3] = { float(colorToShift.Get().r.Get()) / 0xFF,
float(colorToShift.Get().g.Get()) / 0xFF,
float(colorToShift.Get().b.Get()) / 0xFF };
GLfloat *data = ((GLfloat *)malloc(3 * screenWidth.Get() * screenHeight.Get() * sizeof(GLfloat)));
if( data )
{
glReadPixels(0, 0, screenWidth.Get(), screenHeight.Get(), GL_RGB, GL_FLOAT, data);
}
else
{
return;
}
for( int i = 0; i < screenWidth.Get() * screenHeight.Get() * 3; i += 3 )
{
GLfloat *dataR = data + i + 0;
GLfloat *dataG = data + i + 1;
GLfloat *dataB = data + i + 2;
*dataR = min( 1.0, max( 0.0, *dataR + ( normalColor[0] - *dataR ) * degree.Get()));
*dataG = min( 1.0, max( 0.0, *dataG + ( normalColor[1] - *dataG ) * degree.Get()));
*dataB = min( 1.0, max( 0.0, *dataB + ( normalColor[2] - *dataB ) * degree.Get()));
}

glDrawPixels(screenWidth.Get(), screenHeight.Get(), GL_RGB, GL_FLOAT, data);
------

The program has read the pixel fine with glReadPixel, the pixel processing is working, but glDrawPixel is not doing anything. I basically want to rewrite the pixels I see on the screen.

What am I doing wrong??

thanks
Advertisement
Dont do that. glRead and glDraw are slow.

Are you just fading to red? Draw a red quad and change the alpha. You can always use a texture with varying red/blood instead of just using pure red.

You have to call glRasterPos and glLoadIdentity to DrawPixels

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

OpenGL will also quite happily apply texturing and lighting to glDrawPixels. And aside from their overall slowness (please don't anybody mention how bandwidth is good nowadays, that's not relevant, pipeline stalls will be the biggest issue there and no amount of bandwidth will eliminate a pipeline stall) you're neither reading from nor drawing to the framebuffer in it's native format, meaning that you're forcing OpenGL to go through extra software stages to convert to and from 3-component RGB floats.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

My original intent was to make a class to make some cool post-render effects. After everything is drawn, apply some modifiers to the pixels on the buffer. Like some fade out to black between screen transition... Or maybe some blur effects applied on the render directly when the character is dizzy.

So glRead and glDraw too slow? Better use some quads with alpha to make the special effects? Is this possible any other way?

Thanks
Use a shader.
Like some fade out to black between screen transition..
fade out to black would be
glColor4f(0,0,0,alphaFade);
Where alphaFade = 0 and goes to 1. You just draw a fullscreen quad and its fast.

Motion blur is done with shaders. To do the dizzy effect you copy the screen to texture and use that along with a "distortion" texture. In a shader you wiggle the distortion texture around by manipulating UV coords. You use that texture as offsets from the current pixel.

NBA2K, Madden, Maneater, Killing Floor, Sims http://www.pawlowskipinball.com/pinballeternal

Ok thanks, I`ll start looking into shaders.
A shader requires drawing a fullscreen quad too. Basic theory is that you either render to an FBO, or - if you don't support FBOs - glCopyTexSubImage2D to another texture, then draw over the scene with depth test/depth write disabled and a glOrtho projection. For something as simple as a colour tint or a fade-to-black you don't even need that, you can just draw an untextured quad over the scene (also glDisable (GL_TEXTURE_2D) if doing this) with blending enabled and adjusting your glColor4f over time.

It's fast but it won't be as fast as not doing it at all. If nothing else, the operation requires touching every pixel in your scene twice - once for the regular draw, once for the effect. But it will still be colossally faster than reading back and doing it on the CPU, which is quite possibly the worst thing you could do for this kind of effect.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

This topic is closed to new replies.

Advertisement