# HG changeset patch # User Matti Hamalainen # Date 1572191857 -7200 # Node ID be31ff9e5f5879860f881d31fa586d7efbeca5c2 # Parent b45d8958e5a60b2a5aba9acc2787b7b663d424ab Port to libSDL2, clean up the code and some de-C++-ifications. diff -r b45d8958e5a6 -r be31ff9e5f58 Makefile --- a/Makefile Sun Oct 27 17:27:55 2019 +0200 +++ b/Makefile Sun Oct 27 17:57:37 2019 +0200 @@ -1,11 +1,14 @@ +BINEXT = -CC = g++ -CFLAGS = -O2 -Wall -I/usr/include/SDL -LDFLAGS = -lSDL -lGL -lGLU +CFLAGS = -O3 -W -Wall $(shell pkg-config --cflags sdl2 gl glu) +LDFLAGS = $(shell pkg-config --libs sdl2 gl glu) -glxdragon: glxdragon.cpp - $(CC) $(CFLAGS) -o glxdragon glxdragon.cpp $(LDFLAGS) +TARGETS = glxdragon$(BINEXT) + +glxdragon$(BINEXT): glxdragon.cpp + $(CXX) $(CFLAGS) -o $@ $< $(LDFLAGS) clean: - rm glxdragon + $(RM) $(TARGETS) + diff -r b45d8958e5a6 -r be31ff9e5f58 glxdragon.cpp --- a/glxdragon.cpp Sun Oct 27 17:27:55 2019 +0200 +++ b/glxdragon.cpp Sun Oct 27 17:57:37 2019 +0200 @@ -1,7 +1,10 @@ - +// // Copyright (c) 2009, Thomas Trummer // All rights reserved. // +// Port to libSDL2 and cleanups by Matti Hämäläinen +// (C) Copyright 2019 Tecnic Software productions (TNSP) +// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // * Redistributions of source code must retain the above copyright @@ -23,10 +26,11 @@ // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - +// #include #include +#include #include #include @@ -39,59 +43,67 @@ #include -struct Mesh -{ - std::vector vertices; - std::vector faces; -} -dragonMesh; +#define SET_FRAMES (180 * 2) + + +SDL_Window *s_window = NULL; +SDL_GLContext s_context; -void init(const int windowWidth, const int windowHeight, const std::string& windowTitle) +struct Mesh { - std::stringstream ss; + std::vector vertices; + std::vector faces; +}; - if (SDL_Init(SDL_INIT_VIDEO) != 0) - { - ss << "Unable to initialize SDL: " << SDL_GetError() << '\n'; - - throw std::runtime_error(ss.str()); - } - - +bool init(const int width, const int height, const char *title) +{ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - SDL_WM_SetCaption(windowTitle.c_str(), 0); - + 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; + } - if ((SDL_SetVideoMode(windowWidth, windowHeight, 0, SDL_OPENGL)) == NULL) + if ((s_window = SDL_CreateWindow(title, + SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + width, height, + SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE)) == NULL) { - ss << "Couldn't set GL mode: " << SDL_GetError() << '\n'; - - throw std::runtime_error(ss.str()); + printf("ERROR: Could not create SDL window: %s", + SDL_GetError()); + return false; } + if ((s_context = SDL_GL_CreateContext(s_window)) == NULL) + { + printf("ERROR: Unable to create SDL OpenGL context: %s\n", + SDL_GetError()); + return false; + } - std::cout << "GL_VENDOR : " << glGetString(GL_VENDOR) << std::endl; - std::cout << "GL_RENDERER : " << glGetString(GL_RENDERER) << std::endl; - std::cout << "GL_VERSION : " << glGetString(GL_VERSION) << std::endl; - - std::cout << std::endl; - + printf( + "GL_VENDOR : %s\n" + "GL_RENDERER : %s\n" + "GL_VERSION : %s\n", + glGetString(GL_VENDOR), + glGetString(GL_RENDERER), + glGetString(GL_VERSION)); // Setup the window and view port - glViewport(0, 0, windowWidth, windowHeight); + glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); - gluPerspective(45.0f, GLfloat(windowWidth) / GLfloat(windowHeight), 0.1f, 1000.0f); + gluPerspective(45.0f, GLfloat(width) / GLfloat(height), 0.1f, 1000.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -118,6 +130,8 @@ // Set correct perspective correction glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + return true; } @@ -153,6 +167,9 @@ void done() { + SDL_GL_DeleteContext(s_context); + SDL_DestroyWindow(s_window); + s_window = NULL; SDL_Quit(); } @@ -163,25 +180,21 @@ glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &maxIndices); - glVertexPointer(3, GL_FLOAT, 24, &mesh.vertices[0]); glNormalPointer(GL_FLOAT, 24, &mesh.vertices[3]); - for (size_t n = 0; n < mesh.faces.size() / 3; n += maxIndices) { const int count = std::min(maxIndices, int(mesh.faces.size() / 3 - n)); - - glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_INT, &dragonMesh.faces[n * 3]); + glDrawElements(GL_TRIANGLES, count * 3, GL_UNSIGNED_INT, &mesh.faces[n * 3]); } } -bool paintGL() +void paintGL(Mesh &mesh) { glClear(GL_DEPTH_BUFFER_BIT); - glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); @@ -217,89 +230,39 @@ glMatrixMode(GL_MODELVIEW); glPopMatrix(); + glEnable(GL_DEPTH_TEST); - glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); - - // Set the color of the model glColor3ub(0x90, 0x80, 0x90); - // Draw the model using vertex arrays - drawModelVA(dragonMesh); - - // Draw the current frame - SDL_GL_SwapBuffers(); - static int steps = 0; - - // Rotate for 2 degrees - glRotatef(2.0f, 0, 1, 0); - - // Return true if a full rotation was done - return (steps++ == 180) ? (steps = 0, true) : false; + // Draw the model using vertex arrays + drawModelVA(mesh); } -void runEventLoop() +void loadMesh(const std::string& filename, Mesh& mesh, size_t nvertices, size_t nfaces) { - static std::clock_t startTime = std::clock(); - - while (true) - { - SDL_Event event; - - if (SDL_PollEvent(&event)) - { - if (event.type == SDL_QUIT) - break; - } - else - { - // Render the next frame and test if a full turn was completed - if (paintGL()) - { - // Get the time it took to render a full turn - double time = double(std::clock() - startTime) / CLOCKS_PER_SEC; - - // Print the current frames per second - std::printf("%.1lf seconds for 180 frames = %.1lf FPS\n", time, 180 / time); - - // Restart the timer - startTime = std::clock(); - } - } - } -} - - -void loadMesh(const std::string& fileName, Mesh& mesh) -{ - std::ifstream in(fileName.c_str(), std::ios::binary); - + std::ifstream in(filename.c_str(), std::ios::binary); if (!in.is_open()) { std::stringstream ss; - - ss << "Unable to open file: " << fileName << '\n'; - + ss << "Unable to open file: " << filename << '\n'; throw std::runtime_error(ss.str()); - } - - mesh.vertices.resize(100139 * 6); - in.read(reinterpret_cast(&mesh.vertices[0]), 100139 * 6 * 4); + mesh.vertices.resize(nvertices * 6); + in.read(reinterpret_cast(&mesh.vertices[0]), nvertices * 6 * 4); + mesh.faces.resize(nfaces * 3); - mesh.faces.resize(200198 * 3); - for (unsigned i = 0; i < 200198; i++) + for (size_t i = 0; i < nfaces; i++) { in.seekg(1, std::ios::cur); - in.read(reinterpret_cast(&mesh.faces[i * 3]), 3 * 4); } } @@ -309,18 +272,72 @@ { try { - loadMesh("dragon.mesh", dragonMesh); + struct Mesh dragonMesh; + loadMesh("dragon.mesh", dragonMesh, 100139, 200198); - init(640, 480, "glxdragon"); + //if (!init(640, 480, "glxdragon")) + if (!init(1280, 960, "glxdragon")) + throw std::runtime_error("Fatal error."); initScene(); - runEventLoop(); + bool exitFlag = false; + int steps = 0; + std::clock_t startTime = std::clock(); + + 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 + paintGL(dragonMesh); + + // Draw the current frame + SDL_GL_SwapWindow(s_window); + + // Rotate for 2 degrees + glRotatef(2.0f, 0, 1, 0); + + // Return true if a full rotation was done + if (steps++ == SET_FRAMES) + { + // Reset steps + steps = 0; + + // Get the time it took to render a full turn + double time = (double(std::clock() - startTime) * 1000.0f) / CLOCKS_PER_SEC; + + // Print the current frames per second + std::printf("%.1lf ms for %d frames = %.1lf FPS\n", + time, SET_FRAMES, (SET_FRAMES * 1000.0f) / time); + + // Restart the timer + startTime = std::clock(); + } + } } catch(std::runtime_error & e) { std::cerr << e.what(); } - done(); }