/* * based on https://www.cs.rit.edu/~ncs/Courses/570/UserGuide/OpenGLonWin-11.html * * by Greg Couch, UCSF Computer Graphics Lab, 2016 * * compile with: cl stereotest-win.c */ #pragma warning(push, 1) #include #include #pragma warning(pop) /* FULLSCREEN isn't work on GeForce even though stereo visuals are available */ #undef FULLSCREEN #pragma comment (lib, "user32.lib") #pragma comment (lib, "gdi32.lib") #pragma comment (lib, "opengl32.lib") static const char className[] = "OpenGL"; static const char windowName[] = "Stereo Test"; int winX = 0, winY = 0; int winWidth = 200; int winHeight = 200; HDC hDC; HGLRC hGLRC; void redraw(void) { glDrawBuffer(GL_BACK_LEFT); glClearColor(1, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glDrawBuffer(GL_BACK_RIGHT); glClearColor(0, 0, 1, 1); glClear(GL_COLOR_BUFFER_BIT); SwapBuffers(hDC); } void resize(void) { /* set viewport to cover the window */ glViewport(0, 0, winWidth, winHeight); } void setupPixelFormat(void) { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), /* size */ 1, /* version */ PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | /* support double-buffering */ PFD_STEREO, /* want 3D stereo */ PFD_TYPE_RGBA, /* color type */ 24, /* prefered color depth */ 0, 0, 0, 0, 0, 0, /* color bits (ignored) */ 0, /* no alpha buffer */ 0, /* alpha bits (ignored) */ 0, /* no accumulation buffer */ 0, 0, 0, 0, /* accum bits (ignored) */ 0, /* depth buffer */ 0, /* no stencil buffer */ 0, /* no auxiliary buffers */ PFD_MAIN_PLANE, /* main layer */ 0, /* reserved */ 0, 0, 0, /* no layer, visible, damage masks */ }; int pixelFormat; pixelFormat = ChoosePixelFormat(hDC, &pfd); if (pixelFormat == 0) { MessageBox(WindowFromDC(hDC), "ChoosePixelFormat failed.", "Error", MB_ICONERROR | MB_OK); exit(1); } if (SetPixelFormat(hDC, pixelFormat, &pfd) != TRUE) { MessageBox(WindowFromDC(hDC), "SetPixelFormat failed.", "Error", MB_ICONERROR | MB_OK); exit(1); } /* confirm that we get a stereo pixel format */ DescribePixelFormat(hDC, pixelFormat, sizeof (pfd), &pfd); if ((pfd.dwFlags & PFD_STEREO) == 0) { MessageBox(WindowFromDC(hDC), "Unable to get stereo pixel format.", "Error", MB_ICONERROR | MB_OK); exit(1); } } LRESULT APIENTRY WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: /* initialize OpenGL rendering */ hDC = GetDC(hWnd); setupPixelFormat(); hGLRC = wglCreateContext(hDC); wglMakeCurrent(hDC, hGLRC); return 0; case WM_DESTROY: /* finish OpenGL rendering */ if (hGLRC) { wglMakeCurrent(NULL, NULL); wglDeleteContext(hGLRC); } ReleaseDC(hWnd, hDC); PostQuitMessage(0); return 0; case WM_SIZE: /* track window size changes */ if (hGLRC) { winWidth = (int) LOWORD(lParam); winHeight = (int) HIWORD(lParam); resize(); return 0; } case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hWnd, &ps); if (hGLRC) { redraw(); } EndPaint(hWnd, &ps); return 0; } break; case WM_LBUTTONDOWN: case WM_CHAR: DestroyWindow(hWnd); return 0; default: break; } return DefWindowProc(hWnd, message, wParam, lParam); } int APIENTRY WinMain(__in HINSTANCE hCurrentInst, __in_opt HINSTANCE hPreviousInst, __in_opt LPSTR lpszCmdLine, __in_opt int nCmdShow) { WNDCLASS wndClass; HWND hWnd; MSG msg; #ifdef FULLSCREEN HMONITOR hmon; MONITORINFO mi; mi.cbSize = sizeof mi; hmon = MonitorFromWindow(GetDesktopWindow(), MONITOR_DEFAULTTONEAREST); if (hmon && GetMonitorInfo(hmon, &mi)) { winX = mi.rcMonitor.left; winY = mi.rcMonitor.top; winWidth = mi.rcMonitor.right - mi.rcMonitor.left; winHeight = mi.rcMonitor.bottom - mi.rcMonitor.top; } #endif /* register window class */ wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW; wndClass.lpfnWndProc = WndProc; wndClass.cbClsExtra = 0; wndClass.cbWndExtra = 0; wndClass.hInstance = hCurrentInst; wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndClass.hCursor = LoadCursor(NULL, IDC_ARROW); wndClass.hbrBackground = GetStockObject(BLACK_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = className; RegisterClass(&wndClass); /* create window */ hWnd = CreateWindowEx( WS_EX_APPWINDOW | WS_EX_TOPMOST, className, windowName, #ifdef FULLSCREEN WS_POPUP #else WS_OVERLAPPEDWINDOW #endif | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, winX, winY, winWidth, winHeight, NULL, NULL, hCurrentInst, NULL); /* display window */ #ifdef FULLSCREEN ShowWindow(hWnd, SW_MAXIMIZE); #else ShowWindow(hWnd, nCmdShow); #endif UpdateWindow(hWnd); /* process messages */ while (GetMessage(&msg, NULL, 0, 0) == TRUE) { TranslateMessage(&msg); DispatchMessage(&msg); } return (int) msg.wParam; }