First frame white in OpenGL

I have an OpenGL backend for my DOOM source port. Something that’s driving me nuts and that I cannot find a solution for anywhere is that the first frame of graphics displayed on the screen are solid white, always, no matter what I do.

I have made sure all my own software buffers are calloc()'d to 0, I have tried setting SDL_GL color attributes before setting the video mode, I have tried disabling vsync and double buffering, I tried clearing the screen forcefully to black. Nothing makes a difference.

Notably, if I comment out all my drawing code and never call SDL_GL_SwapBuffers(), the screen stays solid white.

Any ideas would be appreciated. There either has to be something I have forgotten/am doing wrong, or else this is a bug in SDL 1.2.14’s buffer swapping for OpenGL.

The code in question is at http://mancubus.net/svn/hosted/eternity/branches/edf3-branch/source/sdl/i_sdlgl2d.cpp

James Haley

The code in question is at
http://mancubus.net/svn/hosted/eternity/branches/edf3-branch/source/sdl/i_sdlgl2d.cpp

So this doesn’t work?

if(!(surface = SDL_SetVideoMode(v_w, v_h, colordepth, flags)))
{
I_FatalError(I_ERR_KILL, “Couldn’t set OpenGL video mode %dx%dx%d\n”,
v_w, v_h, colordepth);
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers();

You can’t stop the window from coming up with something in it, which
is usually white on most platforms, but you can flash it to black faster
than the human eye can perceive. :slight_smile:

One unrelated note: SDL_GL_BUFFER_SIZE doesn’t do what you think. You
probably wanted:

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

(or whatever.)

We should probably remove the GLX_BUFFER_SIZE set in the x11
driver…all the other drivers ignore SDL_GL_BUFFER_SIZE except in
GetAttribute, and the glX docs say this attribute is ignored if you set
GLX_RGBA (which we do).

–ryan.

GLX_BUFFER_SIZE is for color index visuals in glXChooseVisual() – which
I’m pretty sure SDL would not want to support.On Wed, Jan 18, 2012 at 2:31 AM, Ryan C. Gordon wrote:

The code in question is at

http://mancubus.net/svn/hosted/eternity/branches/edf3-
branch/source/sdl/i_sdlgl2d.**cpphttp://mancubus.net/svn/hosted/eternity/branches/edf3-branch/source/sdl/i_sdlgl2d.cpp

So this doesn’t work?

if(!(surface = SDL_SetVideoMode(v_w, v_h, colordepth, flags)))
{
I_FatalError(I_ERR_KILL, “Couldn’t set OpenGL video mode %dx%dx%d\n”,
v_w, v_h, colordepth);
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers();

You can’t stop the window from coming up with something in it, which is
usually white on most platforms, but you can flash it to black faster than
the human eye can perceive. :slight_smile:

One unrelated note: SDL_GL_BUFFER_SIZE doesn’t do what you think. You
probably wanted:

SDL_GL_SetAttribute(SDL_GL_**RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_**BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_**GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_**ALPHA_SIZE, 8);

(or whatever.)

We should probably remove the GLX_BUFFER_SIZE set in the x11 driver…all
the other drivers ignore SDL_GL_BUFFER_SIZE except in GetAttribute, and the
glX docs say this attribute is ignored if you set GLX_RGBA (which we do).

–ryan.

_____________**
SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/**listinfo.cgi/sdl-libsdl.orghttp://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I tested these changes and they don’t seem to have an effect. I suppose it’s something that we can live with if it’s an unavoidable behavior. After all Quake II, a commercial game, gave a nice ugly off-shade gray screen for quite a while when starting up on slower machines :wink: Pure white’s a step better than that, even though I’d still prefer black.

-James Haley> Date: Wed, 18 Jan 2012 03:31:37 -0500

From: icculus at icculus.org
To: sdl at lists.libsdl.org
Subject: Re: [SDL] First frame white in OpenGL

The code in question is at
http://mancubus.net/svn/hosted/eternity/branches/edf3-branch/source/sdl/i_sdlgl2d.cpp

So this doesn’t work?

if(!(surface = SDL_SetVideoMode(v_w, v_h, colordepth, flags)))
{
I_FatalError(I_ERR_KILL, “Couldn’t set OpenGL video mode %dx%dx%d\n”,
v_w, v_h, colordepth);
}
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
SDL_GL_SwapBuffers();

You can’t stop the window from coming up with something in it, which
is usually white on most platforms, but you can flash it to black faster
than the human eye can perceive. :slight_smile:

One unrelated note: SDL_GL_BUFFER_SIZE doesn’t do what you think. You
probably wanted:

SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);

(or whatever.)

We should probably remove the GLX_BUFFER_SIZE set in the x11
driver…all the other drivers ignore SDL_GL_BUFFER_SIZE except in
GetAttribute, and the glX docs say this attribute is ignored if you set
GLX_RGBA (which we do).

–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

James –

I had the same issue when I used GL_TEXTURE_2D instead of GL_TEXTURE_RECTANGLE_EXT to draw the textures.

I “solved” the problem by calling:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

just before glBindTexture() and glTexImage2D() when creating the textures, and also again calling the same functions just before drawing each texture.

No idea if this “fix” will work for you, but I’m curious if it does. Definitely let me know.

Also, I haven’t looked at your code. Just sharing what worked for me. I still don’t understand why this fixes the issue, but I was having the exact same issue as you (textures drew as white the very first time they were drawn).

Also, I use SDL 1.3.

Asked about this on the OpenGL forums, but no response. But, the problem is explained pretty clearly in my first post:

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=308630#Post308630

Vern,

The problem is almost definitely mipmap related or glEnable(GL_TEXTURE_2D).
Try to come up with the absolute simplest example. Nearest I can figure is
this one:

This code should produce a white square:

void init() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texObj);
glTexImage(0, …)

}

void loop() {

glBindTexture(GL_TEXTURE_2D, texObj);
drawRect();

}

Changing init() to:

void init() {
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texObj);
glTexImage(0, …)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

should fix it. Here’s the reasoning:

Texture filter information is bound to the texture object. This is unlike
Direct3D where it is bound to the texture unit. GL 3.3 has so-called
"sampler state" objects that resemble DX better and simplify code (e.g. a
user changing texture filtering from bilinear to trilinear would require
glBindTexture()/glTexParameteri() for each and every texture used in the
world with the new state)

If a texture does NOT have mipmaps, then using GL_MIPMAP will produce
white textures. This is because you have to call glTexImage2D() for each
mipmap level first. Most likely, you’re leaving the texture bound and
messing with the properties of it unintentionally. This is an easy error to
make, but to figure that out, you can try binding the zero texture object
after each group:

glBindTexture(GL_TEXTURE_2D, texObj);
glTexImage(0, ....)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);

Finally, if you are enabling/disabling 2D textures, you should consider how
many cases you really use untextured, and maybe just do
glEnable(GL_TEXTURE_2D) at the start of hte program and never mess with it
again. Let me know if that fixes your issue, or email me a link/project
that I can debug/compile.On Wed, Jan 18, 2012 at 4:48 PM, VernJensen wrote:

**
Asked about this on the OpenGL forums, but no response. But, the problem
is explained pretty clearly in my first post:

http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=308630#Post308630


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Any ideas would be appreciated. There either has to be something I have
forgotten/am doing wrong, or else this is a bug in SDL 1.2.14’s buffer
swapping for OpenGL.

I misread this as “the framebuffer is all white” … if you meant that
all your textures are pure white, that’s usually either you forgot to
glEnable(GL_TEXTURE_2D), or you have an incomplete set of mipmaps (and
probably the first one, if it fixes itself after the first frame).

–ryan.

Ryan,

My program doesn’t use mipmapping.

As for glEnable(GL_TEXTURE_2D), I tried adding that just before creating my texture. But if I take out the calls to set the min and mag filter, it goes back to drawing a white texture the first time.

Patrick – adding:

glBindTexture(GL_TEXTURE_2D, 0);

after creating the texture didn’t help. ONLY setting the min/mg filter helps.

I don’t really want to upload a project for you right now that demonstrates the problem, given that I did find a “solution” that works for me, and I’m in the middle of some other projects at the moment, but I do really appreciate the offer.

Ryan C. Gordon wrote:>

I misread this as “the framebuffer is all white” … if you meant that
all your textures are pure white, that’s usually either you forgot to
glEnable(GL_TEXTURE_2D), or you have an incomplete set of mipmaps (and
probably the first one, if it fixes itself after the first frame).
–ryan.

**
Ryan,

My program doesn’t use mipmapping.

Yes, that’s the problem. By default, OpenGL DOES enable mipmapping unless
you specifically tell it to use GL_LINEAR or GL_NEAREST in
glTexParameteri(), which is why it will be white until you set it to that
otherwise. I apologize if my earlier example wasn’t explicit on that point.

As for glEnable(GL_TEXTURE_2D), I tried adding that just before creating
my texture. But if I take out the calls to set the min and mag filter, it
goes back to drawing a white texture the first time.

Patrick – adding:

glBindTexture(GL_TEXTURE_2D, 0);

after creating the texture didn’t help. ONLY setting the min/mg filter
helps.

Yes, setting those are required. My guess was that you might be doing
glTexParameteri(…, GL_MIPMAP) before binding the proper texture.
Setting it to 0 first would catch that class of error.On Thu, Jan 19, 2012 at 1:17 PM, VernJensen wrote:

I don’t really want to upload a project for you right now that
demonstrates the problem, given that I did find a “solution” that works for
me, and I’m in the middle of some other projects at the moment, but I do
really appreciate the offer.

Ryan C. Gordon wrote:

I misread this as “the framebuffer is all white” … if you meant that
all your textures are pure white, that’s usually either you forgot to
glEnable(GL_TEXTURE_2D), or you have an incomplete set of mipmaps (and
probably the first one, if it fixes itself after the first frame).
–ryan.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Technically OpenGL expects (by default) you to upload all the mipmaps, like calling gluBuild2DMipmaps on every texture (even 2D UI art) or your own mipmapping routine (my choice, much faster than the
glu32.dll on Windows at least), but of course one does not even desire mipmapping on these textures (or the wasted 33% extra memory involved) so it is far more elegant to just change the
glTexParameter settings.On 01/19/2012 11:25 AM, Patrick Baggett wrote:

On Thu, Jan 19, 2012 at 1:17 PM, VernJensen <vern at actionsoft.com <mailto:vern at actionsoft.com>> wrote:

__
Ryan,

My program doesn't use mipmapping.

Yes, that’s the problem. By default, OpenGL DOES enable mipmapping unless you specifically tell it to use GL_LINEAR or GL_NEAREST in glTexParameteri(), which is why it will be white until you set it
to that otherwise. I apologize if my earlier example wasn’t explicit on that point.

As for glEnable(GL_TEXTURE_2D), I tried adding that just before creating my texture. But if I take out the calls to set the min and mag filter, it goes back to drawing a white texture the first time.

Patrick -- adding:

glBindTexture(GL_TEXTURE_2D, 0);

after creating the texture didn't help. ONLY setting the min/mg filter helps.

Yes, setting those are required. My guess was that you might be doing glTexParameteri(…, GL_MIPMAP) before binding the proper texture. Setting it to 0 first would catch that class of error.

I don't really want to upload a project for you right now that demonstrates the problem, given that I did find a "solution" that works for me, and I'm in the middle of some other projects at the
moment, but I do really appreciate the offer.




Ryan C. Gordon wrote:	


I misread this as "the framebuffer is all white" ... if you meant that
all your textures are pure white, that's usually either you forgot to
glEnable(GL_TEXTURE_2D), or you have an incomplete set of mipmaps (and
probably the first one, if it fixes itself after the first frame).
--ryan.
	


_______________________________________________
SDL mailing list
SDL at lists.libsdl.org <mailto:SDL at lists.libsdl.org>
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


LordHavoc
Author of DarkPlaces Quake1 engine - http://icculus.org/twilight/darkplaces
Co-designer of Nexuiz - http://alientrap.org/nexuiz
"War does not prove who is right, it proves who is left." - Unknown
"Any sufficiently advanced technology is indistinguishable from a rigged demo." - James Klass
"A game is a series of interesting choices." - Sid Meier

Okay, that all makes perfect sense. Thanks for clearing it up for me. :slight_smile: