0
votes

I'm experiencing some weird graphical corruption with my SDL2 + OpenGL GUI application. Now I apologize if I'm not using the appropriate term to describe the situation. It seems that the front buffer is being invalidated and other applications are being drawn in the buffer?

Important note: this corruption only occurs in Windows XP or when using the Windows Basic theme in Windows 7.

The corruption can be reproduced in a few ways:

  1. by moving the window around. It seems that the front buffer gets corrupted with the image of other applications in front or behind it.
  2. if there's an application behind, it'll occasionally flash into the front buffer.
  3. I can load up a google webpage in Chrome above the opengl application, close the chrome process, and then move the opengl application around and I'll see the google homepage covering the whole inside of the window.
  4. by moving another application over the opengl window.

It seems that I also see the corruption when I'm moving other windows around, even if they don't overlap the opengl window, so long as I've already tried one of the ones posted just above.

inline int UI::RenderingThread()
{
   UI::Window::Instance().RenderingThreadEnter();
   while( UI::Window::Instance().RenderingThreadActive() )
   {
      unsigned int ticks = SDL_GetTicks();
      UI::Window::Instance().RenderingThreadUpdate();
      UI::Window::Instance().RenderingThreadRender();
      ticks = SDL_GetTicks() - ticks;
      if( ticks < 33 )
      {
         SDL_Delay( 33 - ticks );
      }
   }
   UI::Window::Instance().RenderingThreadExit();

   return 0;
}

As you probably guessed, I'm using multithreading and I have my rendering in a separate thread. Within the RenderingThreadRender() function, I only redraw if there's a change in content, or I've requested a redraw.

case SDL_WINDOWEVENT:
   switch( sdl_event.window.event )
   {
      default:
         UI::Window::Instance().Redraw();
         break;
   }

This is done to allow all SDL_WINDOWEVENT events to redraw in hopes that one of them would fix the problem. Unfortunately that has not solved the issue.

I'm hesitant to simply constantly redraw my application at 30 or 60 fps since I've noticed that by doing so, other application would be sluggish when moving them around.

Initialization:

SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); 
this->window = SDL_CreateWindow( this->caption.c_str(), SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                                 UI::WindowSize::Instance().GetWindowWidth(), UI::WindowSize::Instance().GetWindowHeight(),
                                 SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glViewport(0, 0, UI::WindowSize::Instance().GetWindowWidth(), UI::WindowSize::Instance().GetWindowHeight());

// Set the OpenGL view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho( 0, UI::WindowSize::Instance().GetWindowWidth(), UI::WindowSize::Instance().GetWindowHeight(), 0, -1, 1 );
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
glDisable( GL_DITHER );

Rendering:

if( this->redraw )
{
     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glLoadIdentity();

     // a few DrawArrays

     SDL_GL_SwapWindow( this->window ); 
}

Does anyone have any idea what could be causing this issue, and how to fix it?

EDIT: Some more research has pointed me to the following two questions:

https://superuser.com/questions/316738/what-happens-with-the-off-screen-front-buffers-in-windows-7-when-dwm-is-disabled

C++ OpenGL window only tracks background

However, this doesn't solve my problem since I'm already using Double Buffering.

1
There are a couple of window flags I would try to solve this, CS_OWNDC first and foremost. CS_HREDRAW and CS_VREDRAW as well. Unfortunately, SDL hides all of this stuff from you, and I think it actually defaults to CS_OWNDC. I have to suspect that Windows is sending your application WM_PAINT events that for whatever reason SDL is not forwarding to you, and this is why you get the corruption every so often.Andon M. Coleman

1 Answers

0
votes

I've found the solution to my problem. It's unlikely that anyone will experience the same issue that I was having, but you never know. Essentially a C# Window of size equal or larger than my application, was being created before. This window was hidden, however because XP has a global framebuffer instead of a composition, there was a conflict causing the corruption.

All in all, if you're having a similar issue, make sure there isn't another context.