changeset 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
files glxdragon.cpp
diffstat 1 files changed, 89 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/glxdragon.cpp	Mon Oct 28 15:03:52 2019 +0200
+++ b/glxdragon.cpp	Mon Oct 28 19:13:27 2019 +0200
@@ -43,7 +43,7 @@
  */
 #define SET_DEF_WIDTH   1280
 #define SET_DEF_HEIGHT  960
-#define SET_FRAMES      (180 * 2)
+#define SET_FRAMES      (180)
 
 
 /* Structures
@@ -62,7 +62,9 @@
  */
 bool   optUseShaders = false;
 int    optWidth = SET_DEF_WIDTH,
-       optHeight = SET_DEF_HEIGHT;
+       optHeight = SET_DEF_HEIGHT,
+       optVSyncMode = 1;
+
 std::string optModelPrefix = "dragon";
 
 
@@ -74,6 +76,9 @@
 
 bool dmInitSDLGL(const int width, const int height, const char *title)
 {
+    int ret;
+    std::string msg;
+
     // Set GL attributes
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
     SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
@@ -108,14 +113,47 @@
         return false;
     }
 
+    // Check if we want to attempt to use vsync
+    switch (optVSyncMode)
+    {
+        case 3:
+            ret = SDL_GL_SetSwapInterval(-1);
+            msg = "adaptive vsync";
+            break;
+
+        case 2:
+            ret = SDL_GL_SetSwapInterval(1);
+            msg = "synchronized (vsync)";
+            break;
+
+        case 1:
+            ret = SDL_GL_SetSwapInterval(0);
+            msg = "immediate (no vsync)";
+            break;
+
+        default:
+            ret = -1;
+            msg = "INVALID VSYNC MODE";
+            break;
+    }
+
+    if (ret != 0)
+    {
+        printf("ERROR: Could not set vsync mode to %s.\n",
+            msg.c_str());
+        return false;
+    }
+
     // Dump some information
     printf(
         "GL_VENDOR   : %s\n"
         "GL_RENDERER : %s\n"
-        "GL_VERSION  : %s\n",
+        "GL_VERSION  : %s\n"
+        "VSync mode  : %s\n",
         glGetString(GL_VENDOR),
         glGetString(GL_RENDERER),
-        glGetString(GL_VERSION));
+        glGetString(GL_VERSION),
+        msg.c_str());
 
     // Setup the window and view port
     glViewport(0, 0, width, height);
@@ -306,7 +344,8 @@
     std::string modelVertStr, modelFragStr;
     struct Mesh modelMesh;
     bool exitFlag = false, optShowHelp = false;
-    int startTime, nframes = 0;
+    int startTime, cycleStart, cycleFrames = 0, totalFrames = 0;
+    double totalTime;
 
     // Check commandline argument for enabling shaders
     for (int narg = 1; narg < argc; narg++)
@@ -329,21 +368,30 @@
             if (opt[0] == 'g')
                 optUseShaders = true;
             else
-            if (opt[0] == 'w')
-                optWidth = atoi(opt + 1);
-            else
-            if (opt[0] == 'h')
-                optHeight = atoi(opt + 1);
-            else
-            if (opt[0] == 'm')
+            switch (opt[0])
             {
-                if (opt[1] == 0)
-                {
-                    printf("Option -m requires an argument.\n");
+                case 'w':
+                case 'h':
+                case 'm':
+                case 'v':
+                    if (opt[1] == 0)
+                    {
+                        printf("Option '%s' requires an argument.\n", opt);
+                        goto exit;
+                    }
+
+                    switch (opt[0])
+                    {
+                        case 'w': optWidth = atoi(opt + 1); break;
+                        case 'h': optHeight = atoi(opt + 1); break;
+                        case 'm': optModelPrefix = std::string(opt + 1); break;
+                        case 'v': optVSyncMode = atoi(opt + 1); break;
+                    }
+                    break;
+
+                default:
+                    printf("Unknown option '%s'.\n", opt);
                     goto exit;
-                }
-
-                optModelPrefix = std::string(opt + 1);
             }
         }
     }
@@ -358,6 +406,8 @@
             "-h<height>    Window height (default %d)\n"
             "-m<modelfile> Set model filenames prefix. Using \"-mfoo\" will\n"
             "              specify \"foo.mesh\", \"foo.frag\", \"foo.vert\".\n"
+            "-v<1-3>       Set vsync mode: 1 = no vsync, 2 = vsync, 3 = adaptive\n"
+            "              Default is no vsync.\n"
             "\n",
             argv[0],
             SET_DEF_WIDTH, SET_DEF_HEIGHT
@@ -366,6 +416,13 @@
         goto exit;
     }
 
+    if (optWidth < 100 || optWidth > 8192 || optHeight < 100 || optHeight > 8192)
+    {
+        printf("ERROR: Invalid window width or height (%d x %d).\n",
+            optWidth, optHeight);
+        goto exit;
+    }
+
     if (optModelPrefix.empty())
     {
         printf("Model file prefix empty.\n");
@@ -425,7 +482,7 @@
 
 
     // Main loop starts
-    startTime = SDL_GetTicks();
+    startTime = cycleStart = SDL_GetTicks();
 
     while (!exitFlag)
     {
@@ -459,23 +516,30 @@
         glRotatef(2.0f, 0, 1, 0);
 
         // Return true if a full rotation was done
-        if (nframes++ == SET_FRAMES)
+        if (cycleFrames++ == SET_FRAMES)
         {
-            // Reset nframes
-            nframes = 0;
+            // Reset cycleFrames
+            totalFrames += cycleFrames;
+            cycleFrames = 0;
 
             // Get the time it took to render a full turn
-            double time = SDL_GetTicks() - startTime;
+            int cycleEnd = SDL_GetTicks();
+            double cycleTime = cycleEnd - cycleStart;
 
             // Restart the timer
-            startTime = SDL_GetTicks();
+            cycleStart = SDL_GetTicks();
 
             // Print the current frames per second
             printf("%.1lf ms for %d frames = %.1lf FPS\n",
-                time, SET_FRAMES, (SET_FRAMES * 1000.0f) / time);
+                cycleTime, SET_FRAMES, (SET_FRAMES * 1000.0f) / cycleTime);
         }
     }
 
+    // Show totals
+    totalTime = SDL_GetTicks() - startTime;
+    printf("%.1lf ms total for %d total frames = %.2lf FPS average\n",
+        totalTime, totalFrames, (totalFrames * 1000.0f) / totalTime);
+
 exit:
     if (dmGLContext != NULL)
         SDL_GL_DeleteContext(dmGLContext);