Mercurial > hg > forks > gldragon
diff gldragon.cpp @ 62:baccf2044289
Move the OpenGL rendering, setup etc. into a separate module/class, perhaps
facilitating other types of renderers in future .. maybe.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 14 Dec 2019 16:39:20 +0200 |
parents | 7b138613e2fc |
children | d6ffc59bb84d |
line wrap: on
line diff
--- a/gldragon.cpp Sat Dec 14 14:08:51 2019 +0200 +++ b/gldragon.cpp Sat Dec 14 16:39:20 2019 +0200 @@ -8,11 +8,8 @@ // Originally based on 'glxdragon' Copyright (c) 2009, Thomas Trummer // #include <SDL.h> -#include <SDL_opengl.h> -#include <GL/glu.h> - #include "dmutil.h" -#include "dmscene.h" +#include "dmglrender.h" /* Default settings etc. constants @@ -34,96 +31,11 @@ /* Globals */ SDL_Window *dmWindow = NULL; -SDL_GLContext dmGLContext = NULL; /* Helpers */ -bool dmGLCheckErrors(void) -{ - bool ok = true; - GLenum err; - while ((err = glGetError()) != GL_NO_ERROR) - { - dmError("OpenGL error code: 0x%x (%d)\n", err); - ok = false; - } - return ok; -} - - -#ifdef GL_GLEXT_PROTOTYPES -#define DM_GLEXT_INIT(extproctype, extprocname) /* stub */ -#else -#define DM_GLEXT_INIT(extproctype, extprocname) extproctype extprocname = NULL; -#include "dmglexts.h" -#undef DM_GLEXT_INIT - - -void dmGLCheckExtension(const std::string &name, bool &status) -{ - if (!SDL_GL_ExtensionSupported(name.c_str())) - { - status = false; - dmMsg(" - '%s' NOT supported.\n", - name.c_str()); - } -} - - -void * dmGLGetProcAddr(const std::string &name) -{ - void *ptr = SDL_GL_GetProcAddress(name.c_str()); - - if (ptr == NULL) - dmMsg(" - '%s' NOT supported.\n"); - - return ptr; -} - - -void * dmGLExtInit(const std::string &name, bool &status) -{ - void *ptr; - bool ok = - (ptr = dmGLGetProcAddr(name)) != NULL || - (ptr = dmGLGetProcAddr(name + "EXT")) != NULL || - (ptr = dmGLGetProcAddr(name + "ARB")) != NULL; - - if (!ok) - status = false; - - return ptr; -} -#endif - - -bool dmInitGLExtensions(void) -{ - bool status = true; - dmMsg("Checking for required OpenGL extensions ..\n"); - -#ifndef GL_GLEXT_PROTOTYPES - dmGLCheckExtension("GL_ARB_shader_objects", status); - dmGLCheckExtension("GL_ARB_shading_language_100", status); - dmGLCheckExtension("GL_ARB_vertex_shader", status); - dmGLCheckExtension("GL_ARB_fragment_shader", status); - if (!status) - { - dmError("One or more of the required OpenGL extensions not supported.\n"); - return false; - } - -#define DM_GLEXT_INIT(extproctype, extprocname) \ - extprocname = (extproctype) dmGLExtInit(#extprocname, status); -#include "dmglexts.h" -#endif - - return status; -} - - -bool dmInitSDLGL(const int width, const int height, const char *title) +bool dmInitSDL(DMSimpleRenderer &renderer, const int width, const int height, const char *title) { int ret; std::string msg; @@ -136,19 +48,9 @@ return false; } - // 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_RED_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); - SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8); - - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - //SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + // Part 1 of initialization + if (!renderer.initRender1()) + return false; // Attempt to create a window if ((dmWindow = SDL_CreateWindow(title, @@ -161,12 +63,10 @@ return false; } - if ((dmGLContext = SDL_GL_CreateContext(dmWindow)) == NULL) - { - dmError("Unable to create SDL OpenGL context: %s\n", - SDL_GetError()); + // Part 2 of initialization + if (!renderer.initRender2(dmWindow)) return false; - } + // Check if we want to attempt to use vsync switch (optVSyncMode) @@ -204,211 +104,13 @@ return false; } - // Get/initialize OpenGL extension function pointers - if (optUseShaders && !dmInitGLExtensions()) - return false; - - // Dump some information - dmMsg("GL_VENDOR : %s\n", glGetString(GL_VENDOR)); - dmMsg("GL_RENDERER : %s\n", glGetString(GL_RENDERER)); - dmMsg("GL_VERSION : %s\n", glGetString(GL_VERSION)); - dmMsg("VSync mode : %s\n", msg.c_str()); - - if (!dmGLCheckErrors()) + // Part 3 of initialization + if (!renderer.initRender3(width, height)) return false; - // 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); - - glEnable(GL_COLOR_MATERIAL); - - // 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 dmGLCheckErrors(); -} - - -void dmDrawModel(const DMSimpleScene &scene, const DMModel &model) -{ - int maxIndices; - - if (optUseShaders) - { - // Enable shader program - glUseProgram(model.id_prog); - glUniform1i(glGetUniformLocation(model.id_prog, "nlights"), scene.lights.size()); - } - - // Set the material of the model - glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); - glMateriali(GL_FRONT, GL_SHININESS, model.material.shininess); - glMaterialfv(GL_FRONT, GL_SPECULAR, model.material.specular.values); - glColor4fv(model.material.diffuse.values); - - // Render the model - glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices); - - // Add transforms - if (model.scaleSet) - glScalef(model.scale.x, model.scale.y, model.scale.z); - - if (model.translateSet) - glTranslatef(model.translate.x, model.translate.y, model.translate.z); - - if (model.rotateSet) - { - 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]); - } - - // Restore - if (optUseShaders) - { - glUseProgram(0); - } -} - + dmMsg("VSync mode : %s\n", msg.c_str()); -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); - glEnable(GL_LIGHTING); - - // Draw models - for (const DMModel &model : scene.models) - { - glPushMatrix(); - dmDrawModel(scene, model); - glPopMatrix(); - } -} - - -bool dmCompileShader(const GLenum stype, const std::string &src, GLuint &shader) -{ - GLint status; - const char *tmp = src.c_str(); - - shader = glCreateShader(stype); - glShaderSource(shader, 1, &tmp, 0); - glCompileShader(shader); - - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if (status == GL_TRUE) - return true; - else - { - GLint bufLen = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &bufLen); - - if (bufLen > 0) - { - char *buf = new char[bufLen]; - glGetShaderInfoLog(shader, bufLen, NULL, buf); - dmError("Shader compilation error:\n%s\n", - buf); - delete[] buf; - } - else - { - dmError("Shader compilation error occured, but no error information got.\n"); - } - return false; - } -} - - -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); -} - - -void dmSetupLight(const int n, const DMLight &light) -{ - glEnable(GL_LIGHT0 + n); - glLightfv(GL_LIGHT0 + n, GL_AMBIENT, light.color.ambient.values); - glLightfv(GL_LIGHT0 + n, GL_DIFFUSE, light.color.diffuse.values); - glLightfv(GL_LIGHT0 + n, GL_SPECULAR, light.color.specular.values); - glLightfv(GL_LIGHT0 + n, GL_POSITION, light.position.values); + return true; } @@ -421,6 +123,7 @@ optShowHelp = false, optSetInputFilename = false; std::string optInputFilename = "dragon.scene", basePath; + DMGLSimpleRenderer renderer; DMSimpleScene scene; // Check commandline argument for enabling shaders @@ -559,30 +262,20 @@ } } + // Set shader usage + renderer.useShaders = optUseShaders; + // Initialize SDL + OpenGL - if (!dmInitSDLGL(optWidth, optHeight, "GLDragon")) + if (!dmInitSDL(renderer, optWidth, optHeight, "GLDragon")) goto exit; - // According to our mode .. - if (optUseShaders) - { - for (DMModel &model : scene.models) - { - if (!dmCompileShader(GL_FRAGMENT_SHADER, model.fragShaderStr, model.id_fs) || - !dmCompileShader(GL_VERTEX_SHADER, model.vertShaderStr, model.id_vs)) - goto exit; + // Compile shaders for scene + if (!renderer.compileSceneShaders(scene)) + goto exit; - dmLinkModelShaders(model); - } - } - - // Setup lights - for (size_t n = 0; n < scene.lights.size(); n++) - dmSetupLight(n, scene.lights[n]); - - // Define the camera - gluLookAt(0, 0.12, 0.24, 0, 0.12, 0, 0, 1, 0); - + // Setup lights and camera + renderer.setupLights(scene); + renderer.setupCamera(scene.camera); // Main loop starts startTime = cycleStart = SDL_GetTicks(); @@ -610,16 +303,17 @@ } // Render the next frame - dmDrawScene(scene); + totalTime = SDL_GetTicks() - startTime; + renderer.drawScene(scene, totalTime); // Draw the current frame SDL_GL_SwapWindow(dmWindow); // Rotate for 2 degrees - glRotatef(2.0f, 0, 1, 0); + renderer.animate(scene, totalTime); // Check for errors - dmGLCheckErrors(); + renderer.checkErrors(); // Return true if a full rotation was done totalFrames++; @@ -647,8 +341,7 @@ totalTime, totalFrames, (totalFrames * 1000.0f) / totalTime); exit: - if (dmGLContext != NULL) - SDL_GL_DeleteContext(dmGLContext); + renderer.shutdownRenderer(); if (dmWindow != NULL) SDL_DestroyWindow(dmWindow);