# HG changeset patch # User Matti Hamalainen # Date 1574393374 -7200 # Node ID f080349584b8be30b5e5399f6ae92199f50bd989 # Parent 03b86b9c2f2910885f9bec428b65c15e10d67bb2 Rename from glxdragon to gldragon. diff -r 03b86b9c2f29 -r f080349584b8 Makefile --- a/Makefile Fri Nov 22 05:29:02 2019 +0200 +++ b/Makefile Fri Nov 22 05:29:34 2019 +0200 @@ -9,7 +9,7 @@ CFLAGS += $(SDLGL_CFLAGS) LDFLAGS += $(SDLGL_LIBS) -TARGETS = glxdragon$(BINEXT) +TARGETS = gldragon$(BINEXT) %.o: %.cpp %.h @@ -19,7 +19,7 @@ $(CXX) $(CFLAGS) -c -o $@ $< -glxdragon$(BINEXT): glxdragon.o dmmodel.o dmutil.o +gldragon$(BINEXT): gldragon.o dmmodel.o dmutil.o $(CXX) -o $@ $+ $(LDFLAGS) clean: diff -r 03b86b9c2f29 -r f080349584b8 gldragon.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gldragon.cpp Fri Nov 22 05:29:34 2019 +0200 @@ -0,0 +1,526 @@ +// +// GLDragon - OpenGL PLY model viewer / simple benchmark +// Programmed and designed by Matti 'ccr' Hämäläinen +// (C) Copyright 2019 Tecnic Software productions (TNSP) +// +// See file "COPYING" for license information. +// +// Originally based on 'glxdragon' Copyright (c) 2009, Thomas Trummer +// +#include +#include +#include +#include + +#include "dmutil.h" +#include "dmmodel.h" + + +/* Default settings etc. constants + */ +#define SET_DEF_WIDTH 1280 +#define SET_DEF_HEIGHT 960 +#define SET_FRAMES (180) +#define SET_MAX_SHADER_SIZE (128 * 1024) + + +/* Options + */ +bool optUseShaders = false; +int optWidth = SET_DEF_WIDTH, + optHeight = SET_DEF_HEIGHT, + optVSyncMode = 1; + + + +/* Globals + */ +SDL_Window *dmWindow = NULL; +SDL_GLContext dmGLContext = NULL; + + +/* Helpers + */ +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); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + // Attempt to initialize libSDL + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS) != 0) + { + printf("ERROR: Unable to initialize SDL: %s\n", + SDL_GetError()); + return false; + } + + // Attempt to create a window + if ((dmWindow = SDL_CreateWindow(title, + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + width, height, + SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE)) == NULL) + { + printf("ERROR: Could not create SDL window: %s", + SDL_GetError()); + return false; + } + + if ((dmGLContext = SDL_GL_CreateContext(dmWindow)) == NULL) + { + printf("ERROR: Unable to create SDL OpenGL context: %s\n", + SDL_GetError()); + 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" + "VSync mode : %s\n", + glGetString(GL_VENDOR), + glGetString(GL_RENDERER), + glGetString(GL_VERSION), + msg.c_str()); + + // Setup the window and view port + glViewport(0, 0, width, height); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + gluPerspective(45.0f, GLfloat(width) / GLfloat(height), 0.1f, 1000.0f); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + // Enable back face culling + glEnable(GL_CULL_FACE); + + // Enable smooth shading + glShadeModel(GL_SMOOTH); + + // Enable the depth buffer + glEnable(GL_DEPTH_TEST); + + // Enable normal rescaling + glEnable(GL_RESCALE_NORMAL); + + // Setup depth buffer + glClearDepth(1.0f); + + // Set the depth buffer function + glDepthFunc(GL_LEQUAL); + + // Enable vertex and and normal arrays + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + // Set correct perspective correction + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + return true; +} + + +void dmDrawModel(const DMModel &model) +{ + int maxIndices; + + if (optUseShaders) + { + // Enable shader program + glUseProgram(model.id_prog); + } + else + { + // Set the color of the model + glEnable(GL_LIGHTING); + glColor3ub(0x90, 0x80, 0x90); + } + + // Render the model + glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices); + + glPushMatrix(); + + // Add transforms + glScalef(model.scale.x, model.scale.y, model.scale.z); + glTranslatef(model.translate.x, model.translate.y, model.translate. z); + glRotatef(model.rotate.x, 1.0f, 0.0f, 0.0f); + glRotatef(model.rotate.y, 0.0f, 1.0f, 0.0f); + glRotatef(model.rotate.z, 0.0f, 0.0f, 1.0f); + + glVertexPointer(3, GL_FLOAT, 0, &model.vertices[0]); + glNormalPointer( GL_FLOAT, 0, &model.normals[0]); + + for (int n = 0; n < model.nfaces; n += maxIndices) + { + const int count = std::min(maxIndices, model.nfaces - n); + glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_INT, &model.faces[n * 3]); + } + + glPopMatrix(); + + // Restore + if (optUseShaders) + { + glUseProgram(0); + } +} + + +void dmDrawScene(const DMSimpleScene &scene) +{ + glClear(GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glOrtho(0.0, 1.0, 0.0, 1.0, -1, 1); + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + // Draw the background gradient + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); + glBegin(GL_QUADS); + { + glColor3ub(0x3B, 0x3B, 0x75); + glVertex2f(0.0f, 0.0f); + glVertex2f(1.0f, 0.0f); + + glColor3ub(0x00, 0x00, 0x00); + glVertex2f(1.0f, 1.0f); + glVertex2f(0.0f, 1.0f); + } + glEnd(); + + + // Restore the 3D projection + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + glEnable(GL_DEPTH_TEST); + + // Draw models + for (const DMModel &model : scene.models) + dmDrawModel(model); +} + + +GLuint dmCompileShader(const GLenum stype, const std::string &src) +{ + GLuint shader = glCreateShader(stype); + const char *tmp = src.c_str(); + + glShaderSource(shader, 1, &tmp, 0); + glCompileShader(shader); + + return shader; +} + + +void dmLinkModelShaders(DMModel &model) +{ + model.id_prog = glCreateProgram(); + glAttachShader(model.id_prog, model.id_fs); + glAttachShader(model.id_prog, model.id_vs); + glLinkProgram(model.id_prog); +} + + +int main(int argc, char *argv[]) +{ + int startTime, cycleStart, cycleFrames = 0, totalFrames = 0; + double totalTime; + bool + exitFlag = false, + optShowHelp = false, + optSetInputFilename = false; + std::string optInputFilename = "dragon.scene", basePath; + DMSimpleScene scene; + + // Check commandline argument for enabling shaders + for (int narg = 1; narg < argc; narg++) + { + char *arg = argv[narg]; + if (arg[0] == '-') + { + char *opt = arg + 1; + + if ((opt[0] == '-' && opt[1] == 'h' && opt[2] == 'e') || + opt[0] == '?' || (opt[0] == '-' && opt[1] == '?')) + { + optShowHelp = true; + break; + } + else + if (opt[0] == '-') + opt++; + + if (opt[0] == 'g') + optUseShaders = true; + else + switch (opt[0]) + { + 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 'v': optVSyncMode = atoi(opt + 1); break; + } + break; + + default: + printf("Unknown option '%s'.\n", opt); + goto exit; + } + } + else + { + if (optSetInputFilename) + { + printf("ERROR: Please specify only one scene file.\n"); + goto exit; + } + + optSetInputFilename = true; + optInputFilename = std::string(arg); + if (optInputFilename.empty()) + { + printf("ERROR: Invalid input filename.\n"); + goto exit; + } + + } + } + + if (optShowHelp) + { + printf( + "Usage: %s [options] []\n" + "-? Show this help\n" + "-g Use GLSL shader instead of basic OpenGL lighting\n" + "-w Window width (default %d)\n" + "-h Window height (default %d)\n" + "-v<1-3> Set vsync mode: 1 = no vsync, 2 = vsync, 3 = adaptive\n" + " Default is no vsync. Using vsync will result in FPS being\n" + " approx whatever your monitor refresh rate is.\n" + "\n", + argv[0], + SET_DEF_WIDTH, SET_DEF_HEIGHT + ); + + 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; + } + + // Load the scene + if (!scene.loadInfo(optInputFilename)) + goto exit; + + if (scene.models.size() == 0) + { + printf("ERROR: Scenefile '%s' contains no models.\n", + optInputFilename.c_str()); + goto exit; + } + + printf("INFO: Loading %ld model(s) ..\n", + scene.models.size()); + + basePath = dmGetPath(optInputFilename); + printf("INFO: Model base path '%s'\n", basePath.c_str()); + + for (DMModel &model : scene.models) + { + if (!model.loadFromPLY(basePath + model.modelFile)) + goto exit; + + if (optUseShaders) + { + std::string + fragFile = model.fragShaderFile.empty() ? "shader.frag" : basePath + model.fragShaderFile, + vertFile = model.vertShaderFile.empty() ? "shader.vert" : basePath + model.vertShaderFile; + + if (!dmReadText(fragFile, model.fragShaderStr, SET_MAX_SHADER_SIZE) || + !dmReadText(vertFile, model.vertShaderStr, SET_MAX_SHADER_SIZE)) + goto exit; + } + } + + // Initialize SDL + OpenGL + if (!dmInitSDLGL(optWidth, optHeight, "GLDragon")) + goto exit; + + // According to our mode .. + if (optUseShaders) + { + for (DMModel &model : scene.models) + { + model.id_fs = dmCompileShader(GL_FRAGMENT_SHADER, model.fragShaderStr); + model.id_vs = dmCompileShader(GL_VERTEX_SHADER, model.vertShaderStr); + dmLinkModelShaders(model); + } + } + else + { + float specReflection[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + + glEnable(GL_COLOR_MATERIAL); + + glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); + glMateriali(GL_FRONT, GL_SHININESS, 96); + glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection); + + glEnable(GL_LIGHT0); + + // Define the light components and position + GLfloat ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; + GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; + GLfloat specular[] = { 0.5f, 0.5f, 0.5f, 1.0f }; + GLfloat position[] = { 10.0f, 10.0f, 0.0f, 0.0f }; + + // Define the light components and position + glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); + glLightfv(GL_LIGHT0, GL_SPECULAR, specular); + glLightfv(GL_LIGHT0, GL_POSITION, position); + } + + // Define the camera + gluLookAt(0, 0.12, 0.24, 0, 0.12, 0, 0, 1, 0); + + + // Main loop starts + startTime = cycleStart = SDL_GetTicks(); + + while (!exitFlag) + { + SDL_Event event; + + // Check for quit events + while (SDL_PollEvent(&event)) + switch (event.type) + { + case SDL_QUIT: + exitFlag = true; + break; + + case SDL_KEYDOWN: + switch (event.key.keysym.sym) + { + case SDLK_ESCAPE: + case SDLK_q: + exitFlag = true; + break; + } + } + + // Render the next frame + dmDrawScene(scene); + + // Draw the current frame + SDL_GL_SwapWindow(dmWindow); + + // Rotate for 2 degrees + glRotatef(2.0f, 0, 1, 0); + + // Return true if a full rotation was done + totalFrames++; + if (cycleFrames++ == SET_FRAMES) + { + // Reset cycleFrames + cycleFrames = 0; + + // Get the time it took to render a full turn + int cycleEnd = SDL_GetTicks(); + double cycleTime = cycleEnd - cycleStart; + + // Restart the timer + cycleStart = SDL_GetTicks(); + + // Print the current frames per second + printf("%.1lf ms for %d frames = %.1lf FPS\n", + 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); + + if (dmWindow != NULL) + SDL_DestroyWindow(dmWindow); + + SDL_Quit(); + + return 0; +} diff -r 03b86b9c2f29 -r f080349584b8 glxdragon.cpp --- a/glxdragon.cpp Fri Nov 22 05:29:02 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,526 +0,0 @@ -// -// GLDragon - OpenGL PLY model viewer / simple benchmark -// Programmed and designed by Matti 'ccr' Hämäläinen -// (C) Copyright 2019 Tecnic Software productions (TNSP) -// -// See file "COPYING" for license information. -// -// Originally based on 'glxdragon' Copyright (c) 2009, Thomas Trummer -// -#include -#include -#include -#include - -#include "dmutil.h" -#include "dmmodel.h" - - -/* Default settings etc. constants - */ -#define SET_DEF_WIDTH 1280 -#define SET_DEF_HEIGHT 960 -#define SET_FRAMES (180) -#define SET_MAX_SHADER_SIZE (128 * 1024) - - -/* Options - */ -bool optUseShaders = false; -int optWidth = SET_DEF_WIDTH, - optHeight = SET_DEF_HEIGHT, - optVSyncMode = 1; - - - -/* Globals - */ -SDL_Window *dmWindow = NULL; -SDL_GLContext dmGLContext = NULL; - - -/* Helpers - */ -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); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - // Attempt to initialize libSDL - if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS) != 0) - { - printf("ERROR: Unable to initialize SDL: %s\n", - SDL_GetError()); - return false; - } - - // Attempt to create a window - if ((dmWindow = SDL_CreateWindow(title, - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - width, height, - SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE)) == NULL) - { - printf("ERROR: Could not create SDL window: %s", - SDL_GetError()); - return false; - } - - if ((dmGLContext = SDL_GL_CreateContext(dmWindow)) == NULL) - { - printf("ERROR: Unable to create SDL OpenGL context: %s\n", - SDL_GetError()); - 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" - "VSync mode : %s\n", - glGetString(GL_VENDOR), - glGetString(GL_RENDERER), - glGetString(GL_VERSION), - msg.c_str()); - - // Setup the window and view port - glViewport(0, 0, width, height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - gluPerspective(45.0f, GLfloat(width) / GLfloat(height), 0.1f, 1000.0f); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - // Enable back face culling - glEnable(GL_CULL_FACE); - - // Enable smooth shading - glShadeModel(GL_SMOOTH); - - // Enable the depth buffer - glEnable(GL_DEPTH_TEST); - - // Enable normal rescaling - glEnable(GL_RESCALE_NORMAL); - - // Setup depth buffer - glClearDepth(1.0f); - - // Set the depth buffer function - glDepthFunc(GL_LEQUAL); - - // Enable vertex and and normal arrays - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - - // Set correct perspective correction - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - return true; -} - - -void dmDrawModel(const DMModel &model) -{ - int maxIndices; - - if (optUseShaders) - { - // Enable shader program - glUseProgram(model.id_prog); - } - else - { - // Set the color of the model - glEnable(GL_LIGHTING); - glColor3ub(0x90, 0x80, 0x90); - } - - // Render the model - glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices); - - glPushMatrix(); - - // Add transforms - glScalef(model.scale.x, model.scale.y, model.scale.z); - glTranslatef(model.translate.x, model.translate.y, model.translate. z); - glRotatef(model.rotate.x, 1.0f, 0.0f, 0.0f); - glRotatef(model.rotate.y, 0.0f, 1.0f, 0.0f); - glRotatef(model.rotate.z, 0.0f, 0.0f, 1.0f); - - glVertexPointer(3, GL_FLOAT, 0, &model.vertices[0]); - glNormalPointer( GL_FLOAT, 0, &model.normals[0]); - - for (int n = 0; n < model.nfaces; n += maxIndices) - { - const int count = std::min(maxIndices, model.nfaces - n); - glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_INT, &model.faces[n * 3]); - } - - glPopMatrix(); - - // Restore - if (optUseShaders) - { - glUseProgram(0); - } -} - - -void dmDrawScene(const DMSimpleScene &scene) -{ - glClear(GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glOrtho(0.0, 1.0, 0.0, 1.0, -1, 1); - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - // Draw the background gradient - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); - glBegin(GL_QUADS); - { - glColor3ub(0x3B, 0x3B, 0x75); - glVertex2f(0.0f, 0.0f); - glVertex2f(1.0f, 0.0f); - - glColor3ub(0x00, 0x00, 0x00); - glVertex2f(1.0f, 1.0f); - glVertex2f(0.0f, 1.0f); - } - glEnd(); - - - // Restore the 3D projection - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - glEnable(GL_DEPTH_TEST); - - // Draw models - for (const DMModel &model : scene.models) - dmDrawModel(model); -} - - -GLuint dmCompileShader(const GLenum stype, const std::string &src) -{ - GLuint shader = glCreateShader(stype); - const char *tmp = src.c_str(); - - glShaderSource(shader, 1, &tmp, 0); - glCompileShader(shader); - - return shader; -} - - -void dmLinkModelShaders(DMModel &model) -{ - model.id_prog = glCreateProgram(); - glAttachShader(model.id_prog, model.id_fs); - glAttachShader(model.id_prog, model.id_vs); - glLinkProgram(model.id_prog); -} - - -int main(int argc, char *argv[]) -{ - int startTime, cycleStart, cycleFrames = 0, totalFrames = 0; - double totalTime; - bool - exitFlag = false, - optShowHelp = false, - optSetInputFilename = false; - std::string optInputFilename = "dragon.scene", basePath; - DMSimpleScene scene; - - // Check commandline argument for enabling shaders - for (int narg = 1; narg < argc; narg++) - { - char *arg = argv[narg]; - if (arg[0] == '-') - { - char *opt = arg + 1; - - if ((opt[0] == '-' && opt[1] == 'h' && opt[2] == 'e') || - opt[0] == '?' || (opt[0] == '-' && opt[1] == '?')) - { - optShowHelp = true; - break; - } - else - if (opt[0] == '-') - opt++; - - if (opt[0] == 'g') - optUseShaders = true; - else - switch (opt[0]) - { - 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 'v': optVSyncMode = atoi(opt + 1); break; - } - break; - - default: - printf("Unknown option '%s'.\n", opt); - goto exit; - } - } - else - { - if (optSetInputFilename) - { - printf("ERROR: Please specify only one scene file.\n"); - goto exit; - } - - optSetInputFilename = true; - optInputFilename = std::string(arg); - if (optInputFilename.empty()) - { - printf("ERROR: Invalid input filename.\n"); - goto exit; - } - - } - } - - if (optShowHelp) - { - printf( - "Usage: %s [options] []\n" - "-? Show this help\n" - "-g Use GLSL shader instead of basic OpenGL lighting\n" - "-w Window width (default %d)\n" - "-h Window height (default %d)\n" - "-v<1-3> Set vsync mode: 1 = no vsync, 2 = vsync, 3 = adaptive\n" - " Default is no vsync. Using vsync will result in FPS being\n" - " approx whatever your monitor refresh rate is.\n" - "\n", - argv[0], - SET_DEF_WIDTH, SET_DEF_HEIGHT - ); - - 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; - } - - // Load the scene - if (!scene.loadInfo(optInputFilename)) - goto exit; - - if (scene.models.size() == 0) - { - printf("ERROR: Scenefile '%s' contains no models.\n", - optInputFilename.c_str()); - goto exit; - } - - printf("INFO: Loading %ld model(s) ..\n", - scene.models.size()); - - basePath = dmGetPath(optInputFilename); - printf("INFO: Model base path '%s'\n", basePath.c_str()); - - for (DMModel &model : scene.models) - { - if (!model.loadFromPLY(basePath + model.modelFile)) - goto exit; - - if (optUseShaders) - { - std::string - fragFile = model.fragShaderFile.empty() ? "shader.frag" : basePath + model.fragShaderFile, - vertFile = model.vertShaderFile.empty() ? "shader.vert" : basePath + model.vertShaderFile; - - if (!dmReadText(fragFile, model.fragShaderStr, SET_MAX_SHADER_SIZE) || - !dmReadText(vertFile, model.vertShaderStr, SET_MAX_SHADER_SIZE)) - goto exit; - } - } - - // Initialize SDL + OpenGL - if (!dmInitSDLGL(optWidth, optHeight, "GLDragon")) - goto exit; - - // According to our mode .. - if (optUseShaders) - { - for (DMModel &model : scene.models) - { - model.id_fs = dmCompileShader(GL_FRAGMENT_SHADER, model.fragShaderStr); - model.id_vs = dmCompileShader(GL_VERTEX_SHADER, model.vertShaderStr); - dmLinkModelShaders(model); - } - } - else - { - float specReflection[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - - glEnable(GL_COLOR_MATERIAL); - - glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); - glMateriali(GL_FRONT, GL_SHININESS, 96); - glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection); - - glEnable(GL_LIGHT0); - - // Define the light components and position - GLfloat ambient[] = { 0.2f, 0.2f, 0.2f, 1.0f }; - GLfloat diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f }; - GLfloat specular[] = { 0.5f, 0.5f, 0.5f, 1.0f }; - GLfloat position[] = { 10.0f, 10.0f, 0.0f, 0.0f }; - - // Define the light components and position - glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); - glLightfv(GL_LIGHT0, GL_SPECULAR, specular); - glLightfv(GL_LIGHT0, GL_POSITION, position); - } - - // Define the camera - gluLookAt(0, 0.12, 0.24, 0, 0.12, 0, 0, 1, 0); - - - // Main loop starts - startTime = cycleStart = SDL_GetTicks(); - - while (!exitFlag) - { - SDL_Event event; - - // Check for quit events - while (SDL_PollEvent(&event)) - switch (event.type) - { - case SDL_QUIT: - exitFlag = true; - break; - - case SDL_KEYDOWN: - switch (event.key.keysym.sym) - { - case SDLK_ESCAPE: - case SDLK_q: - exitFlag = true; - break; - } - } - - // Render the next frame - dmDrawScene(scene); - - // Draw the current frame - SDL_GL_SwapWindow(dmWindow); - - // Rotate for 2 degrees - glRotatef(2.0f, 0, 1, 0); - - // Return true if a full rotation was done - totalFrames++; - if (cycleFrames++ == SET_FRAMES) - { - // Reset cycleFrames - cycleFrames = 0; - - // Get the time it took to render a full turn - int cycleEnd = SDL_GetTicks(); - double cycleTime = cycleEnd - cycleStart; - - // Restart the timer - cycleStart = SDL_GetTicks(); - - // Print the current frames per second - printf("%.1lf ms for %d frames = %.1lf FPS\n", - 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); - - if (dmWindow != NULL) - SDL_DestroyWindow(dmWindow); - - SDL_Quit(); - - return 0; -}