I am attempting to load some largish textures (1024x1024). When I display them they show up as a big white rectangle, and then they magically appear correctly a few seconds later.
I am doing a glFinish() immediately after calling glTexImage2D(…). I’m guessing that the texture just isn’t completely loaded even though I call glFinish(), which is why it shows up correctly a few seconds later.
I saw something about ARB_sync on a google search, but I’m not sure if that will fix my problem.
Can someone point me in the direction of a solution?
Your suspicion is possibly correct, but I’d be more suspicious that some OpenGL state that is not initialized properly to do with textures / pixel format is getting altered at some point in your main loop and that is when the texture appears…
What kind of texture is it? Format etc.? And what GPU are you on?
That is bizarre. It may be an overly aggressive optimization aimed at asynchronous downloads but that would be pretty sophisticated and also non conformant. It wold be a bug. I think this is highly implausible for all sorts of reasons, especially when you consider the potential volatility of memory that the driver manages (I assume your’e not using PBOs).
Are you sure you’re not doing something else that invalidates the texture unit for the fetch. White basically means the texture is invalid and it can be invalid for many reasons.
I have tested it on two different NVIDIA graphics cards (8000 and 9000 series) and it works fine. This could just be coincidence because the GPUs are faster?
The problem shows up when using the Intel graphics chipset on some of my friends’ laptops. I can also reproduce this when running Windows in VMWare Fusion on my machine with an NVIDIA graphics card.
Here is how I’m loading the texture.
[ get bitmap data ]
unsigned char *pixbuf = new unsigned char[mBmp->GetWidth()*mBmp->GetHeight()*4];
[ populate pixbuf with pixel values ]
glGenTextures (1, &mTexid);
glTexImage2D(GL_TEXTURE_2D, 0, 4, mBmp->GetWidth(), mBmp->GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, pixbuf);
I call this loading routine exactly once per image. Each texture is wrapped in an SSPic object. Once the loading routine is complete, the SSPic object is added to a vector of SSPic objects used by the drawing thread. A picture can only be in the vector of SSPic objects if its loading routine has returned success (where glFinish is executed). There is proper synchronization with respect to this vector of pictures so that only one of the drawing thread or picture loading thread can be using it at any one time.
Even if you don’t believe me that the synchronization around the vector works, I am only adding the SSPic object to the vector after the loading routine has completed.
Essentially, if the picture is in the shared vector (meaning that it will be drawn), then glFinish must have returned.
What am I missing? Do you need me to give more information? Thanks for your help.
I forgot to mention that I have two contexts. I will call them c0 and c1.
The main drawing thread initializes the contexts and acquires c0 via
c0 = wglCreateContext(mDC);
c1 = wglCreateContext(mDC);
The main drawing thread then immediately enables sharing between the contexts via
When the image loading thread begins it immediately acquires c1 via
The image loading thread loads textures in a loop. If it ever terminates then the image loading thread releases c1
Could there be some funky delay in sharing between the two contexts that would be causing the textures to show up as white for a few seconds?
Does anyone have any clue as to why the textures would show up white for a few seconds?