PDA

View Full Version : why does the background appear in grey?



12-09-2003, 06:32 AM
Hi!

My program has three independt parts. The third of them has no refresh of the colors, etc, because I need it to draw all (from the begining).

With the two first there is no problem, but in the last, the background appears in grey.. There are no instructions with such color in all the program.. so I don't understand what is happening.

Any idea??

Thank you in advance.

Relic
12-09-2003, 07:41 AM
I don't quite see the relation to OpenGL, but under Windows the WNDCLASS struct defines a HBRUSH hbrBackground which is normally set to (HBRUSH) (COLOR_WINDOW + 1); for the default workspace color.
This is then used by the WM_ERASEBKGND handler in DefWindowProc(), which handles all messages you haven't.
To keep the DefWindowProc() from erasing your background, you need to add an own handler for WM_ERASEBKGND and it just needs to return non-zero. Now your window hasn't even a background.
For MFC it's OnEraseBkgnd() and the like.

[This message has been edited by Relic (edited 12-09-2003).]

12-09-2003, 08:46 AM
I'm programming in C++ with OpenGL and glut library.

I don't know if that colour appears for default or something like that. I'm sure I don't give the instruction for that colour in all the program.

nexusone
12-09-2003, 09:17 AM
Do you enable lighting somewhere in your program?

cwc36
12-09-2003, 05:41 PM
Hi,

Try to do this..

void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
//draw 1 object
glColor3f(...);
glPushMatrix()
drawObject();
glPopMatrix();

//draw 2 object
glColor3f(...);
glPushMatrix()
drawObject();
glPopMatrix();

//draw 3 object
glColor3f(...);
glPushMatrix()
drawObject();
glPopMatrix();

glPopMatrix();
glClearColor(0.0,0.0,0.0,0.0);
glutSwapBuffers();

}

12-10-2003, 02:44 AM
Answering your questions, I don't enable lighting anywhere and if I do

void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
....
}

there is no problem with the background color (it obeys me).

The problem is just that!!! I can't do it because I need to keep all the images, from the begining (I need to draw up the path of some particles in time).

I don't understand why, if I don't clear the color buffer bit, the back ground remains grey whatever I do.

Deiussum
12-10-2003, 05:46 AM
Are you using double buffering? If so, the back buffer won't automatically retain what was previously drawn. Every time you swap buffers, you will most likely have undefined data in your back buffer.

You could try to do something like a glReadPixels to get the previous scene, then start your rendering to the new back buffer by drawing with glDrawPixels.

Or, you just keep a list of all your particles and where to draw them, and draw them all every frame...

[This message has been edited by Deiussum (edited 12-10-2003).]

ZbuffeR
12-10-2003, 08:51 AM
If I understood your description correctly, you have 3 independant parts. In this case, you can clear everything at beginning of part 3, then draw and swap without clearing.
<part2>
glClearColor(0.0,0.0,0.0,1.0); // I prefer opaque alpha

glClear(GL_COLOR_BUFFER_BIT); // clear front buffer
glDrawBuffer(GL_BACK); // select back buffer
glClear(GL_COLOR_BUFFER_BIT);// clear back buffer
glDrawBuffer(GL_FRONT); // go back to normal
<part3>

The two clears are needed because you have a front and back buffer.


If so, the back buffer won't automatically retain what was previously drawn. Every time you swap buffers, you will most likely have undefined data in your back buffer.
I have never seen that myself, but it might happen.


You could try to do something like a glReadPixels to get the previous scene, then start your rendering to the new back buffer by drawing with glDrawPixels.
Forget glReadPixels if you want fast performance. You can use glCopyTexSubImage and a textured quad, it is much, much faster.


Or, you just keep a list of all your particles and where to draw them, and draw them all every frame...
If my clears do not work, try this in priority.


[This message has been edited by ZbuffeR (edited 12-10-2003).]

Deiussum
12-10-2003, 10:46 AM
glClear(GL_COLOR_BUFFER_BIT); // clear front buffer
glDrawBuffer(GL_BACK); // select back buffer
glClear(GL_COLOR_BUFFER_BIT);// clear back buffer
glDrawBuffer(GL_FRONT); // go back to normal


First, in a double buffered window, the default draw buffer is the back buffer. You draw to the back buffer, where you won't see the actual drawing taking place, then swap buffers to display the back buffer, so that you see everything drawn at once.

Second, using a double buffered window, and then relying on clearing both buffers, pretty much removes any benefit you have to a double buffered window, and is really an awkward design.

Third, the spec in no way states that once you swap buffers, they will retain what was previously there, and you should not assume it does. Whether it does or not is a driver implementation detail. Even if you happen to be using a driver that does retain the buffer, you will have information there that is now 2 frames old.

I admit that glReadPixels would be slow and should be avoided, so my second suggestion is what I would probably do. Keep a list of everything to be drawn, adding to that list as you need to, drawing everything, every frame.

12-11-2003, 05:52 AM
Well.. I tried all you said (and some variants) and I didn't manage to make it work :-S.

I can't store all the information about particles each time (I'd need a super-machine).. So I don't know what to do. Now is all ok but the grey background...

I'll give it up, but if you have more ideas in the future... They will be wellcome ;-).

Thank for all.

ZbuffeR
12-11-2003, 06:01 AM
Have you tried everything even glReadPixels /drawpixels ? Even if slow ? Try to glCopyTexSubImage your screen to a texture, map it to a quad, and blend your next scene on top. Try nehe.gamedev.net , lesson 36 I believe. Or pbuffers. Or RenderToTexture extension. You will find many info on gl advanced/beginner forum if you search these keywords.

[This message has been edited by ZbuffeR (edited 12-11-2003).]

12-11-2003, 06:13 AM
I need the program to be as fast as possible, so I didn't try
"glReadPixels /drawpixels"
because of the reasons you gave me.

Copy to a texture?!?! Is my problem so complicated?!.. Well I'll try to find information there. Thank you.

Deiussum
12-11-2003, 10:19 AM
How many particles exactly? Did you even try to store them all as I suggested to see how it performed? You might be surprised.

Overmind
12-11-2003, 12:21 PM
I don't want to be uncreative, but wouldn't simply turning off double buffering solve the problem? I mean, the advantage of double buffering is that you don't see the image flicker between the clear and the drawing, but without clear this problem doesn't exist, so just using single buffering would be the fastest and easiest solution.

ZbuffeR
12-11-2003, 12:25 PM
Very right, Overmind !

12-12-2003, 05:37 AM
Well..
The number of particles is quite large... It depends on the examples I you use.. And I can store them, I know, but I'd rather prefer to avoid it.

I tried using only one buffer, but I give it up.. I realize one important thing:

IN OTHER PC (my lap top), IT WORKS WITHOUT PROBLEMS!!!!!

I don't understand why (?)..

Deiussum
12-12-2003, 10:44 AM
Double buffering also helps prevent animation tearing.

Anyway, another reason why you would want to save your particles is that if you don't, and your scene needs to be redrawn, you'll need to know where to redraw them.

For instance, if another window covers yours, and then it uncovers it, or you minimize and restore your window. If you don't store what you've drawn, you can't expect to be able to redraw it in these cases.