PDA

View Full Version : TrackPopupMenu breaks full screen OpenGL window?



Radek
09-05-2011, 02:23 PM
I have a full-screen OpenGL application which uses standard Win32 TrackPopupMenu function. The first call to this function works fine but after that things go awry: usually the popup menu stops showing up (the code still executes). But on some hardware (notably MacBook running Windows 7) there is some odd flickering when redrawing the window.

I think this is a new problem on Windows 7 (haven't tried on Windows Vista) because it definitely was working on Windows XP.

Has anyone seen this? I am attaching a simple program that reproduces this behavior. Notice that if you change the width or height of the window by one pixel the problem goes away.

Any help or advice will be appreciated.

------------------------
#include <windows.h>
#include <windowsx.h>
#include <GL\gl.h>

HMENU hPopupMenu;

void CreateGL(HWND);
void Redraw();

HDC hdc;
HGLRC hrc;
int width;
int height;

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
CreateGL(hWnd);
return 0;
case WM_PAINT:
ValidateRect(hWnd, NULL);
Redraw();
return 0;
case WM_CONTEXTMENU:
TrackPopupMenu(hPopupMenu, 0, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam), 0, hWnd, NULL);
Redraw();
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
WNDCLASS wc;
memset(&amp;wc, 0, sizeof(wc));
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = "OpenGLTest";
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
RegisterClass(&amp;wc);

hPopupMenu = CreatePopupMenu();
AppendMenu(hPopupMenu, 0, 101, "Item 1");
AppendMenu(hPopupMenu, 0, 102, "Item 2");

width = GetSystemMetrics(SM_CXSCREEN);
// Uncommenting following line will fix the problem
//--width;
height = GetSystemMetrics(SM_CYSCREEN);

HWND hWnd = CreateWindow("OpenGLTest", "Test",
WS_POPUP, 0, 0, width, height,
NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);

MSG msg;
while(GetMessage(&amp;msg, 0, NULL, NULL))
{
TranslateMessage(&amp;msg);
DispatchMessage(&amp;msg);
}
return 0;
}


void CreateGL(HWND hWnd)
{
PIXELFORMATDESCRIPTOR pfd;
memset(&amp;pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cAlphaBits = 16;
pfd.cDepthBits = 16;
pfd.iLayerType = 0;

hdc = GetDC(hWnd);
int nPF = ChoosePixelFormat(hdc, &amp;pfd);
SetPixelFormat(hdc, nPF, &amp;pfd);
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
}


void Redraw()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, width, height);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

glClear(GL_COLOR_BUFFER_BIT);

glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_LINES);

glVertex2f(-0.9f, -0.9f);
glVertex2f(0.9f, 0.9f);

glEnd();

glFlush();
SwapBuffers(hdc);
}

BionicBytes
09-05-2011, 03:03 PM
I can't say what the problem is but perhaps it has something to do with the context.
Have you tried disabling Areo interface?
Also I notice you have set pfd.cAlphaBits=16. Are you sure about this as I'd expectvthis to be 0 (could be wrong as I'm not looking at my source right now).

Radek
09-05-2011, 09:31 PM
Thanks BionicBytes for your response.

Yes, I have tried disabling Areo but it doesn't make any difference. Also setting cAlphaBits to 0 doesn't help (I have always thought that this value is necessary for alpha blending but apparently it is not required).

The only explanation I can think of is that Windows controls (in this case Popup menu) somehow mess up the frame buffer. Also, the problem shows up only in double buffer mode. Single buffer is OK.

BionicBytes
09-06-2011, 09:27 AM
Just guess work really: Is Vsync on or off; try messing with glFinish before swapbuffers.
What happens if you render to framebuffer and then blit that to main window?