Here’s some simple code I’m trying:
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
#define MULTITHREADED
#include <windows.h>
#include <gl/gl.h>
#include <stdio.h>
#ifdef MULTITHREADED
#include <process.h>
#endif
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
typedef void (APIENTRY *PFNWGLEXTSWAPCONTROLPROC)(int);
static PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL;
static HWND gameWindow;
static HGLRC gameRC;
static int quit;
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
static int ogl_init(void)
{
PIXELFORMATDESCRIPTOR pixeldesc;
int pixelformat;
HDC hDC;
hDC = GetDC(gameWindow);
memset(&pixeldesc, 0, sizeof pixeldesc);
pixeldesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixeldesc.nVersion = 1;
pixeldesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pixeldesc.iPixelType = PFD_TYPE_RGBA;
pixeldesc.cColorBits = 32;
pixeldesc.cRedBits = 0;
pixeldesc.cGreenBits = 0;
pixeldesc.cBlueBits = 0;
pixeldesc.cAlphaBits = pixeldesc.cAlphaShift = 0;
pixeldesc.cAccumBits = 32;
pixeldesc.cAccumRedBits =
pixeldesc.cAccumGreenBits = pixeldesc.cAccumBlueBits = 0;
pixeldesc.cAccumAlphaBits = 0;
pixeldesc.cDepthBits = 32;
pixeldesc.cStencilBits = 0;
pixeldesc.cAuxBuffers = 0;
pixeldesc.bReserved = 0;
pixeldesc.dwLayerMask = 0;
pixeldesc.dwVisibleMask = 0;
pixeldesc.dwDamageMask = 0;
if ((pixelformat = ChoosePixelFormat(hDC, &pixeldesc)) == 0)
return 0;
if (pixeldesc.dwFlags & PFD_NEED_PALETTE)
return 0;
if (SetPixelFormat(hDC, pixelformat, &pixeldesc) == FALSE)
return 0;
DescribePixelFormat(hDC, pixelformat, sizeof pixeldesc, &pixeldesc);
gameRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, gameRC);
ReleaseDC(gameWindow, hDC);
if (strstr((const char *)glGetString(GL_EXTENSIONS), "WGL_EXT_swap_control"))
{
wglSwapIntervalEXT = (PFNWGLEXTSWAPCONTROLPROC)wglGetProcAddress("wglSwapIntervalEXT");
if (wglSwapIntervalEXT)
wglSwapIntervalEXT(1);
}
return 1;
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
static void ogl_shutdown(void)
{
wglMakeCurrent(NULL, NULL);
if (gameRC)
{
wglDeleteContext(gameRC);
gameRC = 0;
}
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
void ogl_flip(void)
{
HDC dc;
GLenum err;
err = glGetError();
if (err != GL_NO_ERROR)
{
char tmp[256];
sprintf(tmp, "GLERROR %08X %d
", err, err);
OutputDebugString(tmp);
}
dc = GetDC(gameWindow);
SwapBuffers(dc);
ReleaseDC(gameWindow, dc);
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
#define BAR_HEIGHT 80
void ogl_draw(void)
{
static int ry,gy,by;
static int ri=1, gi=2, bi=3;
glDepthRange(0.0, 1.0);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glPixelZoom(1.0, -1.0);
glDisable(GL_LIGHTING);
glDisable(GL_TEXTURE_2D);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glClearDepth(1.0);
glClearColor(0,0,0,1.0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, (GLdouble)SCREEN_WIDTH, (GLdouble)SCREEN_HEIGHT, 0.0, 0.0, 1.0);
glViewport(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
glColor3ub(0,0,0);
glBegin(GL_QUAD_STRIP);
glVertex2i(0,ry);
glVertex2i(SCREEN_WIDTH,ry);
glColor3ub(0xff,0,0);
glVertex2i(0,ry+BAR_HEIGHT/2);
glVertex2i(SCREEN_WIDTH,ry+BAR_HEIGHT/2);
glColor3ub(0,0,0);
glVertex2i(0,ry+BAR_HEIGHT);
glVertex2i(SCREEN_WIDTH,ry+BAR_HEIGHT);
glEnd();
glColor3ub(0,0,0);
glBegin(GL_QUAD_STRIP);
glVertex2i(0,gy);
glVertex2i(SCREEN_WIDTH,gy);
glColor3ub(0,0xff,0);
glVertex2i(0,gy+BAR_HEIGHT/2);
glVertex2i(SCREEN_WIDTH,gy+BAR_HEIGHT/2);
glColor3ub(0,0,0);
glVertex2i(0,gy+BAR_HEIGHT);
glVertex2i(SCREEN_WIDTH,gy+BAR_HEIGHT);
glEnd();
glColor3ub(0,0,0);
glBegin(GL_QUAD_STRIP);
glVertex2i(0,by);
glVertex2i(SCREEN_WIDTH,by);
glColor3ub(0,0,0xff);
glVertex2i(0,by+BAR_HEIGHT/2);
glVertex2i(SCREEN_WIDTH,by+BAR_HEIGHT/2);
glColor3ub(0,0,0);
glVertex2i(0,by+BAR_HEIGHT);
glVertex2i(SCREEN_WIDTH,by+BAR_HEIGHT);
glEnd();
ry += ri;
gy += gi;
by += bi;
if (ry < 0) ry = 0, ri=-ri;
else if (ry >= SCREEN_HEIGHT-BAR_HEIGHT) ry = SCREEN_HEIGHT-BAR_HEIGHT-1, ri=-ri;
if (gy < 0) gy = 0, gi=-gi;
else if (gy >= SCREEN_HEIGHT-BAR_HEIGHT) gy = SCREEN_HEIGHT-BAR_HEIGHT-1, gi=-gi;
if (by < 0) by = 0, bi=-bi;
else if (by >= SCREEN_HEIGHT-BAR_HEIGHT) by = SCREEN_HEIGHT-BAR_HEIGHT-1, bi=-bi;
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
#ifdef MULTITHREADED
static unsigned int __stdcall runasthread(void *args)
{
HDC dc;
args;
dc = GetDC(gameWindow);
wglMakeCurrent(dc, gameRC);
ReleaseDC(gameWindow, dc);
while (!quit)
{
ogl_draw();
ogl_flip();
}
_endthreadex(0);
return 0;
}
#endif
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg )
{
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;
case WM_ERASEBKGND:
return 1;
case WM_CLOSE:
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return 0;
}
//-----------------------------------------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------------------------------------
//
//
//
//-----------------------------------------------------------------------------------------------------------------
static char GLSampleClass[32] = "GLSampleClass";
int WINAPI WinMain(HINSTANCE this_inst, HINSTANCE prev_inst, LPSTR cmdline, int cmdshow)
{
WNDCLASS wc;
int style, exstyle;
RECT rect;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = this_inst;
wc.hIcon = LoadIcon(NULL, (LPCSTR)IDI_WINLOGO);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
wc.lpszClassName = GLSampleClass;
RegisterClass(&wc);
style = WS_OVERLAPPED|WS_SYSMENU|WS_CAPTION;
exstyle = WS_EX_APPWINDOW;
gameWindow = CreateWindowEx(
0,
GLSampleClass, // class
"OpenGL Sample",
style,
CW_USEDEFAULT,CW_USEDEFAULT, // init. x,y pos
SCREEN_WIDTH,SCREEN_HEIGHT,
NULL, // parent window
NULL, // menu handle
this_inst, // program handle
NULL // create parms
);
GetWindowRect(gameWindow, &rect);
AdjustWindowRectEx(&rect, style, FALSE, exstyle);
SetWindowPos(gameWindow, NULL, 0,0, rect.right-rect.left, rect.bottom-rect.top, SWP_NOMOVE);
ShowWindow(gameWindow, cmdshow);
UpdateWindow(gameWindow);
if (ogl_init() == 0)
{
MessageBox(gameWindow, "Failed Initialising OpenGL", "Failed", MB_OK);
return 0;
}
#ifdef MULTITHREADED
wglMakeCurrent(NULL, NULL);
_beginthreadex(NULL, 0, runasthread, NULL, 0, NULL);
#endif
quit = 0;
do
{
MSG msg;
while (PeekMessage(&msg,NULL,0,0, PM_NOREMOVE))
{
if (GetMessage(&msg,NULL,0,0)>0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
quit = 1;
break;
}
}
#ifndef MULTITHREADED
ogl_draw();
ogl_flip();
#else
Sleep(50);
#endif
} while (!quit);
ogl_shutdown();
return 0;
}
It should work with or without MULTITHREADED defined.
Symptoms are:
MULTITHREADED NOT defined.
All OK
MULTITHREADED defined.
sometimes the display runs correctly.
sometimes the display is not updated.
sometimes the display is not updated but dragging the window round forces an update.
sometimes there is a delay before anything is displayed.
The problem seems only to exist on Windows Vista 32bit. Windows XP SP2 works fine.
This is on an nVidia 8600GT, latest drivers, Core2 Duo.
Has anyone got any ideas?
Jim