wglgears: add srgb-mode to usage
[mesa-demos.git] / src / wgl / wglgears.c
blobed7f5bcaec7890d996bf10719b5595a4a6661d5d
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(" -stereo run in stereo mode\n");
80 printf(" -samples N run in multisample mode with at least N samples\n");
81 printf(" -fullscreen run in fullscreen mode\n");
82 printf(" -info display OpenGL renderer info\n");
83 printf(" -geometry WxH+X+Y window geometry\n");
87 /* return current time (in seconds) */
88 static double
89 current_time(void)
91 return timeGetTime() / 1000.0;
97 * Draw a gear wheel. You'll probably want to call this function when
98 * building a display list since we do a lot of trig here.
100 * Input: inner_radius - radius of hole at center
101 * outer_radius - radius at center of teeth
102 * width - width of gear
103 * teeth - number of teeth
104 * tooth_depth - depth of tooth
106 static void
107 gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
108 GLint teeth, GLfloat tooth_depth)
110 GLint i;
111 GLfloat r0, r1, r2;
112 GLfloat angle, da;
113 GLfloat u, v, len;
115 r0 = inner_radius;
116 r1 = outer_radius - tooth_depth / 2.0;
117 r2 = outer_radius + tooth_depth / 2.0;
119 da = 2.0 * M_PI / teeth / 4.0;
121 glShadeModel(GL_FLAT);
123 glNormal3f(0.0, 0.0, 1.0);
125 /* draw front face */
126 glBegin(GL_QUAD_STRIP);
127 for (i = 0; i <= teeth; i++) {
128 angle = i * 2.0 * M_PI / teeth;
129 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
130 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
131 if (i < teeth) {
132 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
133 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
134 width * 0.5);
137 glEnd();
139 /* draw front sides of teeth */
140 glBegin(GL_QUADS);
141 da = 2.0 * M_PI / teeth / 4.0;
142 for (i = 0; i < teeth; i++) {
143 angle = i * 2.0 * M_PI / teeth;
145 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
146 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
147 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
148 width * 0.5);
149 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
150 width * 0.5);
152 glEnd();
154 glNormal3f(0.0, 0.0, -1.0);
156 /* draw back face */
157 glBegin(GL_QUAD_STRIP);
158 for (i = 0; i <= teeth; i++) {
159 angle = i * 2.0 * M_PI / teeth;
160 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
161 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
162 if (i < teeth) {
163 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
164 -width * 0.5);
165 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
168 glEnd();
170 /* draw back sides of teeth */
171 glBegin(GL_QUADS);
172 da = 2.0 * M_PI / teeth / 4.0;
173 for (i = 0; i < teeth; i++) {
174 angle = i * 2.0 * M_PI / teeth;
176 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
177 -width * 0.5);
178 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
179 -width * 0.5);
180 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
181 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
183 glEnd();
185 /* draw outward faces of teeth */
186 glBegin(GL_QUAD_STRIP);
187 for (i = 0; i < teeth; i++) {
188 angle = i * 2.0 * M_PI / teeth;
190 glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
191 glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
192 u = r2 * cos(angle + da) - r1 * cos(angle);
193 v = r2 * sin(angle + da) - r1 * sin(angle);
194 len = sqrt(u * u + v * v);
195 u /= len;
196 v /= len;
197 glNormal3f(v, -u, 0.0);
198 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
199 glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
200 glNormal3f(cos(angle), sin(angle), 0.0);
201 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
202 width * 0.5);
203 glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
204 -width * 0.5);
205 u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
206 v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
207 glNormal3f(v, -u, 0.0);
208 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
209 width * 0.5);
210 glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
211 -width * 0.5);
212 glNormal3f(cos(angle), sin(angle), 0.0);
215 glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
216 glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
218 glEnd();
220 glShadeModel(GL_SMOOTH);
222 /* draw inside radius cylinder */
223 glBegin(GL_QUAD_STRIP);
224 for (i = 0; i <= teeth; i++) {
225 angle = i * 2.0 * M_PI / teeth;
226 glNormal3f(-cos(angle), -sin(angle), 0.0);
227 glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
228 glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
230 glEnd();
234 static void
235 draw(void)
237 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
239 glPushMatrix();
240 glRotatef(view_rotx, 1.0, 0.0, 0.0);
241 glRotatef(view_roty, 0.0, 1.0, 0.0);
242 glRotatef(view_rotz, 0.0, 0.0, 1.0);
244 glPushMatrix();
245 glTranslatef(-3.0, -2.0, 0.0);
246 glRotatef(angle, 0.0, 0.0, 1.0);
247 glCallList(gear1);
248 glPopMatrix();
250 glPushMatrix();
251 glTranslatef(3.1, -2.0, 0.0);
252 glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
253 glCallList(gear2);
254 glPopMatrix();
256 glPushMatrix();
257 glTranslatef(-3.1, 4.2, 0.0);
258 glRotatef(-2.0 * angle - 25.0, 0.0, 0.0, 1.0);
259 glCallList(gear3);
260 glPopMatrix();
262 glPopMatrix();
266 /* new window size or exposure */
267 static void
268 reshape(int width, int height)
270 GLfloat h = (GLfloat) height / (GLfloat) width;
272 glViewport(0, 0, (GLint) width, (GLint) height);
273 glMatrixMode(GL_PROJECTION);
274 glLoadIdentity();
275 glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
276 glMatrixMode(GL_MODELVIEW);
277 glLoadIdentity();
278 glTranslatef(0.0, 0.0, -40.0);
282 static GLfloat
283 srgb_to_linear(GLfloat c)
285 if (c <= 0.04045f)
286 return c / 12.92f;
287 return powf((c + 0.055f) / 1.055f, 2.4f);
290 static void
291 init(void)
293 static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
294 static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
295 static GLfloat green[4] = { 0.0, 0.8, 0.2, 1.0 };
296 static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };
298 glLightfv(GL_LIGHT0, GL_POSITION, pos);
299 glEnable(GL_CULL_FACE);
300 glEnable(GL_LIGHTING);
301 glEnable(GL_LIGHT0);
302 glEnable(GL_DEPTH_TEST);
303 if (use_srgb) {
304 for (int i = 0; i < 3; ++i) {
305 red[i] = srgb_to_linear(red[i]);
306 green[i] = srgb_to_linear(green[i]);
307 blue[i] = srgb_to_linear(blue[i]);
309 glEnable(GL_FRAMEBUFFER_SRGB);
312 /* make the gears */
313 gear1 = glGenLists(1);
314 glNewList(gear1, GL_COMPILE);
315 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
316 gear(1.0, 4.0, 1.0, 20, 0.7);
317 glEndList();
319 gear2 = glGenLists(1);
320 glNewList(gear2, GL_COMPILE);
321 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
322 gear(0.5, 2.0, 2.0, 10, 0.7);
323 glEndList();
325 gear3 = glGenLists(1);
326 glNewList(gear3, GL_COMPILE);
327 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, blue);
328 gear(1.3, 2.0, 0.5, 10, 0.7);
329 glEndList();
331 glEnable(GL_NORMALIZE);
335 static LRESULT CALLBACK
336 WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
338 switch (uMsg) {
339 case WM_CLOSE:
340 PostQuitMessage(0);
341 return 0;
342 case WM_SIZE:
343 reshape(LOWORD(lParam), HIWORD(lParam));
344 return 0;
345 case WM_KEYDOWN:
346 if (wParam == VK_LEFT)
347 view_roty += 5.0;
348 else if (wParam == VK_RIGHT)
349 view_roty -= 5.0;
350 else if (wParam == VK_UP)
351 view_rotx += 5.0;
352 else if (wParam == VK_DOWN)
353 view_rotx -= 5.0;
354 else if (wParam == VK_ESCAPE)
355 PostQuitMessage(0);
356 else if (wParam == 'A')
357 animate = !animate;
358 return 0;
359 #if WINVER >= 0x0605
360 case WM_NCCREATE:
361 EnableNonClientDpiScaling(hWnd);
362 break;
363 #endif
366 return DefWindowProc(hWnd, uMsg, wParam, lParam);
371 * Create an RGB, double-buffered window.
372 * Return the window and context handles.
374 static void
375 make_window(const char *name, int x, int y, int width, int height)
377 int pixelFormat;
378 WNDCLASS wc;
379 DWORD dwExStyle, dwStyle;
380 static const PIXELFORMATDESCRIPTOR pfd = {
381 sizeof(PIXELFORMATDESCRIPTOR),
383 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
384 PFD_TYPE_RGBA,
386 0, 0, 0, 0, 0, 0,
390 0, 0, 0, 0,
394 PFD_MAIN_PLANE,
396 0, 0, 0
399 winrect.left = (long)0;
400 winrect.right = (long)width;
401 winrect.top = (long) 0;
402 winrect.bottom = (long)height;
404 hInst = GetModuleHandle(NULL);
405 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
406 wc.lpfnWndProc = (WNDPROC)WndProc;
407 wc.cbClsExtra = 0;
408 wc.cbWndExtra = 0;
409 wc.hInstance = hInst;
410 wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
411 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
412 wc.hbrBackground = NULL;
413 wc.lpszMenuName = NULL;
414 wc.lpszClassName = name;
415 RegisterClass(&wc);
417 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
418 if (!fullscreen) {
419 dwStyle = WS_OVERLAPPEDWINDOW;
420 AdjustWindowRectEx(&winrect, dwStyle, FALSE, dwExStyle);
422 else {
423 dwStyle = WS_POPUP;
426 hWnd = CreateWindowEx(dwExStyle, name, name,
427 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
428 x, y,
429 winrect.right - winrect.left,
430 winrect.bottom - winrect.top,
431 NULL, NULL, hInst, NULL);
433 if (fullscreen) {
434 DEVMODE devmode;
435 memset(&devmode, 0, sizeof(DEVMODE));
436 devmode.dmSize = sizeof(DEVMODE);
437 devmode.dmPelsWidth = width;
438 devmode.dmPelsHeight = height;
439 devmode.dmBitsPerPel = 24;
440 devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
441 ChangeDisplaySettings(&devmode, CDS_FULLSCREEN);
444 hDC = GetDC(hWnd);
445 pixelFormat = ChoosePixelFormat(hDC, &pfd);
446 if (!pixelFormat)
447 goto nopixelformat;
449 SetPixelFormat(hDC, pixelFormat, &pfd);
450 hRC = wglCreateContext(hDC);
451 wglMakeCurrent(hDC, hRC);
453 if (use_srgb || samples > 0) {
454 /* We can't query/use extension functions until after we've
455 * created and bound a rendering context (done above).
457 * We can only set the pixel format of the window once, so we need to
458 * create a new device context in order to use the pixel format returned
459 * from wglChoosePixelFormatARB, and then create a new window.
461 PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB_func =
462 (PFNWGLCHOOSEPIXELFORMATARBPROC)
463 wglGetProcAddress("wglChoosePixelFormatARB");
464 assert(wglChoosePixelFormatARB_func);
466 int int_attribs[64] = {
467 WGL_SUPPORT_OPENGL_ARB, TRUE,
468 WGL_DRAW_TO_WINDOW_ARB, TRUE,
469 WGL_COLOR_BITS_ARB, 24, // at least 24-bits of RGB
470 WGL_DEPTH_BITS_ARB, 24,
471 WGL_DOUBLE_BUFFER_ARB, TRUE,
472 WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB, TRUE,
474 int i = 10;
476 if (use_srgb) {
477 int_attribs[i++] = WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB;
478 int_attribs[i++] = TRUE;
480 if (samples > 0) {
481 int_attribs[i++] = WGL_SAMPLE_BUFFERS_ARB;
482 int_attribs[i++] = 1;
483 int_attribs[i++] = WGL_SAMPLES_ARB;
484 int_attribs[i++] = samples;
487 int_attribs[i++] = 0;
489 static const float float_attribs[] = { 0 };
490 UINT numFormats;
492 pixelFormat = 0;
493 if (!wglChoosePixelFormatARB_func(hDC, int_attribs, float_attribs, 1,
494 &pixelFormat, &numFormats) ||
495 !numFormats)
496 goto nopixelformat;
498 PIXELFORMATDESCRIPTOR newPfd;
499 DescribePixelFormat(hDC, pixelFormat, sizeof(pfd), &newPfd);
501 /* now, create new context with new pixel format */
502 wglMakeCurrent(hDC, NULL);
503 wglDeleteContext(hRC);
504 DeleteDC(hDC);
506 DestroyWindow(hWnd);
507 hWnd = CreateWindowEx(dwExStyle, name, name,
508 WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle,
509 x, y,
510 winrect.right - winrect.left,
511 winrect.bottom - winrect.top,
512 NULL, NULL, hInst, NULL);
514 hDC = GetDC(hWnd);
515 SetPixelFormat(hDC, pixelFormat, &pfd);
516 hRC = wglCreateContext(hDC);
517 wglMakeCurrent(hDC, hRC);
520 ShowWindow(hWnd, SW_SHOW);
521 SetForegroundWindow(hWnd);
522 SetFocus(hWnd);
523 return;
525 nopixelformat:
526 printf("Error: couldn't get an RGB, Double-buffered");
527 if (samples > 0)
528 printf(", Multisample");
529 if (use_srgb)
530 printf(", sRGB");
531 printf(" pixelformat\n");
532 exit(1);
535 static void
536 draw_frame()
538 static int frames = 0;
539 static double tRot0 = -1.0, tRate0 = -1.0;
540 double dt, t = current_time();
542 if (tRot0 < 0.0)
543 tRot0 = t;
544 dt = t - tRot0;
545 tRot0 = t;
547 if (animate) {
548 /* advance rotation for next frame */
549 angle += 70.0 * dt; /* 70 degrees per second */
550 if (angle > 3600.0)
551 angle -= 3600.0;
554 draw();
555 SwapBuffers(hDC);
557 frames++;
559 if (tRate0 < 0.0)
560 tRate0 = t;
561 if (t - tRate0 >= 5.0) {
562 GLfloat seconds = t - tRate0;
563 GLfloat fps = frames / seconds;
564 printf("%d frames in %3.1f seconds = %6.3f FPS\n", frames, seconds,
565 fps);
566 fflush(stdout);
567 tRate0 = t;
568 frames = 0;
573 * Determine whether or not a WGL extension is supported.
575 static int
576 is_wgl_extension_supported(HDC hdc, const char *query)
578 static const char *wgl_extensions = NULL;
579 const size_t len = strlen(query);
580 const char *ptr;
582 if (wgl_extensions == NULL) {
583 PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_func =
584 (PFNWGLGETEXTENSIONSSTRINGARBPROC)
585 wglGetProcAddress("wglGetExtensionsStringARB");
586 if (!wglGetExtensionsStringARB_func)
587 return 0;
589 wgl_extensions = wglGetExtensionsStringARB_func(hdc);
592 ptr = strstr(wgl_extensions, query);
593 return ((ptr != NULL) && ((ptr[len] == ' ') || (ptr[len] == '\0')));
598 * Attempt to determine whether or not the display is synched to vblank.
600 static void
601 query_vsync()
603 int interval = 0;
604 if (is_wgl_extension_supported(hDC, "WGL_EXT_swap_control")) {
605 PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT_func =
606 (PFNWGLGETSWAPINTERVALEXTPROC)
607 wglGetProcAddress("wglGetSwapIntervalEXT");
608 interval = wglGetSwapIntervalEXT_func();
611 if (interval > 0) {
612 printf("Running synchronized to the vertical refresh. The framerate should be\n");
613 if (interval == 1) {
614 printf("approximately the same as the monitor refresh rate.\n");
616 else if (interval > 1) {
617 printf("approximately 1/%d the monitor refresh rate.\n",
618 interval);
624 static void
625 event_loop(void)
627 MSG msg;
629 TIMECAPS tc;
630 timeGetDevCaps(&tc, sizeof(tc));
631 timeBeginPeriod(tc.wPeriodMin);
633 while(1) {
634 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
635 if (msg.message == WM_QUIT) break;;
636 TranslateMessage(&msg);
637 DispatchMessage(&msg);
640 draw_frame();
643 timeEndPeriod(tc.wPeriodMin);
647 static void
648 parse_geometry(const char *str, int *x, int *y, unsigned int *w, unsigned int *h)
650 char *end;
651 if (*str == '=')
652 str++;
654 long tw = LONG_MAX;
655 if (isdigit(*str)) {
656 tw = strtol(str, &end, 10);
657 if (str == end)
658 return;
659 str = end;
662 long th = LONG_MAX;
663 if (tolower(*str) == 'x') {
664 str++;
665 th = strtol(str, &end, 10);
666 if (str== end)
667 return;
668 str = end;
671 long tx = LONG_MAX;
672 if (*str == '+' || *str == '-') {
673 tx = strtol(str, &end, 10);
674 if (str == end)
675 return;
676 str = end;
679 long ty = LONG_MAX;
680 if (*str == '+' || *str == '-') {
681 ty = strtol(str, &end, 10);
682 if (str == end)
683 return;
684 str = end;
687 if (tw < LONG_MAX)
688 *w = tw;
689 if (th < LONG_MAX)
690 *h = th;
691 if (tx < INT_MAX)
692 *x = tx;
693 if (ty < INT_MAX)
694 *y = ty;
699 main(int argc, char *argv[])
701 unsigned int winWidth = 300, winHeight = 300;
702 int x = 0, y = 0;
703 int i;
704 GLboolean printInfo = GL_FALSE;
706 for (i = 1; i < argc; i++) {
707 if (strcmp(argv[i], "-info") == 0) {
708 printInfo = GL_TRUE;
710 else if (strcmp(argv[i], "-srgb") == 0) {
711 use_srgb = GL_TRUE;
713 else if (i < argc - 1 && strcmp(argv[i], "-samples") == 0) {
714 samples = strtod(argv[i + 1], NULL);
715 ++i;
717 else if (strcmp(argv[i], "-fullscreen") == 0) {
718 fullscreen = GL_TRUE;
720 else if (strcmp(argv[i], "-geometry") == 0) {
721 parse_geometry(argv[i+1], &x, &y, &winWidth, &winHeight);
722 i++;
724 else {
725 usage();
726 return -1;
730 #if WINVER >= 0x0605
731 SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
732 #endif
734 if (fullscreen) {
735 x = 0; y = 0;
736 winWidth = GetSystemMetrics(SM_CXSCREEN);
737 winHeight = GetSystemMetrics(SM_CYSCREEN);
740 make_window("wglgears", x, y, winWidth, winHeight);
741 reshape(winWidth, winHeight);
742 query_vsync();
744 if (printInfo) {
745 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
746 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
747 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
748 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
751 init();
753 event_loop();
755 /* cleanup */
756 wglMakeCurrent (NULL, NULL);
757 wglDeleteContext (hRC);
758 ReleaseDC (hWnd, hDC);
760 return EXIT_SUCCESS;