Mercurial > hg > forks > gldragon
comparison glxdragon.cpp @ 13:c1e8057cc4d0
Improvements to option handling, add option for setting preferred vsync
mode, default to no vsync.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 28 Oct 2019 19:13:27 +0200 |
parents | 52a586c344f4 |
children | 62be2036f604 |
comparison
equal
deleted
inserted
replaced
12:52a586c344f4 | 13:c1e8057cc4d0 |
---|---|
41 | 41 |
42 /* Default settings etc. constants | 42 /* Default settings etc. constants |
43 */ | 43 */ |
44 #define SET_DEF_WIDTH 1280 | 44 #define SET_DEF_WIDTH 1280 |
45 #define SET_DEF_HEIGHT 960 | 45 #define SET_DEF_HEIGHT 960 |
46 #define SET_FRAMES (180 * 2) | 46 #define SET_FRAMES (180) |
47 | 47 |
48 | 48 |
49 /* Structures | 49 /* Structures |
50 */ | 50 */ |
51 struct Mesh | 51 struct Mesh |
60 | 60 |
61 /* Options | 61 /* Options |
62 */ | 62 */ |
63 bool optUseShaders = false; | 63 bool optUseShaders = false; |
64 int optWidth = SET_DEF_WIDTH, | 64 int optWidth = SET_DEF_WIDTH, |
65 optHeight = SET_DEF_HEIGHT; | 65 optHeight = SET_DEF_HEIGHT, |
66 optVSyncMode = 1; | |
67 | |
66 std::string optModelPrefix = "dragon"; | 68 std::string optModelPrefix = "dragon"; |
67 | 69 |
68 | 70 |
69 /* Globals | 71 /* Globals |
70 */ | 72 */ |
72 SDL_GLContext dmGLContext = NULL; | 74 SDL_GLContext dmGLContext = NULL; |
73 | 75 |
74 | 76 |
75 bool dmInitSDLGL(const int width, const int height, const char *title) | 77 bool dmInitSDLGL(const int width, const int height, const char *title) |
76 { | 78 { |
79 int ret; | |
80 std::string msg; | |
81 | |
77 // Set GL attributes | 82 // Set GL attributes |
78 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); | 83 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); |
79 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); | 84 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1); |
80 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); | 85 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); |
81 | 86 |
106 printf("ERROR: Unable to create SDL OpenGL context: %s\n", | 111 printf("ERROR: Unable to create SDL OpenGL context: %s\n", |
107 SDL_GetError()); | 112 SDL_GetError()); |
108 return false; | 113 return false; |
109 } | 114 } |
110 | 115 |
116 // Check if we want to attempt to use vsync | |
117 switch (optVSyncMode) | |
118 { | |
119 case 3: | |
120 ret = SDL_GL_SetSwapInterval(-1); | |
121 msg = "adaptive vsync"; | |
122 break; | |
123 | |
124 case 2: | |
125 ret = SDL_GL_SetSwapInterval(1); | |
126 msg = "synchronized (vsync)"; | |
127 break; | |
128 | |
129 case 1: | |
130 ret = SDL_GL_SetSwapInterval(0); | |
131 msg = "immediate (no vsync)"; | |
132 break; | |
133 | |
134 default: | |
135 ret = -1; | |
136 msg = "INVALID VSYNC MODE"; | |
137 break; | |
138 } | |
139 | |
140 if (ret != 0) | |
141 { | |
142 printf("ERROR: Could not set vsync mode to %s.\n", | |
143 msg.c_str()); | |
144 return false; | |
145 } | |
146 | |
111 // Dump some information | 147 // Dump some information |
112 printf( | 148 printf( |
113 "GL_VENDOR : %s\n" | 149 "GL_VENDOR : %s\n" |
114 "GL_RENDERER : %s\n" | 150 "GL_RENDERER : %s\n" |
115 "GL_VERSION : %s\n", | 151 "GL_VERSION : %s\n" |
152 "VSync mode : %s\n", | |
116 glGetString(GL_VENDOR), | 153 glGetString(GL_VENDOR), |
117 glGetString(GL_RENDERER), | 154 glGetString(GL_RENDERER), |
118 glGetString(GL_VERSION)); | 155 glGetString(GL_VERSION), |
156 msg.c_str()); | |
119 | 157 |
120 // Setup the window and view port | 158 // Setup the window and view port |
121 glViewport(0, 0, width, height); | 159 glViewport(0, 0, width, height); |
122 | 160 |
123 glMatrixMode(GL_PROJECTION); | 161 glMatrixMode(GL_PROJECTION); |
304 int main(int argc, char *argv[]) | 342 int main(int argc, char *argv[]) |
305 { | 343 { |
306 std::string modelVertStr, modelFragStr; | 344 std::string modelVertStr, modelFragStr; |
307 struct Mesh modelMesh; | 345 struct Mesh modelMesh; |
308 bool exitFlag = false, optShowHelp = false; | 346 bool exitFlag = false, optShowHelp = false; |
309 int startTime, nframes = 0; | 347 int startTime, cycleStart, cycleFrames = 0, totalFrames = 0; |
348 double totalTime; | |
310 | 349 |
311 // Check commandline argument for enabling shaders | 350 // Check commandline argument for enabling shaders |
312 for (int narg = 1; narg < argc; narg++) | 351 for (int narg = 1; narg < argc; narg++) |
313 { | 352 { |
314 char *arg = argv[narg]; | 353 char *arg = argv[narg]; |
327 opt++; | 366 opt++; |
328 | 367 |
329 if (opt[0] == 'g') | 368 if (opt[0] == 'g') |
330 optUseShaders = true; | 369 optUseShaders = true; |
331 else | 370 else |
332 if (opt[0] == 'w') | 371 switch (opt[0]) |
333 optWidth = atoi(opt + 1); | |
334 else | |
335 if (opt[0] == 'h') | |
336 optHeight = atoi(opt + 1); | |
337 else | |
338 if (opt[0] == 'm') | |
339 { | 372 { |
340 if (opt[1] == 0) | 373 case 'w': |
341 { | 374 case 'h': |
342 printf("Option -m requires an argument.\n"); | 375 case 'm': |
376 case 'v': | |
377 if (opt[1] == 0) | |
378 { | |
379 printf("Option '%s' requires an argument.\n", opt); | |
380 goto exit; | |
381 } | |
382 | |
383 switch (opt[0]) | |
384 { | |
385 case 'w': optWidth = atoi(opt + 1); break; | |
386 case 'h': optHeight = atoi(opt + 1); break; | |
387 case 'm': optModelPrefix = std::string(opt + 1); break; | |
388 case 'v': optVSyncMode = atoi(opt + 1); break; | |
389 } | |
390 break; | |
391 | |
392 default: | |
393 printf("Unknown option '%s'.\n", opt); | |
343 goto exit; | 394 goto exit; |
344 } | |
345 | |
346 optModelPrefix = std::string(opt + 1); | |
347 } | 395 } |
348 } | 396 } |
349 } | 397 } |
350 | 398 |
351 if (optShowHelp) | 399 if (optShowHelp) |
356 "-g Use GLSL shader instead of basic OpenGL lighting\n" | 404 "-g Use GLSL shader instead of basic OpenGL lighting\n" |
357 "-w<width> Window width (default %d)\n" | 405 "-w<width> Window width (default %d)\n" |
358 "-h<height> Window height (default %d)\n" | 406 "-h<height> Window height (default %d)\n" |
359 "-m<modelfile> Set model filenames prefix. Using \"-mfoo\" will\n" | 407 "-m<modelfile> Set model filenames prefix. Using \"-mfoo\" will\n" |
360 " specify \"foo.mesh\", \"foo.frag\", \"foo.vert\".\n" | 408 " specify \"foo.mesh\", \"foo.frag\", \"foo.vert\".\n" |
409 "-v<1-3> Set vsync mode: 1 = no vsync, 2 = vsync, 3 = adaptive\n" | |
410 " Default is no vsync.\n" | |
361 "\n", | 411 "\n", |
362 argv[0], | 412 argv[0], |
363 SET_DEF_WIDTH, SET_DEF_HEIGHT | 413 SET_DEF_WIDTH, SET_DEF_HEIGHT |
364 ); | 414 ); |
365 | 415 |
416 goto exit; | |
417 } | |
418 | |
419 if (optWidth < 100 || optWidth > 8192 || optHeight < 100 || optHeight > 8192) | |
420 { | |
421 printf("ERROR: Invalid window width or height (%d x %d).\n", | |
422 optWidth, optHeight); | |
366 goto exit; | 423 goto exit; |
367 } | 424 } |
368 | 425 |
369 if (optModelPrefix.empty()) | 426 if (optModelPrefix.empty()) |
370 { | 427 { |
423 // Define the camera | 480 // Define the camera |
424 gluLookAt(0, 0.12, 0.24, 0, 0.12, 0, 0, 1, 0); | 481 gluLookAt(0, 0.12, 0.24, 0, 0.12, 0, 0, 1, 0); |
425 | 482 |
426 | 483 |
427 // Main loop starts | 484 // Main loop starts |
428 startTime = SDL_GetTicks(); | 485 startTime = cycleStart = SDL_GetTicks(); |
429 | 486 |
430 while (!exitFlag) | 487 while (!exitFlag) |
431 { | 488 { |
432 SDL_Event event; | 489 SDL_Event event; |
433 | 490 |
457 | 514 |
458 // Rotate for 2 degrees | 515 // Rotate for 2 degrees |
459 glRotatef(2.0f, 0, 1, 0); | 516 glRotatef(2.0f, 0, 1, 0); |
460 | 517 |
461 // Return true if a full rotation was done | 518 // Return true if a full rotation was done |
462 if (nframes++ == SET_FRAMES) | 519 if (cycleFrames++ == SET_FRAMES) |
463 { | 520 { |
464 // Reset nframes | 521 // Reset cycleFrames |
465 nframes = 0; | 522 totalFrames += cycleFrames; |
523 cycleFrames = 0; | |
466 | 524 |
467 // Get the time it took to render a full turn | 525 // Get the time it took to render a full turn |
468 double time = SDL_GetTicks() - startTime; | 526 int cycleEnd = SDL_GetTicks(); |
527 double cycleTime = cycleEnd - cycleStart; | |
469 | 528 |
470 // Restart the timer | 529 // Restart the timer |
471 startTime = SDL_GetTicks(); | 530 cycleStart = SDL_GetTicks(); |
472 | 531 |
473 // Print the current frames per second | 532 // Print the current frames per second |
474 printf("%.1lf ms for %d frames = %.1lf FPS\n", | 533 printf("%.1lf ms for %d frames = %.1lf FPS\n", |
475 time, SET_FRAMES, (SET_FRAMES * 1000.0f) / time); | 534 cycleTime, SET_FRAMES, (SET_FRAMES * 1000.0f) / cycleTime); |
476 } | 535 } |
477 } | 536 } |
537 | |
538 // Show totals | |
539 totalTime = SDL_GetTicks() - startTime; | |
540 printf("%.1lf ms total for %d total frames = %.2lf FPS average\n", | |
541 totalTime, totalFrames, (totalFrames * 1000.0f) / totalTime); | |
478 | 542 |
479 exit: | 543 exit: |
480 if (dmGLContext != NULL) | 544 if (dmGLContext != NULL) |
481 SDL_GL_DeleteContext(dmGLContext); | 545 SDL_GL_DeleteContext(dmGLContext); |
482 | 546 |