Revert "wglgears: show stereo-option in usage"
[mesa-demos.git] / src / wgl / wglgears.c
blob853912732b5158627e77ec0d95216468382c9950
1 /*
2 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
24 * Port by Brian Paul 23 March 2001
26 * Command line options:
27 * -info print GL implementation information
29 * Modified from X11/GLX to Win32/WGL by Ben Skeggs
30 * 25th October 2004
33 #include <assert.h>
34 #include <windows.h>
35 #include <GL/gl.h>
36 #include <GL/wglext.h>
37 #include <math.h>
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <ctype.h>
42 #include <math.h>
44 #ifndef M_PI
45 #define M_PI 3.14159265
46 #endif /* !M_PI */
48 #ifndef WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB
49 #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
50 #endif
52 #ifndef GL_FRAMEBUFFER_SRGB
53 #define GL_FRAMEBUFFER_SRGB 0x8db9
54 #endif
57 /* Global vars */
58 static HDC hDC;
59 static HGLRC hRC;
60 static HWND hWnd;
61 static HINSTANCE hInst;
62 static RECT winrect;
64 static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
65 static GLint gear1, gear2, gear3;
66 static GLfloat angle = 0.0;
68 static GLboolean fullscreen = GL_FALSE;
69 static GLint samples = 0;
70 static GLboolean use_srgb = GL_FALSE;
71 static GLboolean animate = GL_TRUE;
74 static void
75 usage(void)
77 printf("Usage:\n");
78 printf(" -srgb run in sRGB mode\n");
79 printf(" -samples N run in multisample mode with at least N samples\n");
80 printf(" -fullscreen run in fullscreen mode\n");
81 printf(" -info display OpenGL renderer info\n");
82 printf(" -geometry WxH+X+Y window geometry\n");
86 /* return current time (in seconds) */
87 static double
88 current_time(void)
90 return timeGetTime() / 1000.0;
96 * Draw a gear wheel. You'll probably want to call this function when
97 * building a display list since we do a lot of trig here.
99 * Input: inner_radius - radius of hole at center
100 * outer_radius - radius at center of teeth
101 * width - width of gear
102 * teeth - number of teeth
103 * tooth_depth - depth of tooth
105 static void
106 gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
107 GLint teeth, GLfloat tooth_depth)
109 GLint i;
110 GLfloat r0, r1, r2;
111 GLfloat angle, da;
112 GLfloat u, v, len;
114 r0 = inner_radius;
115 r1 = outer_radius - tooth_depth / 2.0;
116 r2 = outer_radius + tooth_depth / 2.0;
118 da = 2.0 * M_PI / teeth / 4.0;
120 glShadeModel(GL_FLAT);
122 glNormal3f(0.0, 0.0, 1.0);
124 /* draw front face */
125 glBegin(GL_QUAD_STRIP);
126 for (i = 0; i <= teeth; i++) {
127 angle = i * 2.0 * M_PI / teeth;
128 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
129 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
130 if (i < teeth) {
131 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
132 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
133 width * 0.5);
136 glEnd();
138 /* draw front sides of teeth */
139 glBegin(GL_QUADS);
140 da = 2.0 * M_PI / teeth / 4.0;
141 for (i = 0; i < teeth; i++) {
142 angle = i * 2.0 * M_PI / teeth;
144 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
145 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
146 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
147 width * 0.5);
148 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
149 width * 0.5);
151 glEnd();
153 glNormal3f(0.0, 0.0, -1.0);
155 /* draw back face */
156 glBegin(GL_QUAD_STRIP);
157 for (i = 0; i <= teeth; i++) {
158 angle = i * 2.0 * M_PI / teeth;
159 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
160 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
161 if (i < teeth) {
162 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
163 -width * 0.5);
164 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
167 glEnd();
169 /* draw back sides of teeth */
170 glBegin(GL_QUADS);
171 da = 2.0 * M_PI / teeth / 4.0;
172 for (i = 0; i < teeth; i++) {
173 angle = i * 2.0 * M_PI / teeth;
175 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
176 -width * 0.5);
177 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
178 -width * 0.5);
179 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
180 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
182 glEnd();
184 /* draw outward faces of teeth */
185 glBegin(GL_QUAD_STRIP);
186 for (i = 0; i < teeth; i++) {
187 angle = i * 2.0 * M_PI / teeth;
189 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
190 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
191 u = r2 * cos(angle + da) - r1 * cos(angle);
192 v = r2 * sin(angle + da) - r1 * sin(angle);
193 len = sqrt(u * u + v * v);
194 u /= len;
195 v /= len;
196 glNormal3f(v, -u, 0.0);
197 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
198 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
199 glNormal3f(cos(angle), sin(angle), 0.0);
200 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
201 width * 0.5);
202 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
203 -width * 0.5);
204 u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
205 v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
206 glNormal3f(v, -u, 0.0);
207 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
208 width * 0.5);
209 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
210 -width * 0.5);
211 glNormal3f(cos(angle), sin(angle), 0.0);
214 glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
215 glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
217 glEnd();
219 glShadeModel(GL_SMOOTH);
221 /* draw inside radius cylinder */
222 glBegin(GL_QUAD_STRIP);
223 for (i = 0; i <= teeth; i++) {
224 angle = i * 2.0 * M_PI / teeth;
225 glNormal3f(-cos(angle), -sin(angle), 0.0);
226 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
227 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
229 glEnd();
233 static void
234 draw(void)
236 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
238 glPushMatrix();
239 glRotatef(view_rotx, 1.0, 0.0, 0.0);
240 glRotatef(view_roty, 0.0, 1.0, 0.0);
241 glRotatef(view_rotz, 0.0, 0.0, 1.0);
243 glPushMatrix();
244 glTranslatef(-3.0, -2.0, 0.0);
245 glRotatef(angle, 0.0, 0.0, 1.0);
246 glCallList(gear1);
247 glPopMatrix();
249 glPushMatrix();
250 glTranslatef(3.1, -2.0, 0.0);
251 glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
252 glCallList(gear2);
253 glPopMatrix();
255 glPushMatrix();
256 glTranslatef(-3.1, 4.2, 0.0);
257 glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
258 glCallList(gear3);
259 glPopMatrix();
261 glPopMatrix();
265 /* new window size or exposure */
266 static void
267 reshape(int width, int height)
269 GLfloat h = (GLfloat) height / (GLfloat) width;
271 glViewport(0, 0, (GLint) width, (GLint) height);
272 glMatrixMode(GL_PROJECTION);
273 glLoadIdentity();
274 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
275 glMatrixMode(GL_MODELVIEW);
276 glLoadIdentity();
277 glTranslatef(0.0, 0.0, -40.0);
281 static GLfloat
282 srgb_to_linear(GLfloat c)
284 if (c <= 0.04045f)
285 return c / 12.92f;
286 return powf((c + 0.055f) / 1.055f, 2.4f);
289 static void
290 init(void)
292 static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
293 static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
294 static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
295 static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
297 glLightfv(GL_LIGHT0, GL_POSITION, pos);
298 glEnable(GL_CULL_FACE);
299 glEnable(GL_LIGHTING);
300 glEnable(GL_LIGHT0);
301 glEnable(GL_DEPTH_TEST);
302 if (use_srgb) {
303 for (int i = 0; i < 3; ++i) {
304 red[i] = srgb_to_linear(red[i]);
305 green[i] = srgb_to_linear(green[i]);
306 blue[i] = srgb_to_linear(blue[i]);
308 glEnable(GL_FRAMEBUFFER_SRGB);
311 /* make the gears */
312 gear1 = glGenLists(1);
313 glNewList(gear1, GL_COMPILE);
314 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
315 gear(1.0, 4.0, 1.0, 20, 0.7);
316 glEndList();
318 gear2 = glGenLists(1);
319 glNewList(gear2, GL_COMPILE);
320 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
321 gear(0.5, 2.0, 2.0, 10, 0.7);
322 glEndList();
324 gear3 = glGenLists(1);
325 glNewList(gear3, GL_COMPILE);
326 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
327 gear(1.3, 2.0, 0.5, 10, 0.7);
328 glEndList();
330 glEnable(GL_NORMALIZE);
334 static LRESULT CALLBACK
335 WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
337 switch (uMsg) {
338 case WM_CLOSE:
339 PostQuitMessage(0);
340 return 0;
341 case WM_SIZE:
342 reshape(LOWORD(lParam), HIWORD(lParam));
343 return 0;
344 case WM_KEYDOWN:
345 if (wParam == VK_LEFT)
346 view_roty += 5.0;
347 else if (wParam == VK_RIGHT)
348 view_roty -= 5.0;
349 else if (wParam == VK_UP)
350 view_rotx += 5.0;
351 else if (wParam == VK_DOWN)
352 view_rotx -= 5.0;
353 else if (wParam == VK_ESCAPE)
354 PostQuitMessage(0);
355 else if (wParam == 'A')
356 animate = !animate;
357 return 0;
358 #if WINVER >= 0x0605
359 case WM_NCCREATE:
360 EnableNonClientDpiScaling(hWnd);
361 break;
362 #endif
365 return DefWindowProc(hWnd, uMsg, wParam, lParam);
370 * Create an RGB, double-buffered window.
371 * Return the window and context handles.
373 static void
374 make_window(const char *name, int x, int y, int width, int height)
376 int pixelFormat;
377 WNDCLASS wc;
378 DWORD dwExStyle, dwStyle;
379 static const PIXELFORMATDESCRIPTOR pfd = {
380 sizeof(PIXELFORMATDESCRIPTOR),
382 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
383 PFD_TYPE_RGBA,
385 0, 0, 0, 0, 0, 0,
389 0, 0, 0, 0,
393 PFD_MAIN_PLANE,
395 0, 0, 0
398 winrect.left = (long)0;
399 winrect.right = (long)width;
400 winrect.top = (long) 0;
401 winrect.bottom = (long)height;
403 hInst = GetModuleHandle(NULL);
404 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
405 wc.lpfnWndProc = (WNDPROC)WndProc;
406 wc.cbClsExtra = 0;
407 wc.cbWndExtra = 0;
408 wc.hInstance = hInst;
409 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
410 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
411 wc.hbrBackground = NULL;
412 wc.lpszMenuName = NULL;
413 wc.lpszClassName = name;
414 RegisterClass(&wc);
416 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
417 if (!fullscreen) {
418 dwStyle = WS_OVERLAPPEDWINDOW;
419 AdjustWindowRectEx(&winrect, dwStyle, FALSE, dwExStyle);
421 else {
422 dwStyle = WS_POPUP;
425 hWnd = CreateWindowEx(dwExStyle, name, name,
426 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
427 x, y,
428 winrect.right - winrect.left,
429 winrect.bottom - winrect.top,
430 NULL, NULL, hInst, NULL);
432 if (fullscreen) {
433 DEVMODE devmode;
434 memset(&devmode, 0, sizeof(DEVMODE));
435 devmode.dmSize = sizeof(DEVMODE);
436 devmode.dmPelsWidth = width;
437 devmode.dmPelsHeight = height;
438 devmode.dmBitsPerPel = 24;
439 devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
440 ChangeDisplaySettings(&devmode, CDS_FULLSCREEN);
443 hDC = GetDC(hWnd);
444 pixelFormat = ChoosePixelFormat(hDC, &pfd);
445 if (!pixelFormat)
446 goto nopixelformat;
448 SetPixelFormat(hDC, pixelFormat, &pfd);
449 hRC = wglCreateContext(hDC);
450 wglMakeCurrent(hDC, hRC);
452 if (use_srgb || samples > 0) {
453 /* We can't query/use extension functions until after we've
454 * created and bound a rendering context (done above).
456 * We can only set the pixel format of the window once, so we need to
457 * create a new device context in order to use the pixel format returned
458 * from wglChoosePixelFormatARB, and then create a new window.
460 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB_func =
461 (PFNWGLCHOOSEPIXELFORMATARBPROC)
462 wglGetProcAddress("wglChoosePixelFormatARB");
463 assert(wglChoosePixelFormatARB_func);
465 int int_attribs[64] = {
466 WGL_SUPPORT_OPENGL_ARB, TRUE,
467 WGL_DRAW_TO_WINDOW_ARB, TRUE,
468 WGL_COLOR_BITS_ARB, 24, // at least 24-bits of RGB
469 WGL_DEPTH_BITS_ARB, 24,
470 WGL_DOUBLE_BUFFER_ARB, TRUE,
471 WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, TRUE,
473 int i = 10;
475 if (use_srgb) {
476 int_attribs[i++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
477 int_attribs[i++] = TRUE;
479 if (samples > 0) {
480 int_attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
481 int_attribs[i++] = 1;
482 int_attribs[i++] = WGL_SAMPLES_ARB;
483 int_attribs[i++] = samples;
486 int_attribs[i++] = 0;
488 static const float float_attribs[] = { 0 };
489 UINT numFormats;
491 pixelFormat = 0;
492 if (!wglChoosePixelFormatARB_func(hDC, int_attribs, float_attribs, 1,
493 &pixelFormat, &numFormats) ||
494 !numFormats)
495 goto nopixelformat;
497 PIXELFORMATDESCRIPTOR newPfd;
498 DescribePixelFormat(hDC, pixelFormat, sizeof(pfd), &newPfd);
500 /* now, create new context with new pixel format */
501 wglMakeCurrent(hDC, NULL);
502 wglDeleteContext(hRC);
503 DeleteDC(hDC);
505 DestroyWindow(hWnd);
506 hWnd = CreateWindowEx(dwExStyle, name, name,
507 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
508 x, y,
509 winrect.right - winrect.left,
510 winrect.bottom - winrect.top,
511 NULL, NULL, hInst, NULL);
513 hDC = GetDC(hWnd);
514 SetPixelFormat(hDC, pixelFormat, &pfd);
515 hRC = wglCreateContext(hDC);
516 wglMakeCurrent(hDC, hRC);
519 ShowWindow(hWnd, SW_SHOW);
520 SetForegroundWindow(hWnd);
521 SetFocus(hWnd);
522 return;
524 nopixelformat:
525 printf("Error: couldn't get an RGB, Double-buffered");
526 if (samples > 0)
527 printf(", Multisample");
528 if (use_srgb)
529 printf(", sRGB");
530 printf(" pixelformat\n");
531 exit(1);
534 static void
535 draw_frame()
537 static int frames = 0;
538 static double tRot0 = -1.0, tRate0 = -1.0;
539 double dt, t = current_time();
541 if (tRot0 < 0.0)
542 tRot0 = t;
543 dt = t - tRot0;
544 tRot0 = t;
546 if (animate) {
547 /* advance rotation for next frame */
548 angle += 70.0 * dt; /* 70 degrees per second */
549 if (angle > 3600.0)
550 angle -= 3600.0;
553 draw();
554 SwapBuffers(hDC);
556 frames++;
558 if (tRate0 < 0.0)
559 tRate0 = t;
560 if (t - tRate0 >= 5.0) {
561 GLfloat seconds = t - tRate0;
562 GLfloat fps = frames / seconds;
563 printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
564 fps);
565 fflush(stdout);
566 tRate0 = t;
567 frames = 0;
572 * Determine whether or not a WGL extension is supported.
574 static int
575 is_wgl_extension_supported(HDC hdc, const char *query)
577 static const char *wgl_extensions = NULL;
578 const size_t len = strlen(query);
579 const char *ptr;
581 if (wgl_extensions == NULL) {
582 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_func =
583 (PFNWGLGETEXTENSIONSSTRINGARBPROC)
584 wglGetProcAddress("wglGetExtensionsStringARB");
585 if (!wglGetExtensionsStringARB_func)
586 return 0;
588 wgl_extensions = wglGetExtensionsStringARB_func(hdc);
591 ptr = strstr(wgl_extensions, query);
592 return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0')));
597 * Attempt to determine whether or not the display is synched to vblank.
599 static void
600 query_vsync()
602 int interval = 0;
603 if (is_wgl_extension_supported(hDC, "WGL_EXT_swap_control")) {
604 PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT_func =
605 (PFNWGLGETSWAPINTERVALEXTPROC)
606 wglGetProcAddress("wglGetSwapIntervalEXT");
607 interval = wglGetSwapIntervalEXT_func();
610 if (interval > 0) {
611 printf("Running synchronized to the vertical refresh. The framerate should be\n");
612 if (interval == 1) {
613 printf("approximately the same as the monitor refresh rate.\n");
615 else if (interval > 1) {
616 printf("approximately 1/%d the monitor refresh rate.\n",
617 interval);
623 static void
624 event_loop(void)
626 MSG msg;
628 TIMECAPS tc;
629 timeGetDevCaps(&tc, sizeof(tc));
630 timeBeginPeriod(tc.wPeriodMin);
632 while(1) {
633 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
634 if (msg.message == WM_QUIT) break;;
635 TranslateMessage(&msg);
636 DispatchMessage(&msg);
639 draw_frame();
642 timeEndPeriod(tc.wPeriodMin);
646 static void
647 parse_geometry(const char *str, int *x, int *y, unsigned int *w, unsigned int *h)
649 char *end;
650 if (*str == '=')
651 str++;
653 long tw = LONG_MAX;
654 if (isdigit(*str)) {
655 tw = strtol(str, &end, 10);
656 if (str == end)
657 return;
658 str = end;
661 long th = LONG_MAX;
662 if (tolower(*str) == 'x') {
663 str++;
664 th = strtol(str, &end, 10);
665 if (str== end)
666 return;
667 str = end;
670 long tx = LONG_MAX;
671 if (*str == '+' || *str == '-') {
672 tx = strtol(str, &end, 10);
673 if (str == end)
674 return;
675 str = end;
678 long ty = LONG_MAX;
679 if (*str == '+' || *str == '-') {
680 ty = strtol(str, &end, 10);
681 if (str == end)
682 return;
683 str = end;
686 if (tw < LONG_MAX)
687 *w = tw;
688 if (th < LONG_MAX)
689 *h = th;
690 if (tx < INT_MAX)
691 *x = tx;
692 if (ty < INT_MAX)
693 *y = ty;
698 main(int argc, char *argv[])
700 unsigned int winWidth = 300, winHeight = 300;
701 int x = 0, y = 0;
702 int i;
703 GLboolean printInfo = GL_FALSE;
705 for (i = 1; i < argc; i++) {
706 if (strcmp(argv[i], "-info") == 0) {
707 printInfo = GL_TRUE;
709 else if (strcmp(argv[i], "-srgb") == 0) {
710 use_srgb = GL_TRUE;
712 else if (i < argc - 1 && strcmp(argv[i], "-samples") == 0) {
713 samples = strtod(argv[i + 1], NULL);
714 ++i;
716 else if (strcmp(argv[i], "-fullscreen") == 0) {
717 fullscreen = GL_TRUE;
719 else if (strcmp(argv[i], "-geometry") == 0) {
720 parse_geometry(argv[i+1], &x, &y, &winWidth, &winHeight);
721 i++;
723 else {
724 usage();
725 return -1;
729 #if WINVER >= 0x0605
730 SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
731 #endif
733 if (fullscreen) {
734 x = 0; y = 0;
735 winWidth = GetSystemMetrics(SM_CXSCREEN);
736 winHeight = GetSystemMetrics(SM_CYSCREEN);
739 make_window("wglgears", x, y, winWidth, winHeight);
740 reshape(winWidth, winHeight);
741 query_vsync();
743 if (printInfo) {
744 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
745 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
746 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
747 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
750 init();
752 event_loop();
754 /* cleanup */
755 wglMakeCurrent (NULL, NULL);
756 wglDeleteContext (hRC);
757 ReleaseDC (hWnd, hDC);
759 return EXIT_SUCCESS;