#include #include #include #include #include #include #include // only include this one in the source file with main()! #include "opengl.h" #define INITIAL_FPS 60 static double FPS = INITIAL_FPS; static double FrameTime = 1.0 / INITIAL_FPS; static double PerformancePeriod; static double GetTime( void ) { return PerformancePeriod * SDL_GetPerformanceCounter(); } static void SetTitle ( SDL_Window *window ) { char title[48] = {0}; SDL_snprintf(title, sizeof(title), "Hello Triangles! Framelimit: %6.3f Hz", FPS); SDL_SetWindowTitle(window, title); } int main( int argc, char* argv[] ) { _glWindows_t glW; const int WIDTH = 640; const int HEIGHT = 480; int delayThreshold = 2; int r, g, b, alpha_s, depth_s, stencil_s, dbuffer, glVersionMa, glVersionMi, glAccel, glProfile = 0; double sleepTime = 0; double timeCounter = 0; bool loopShouldStop = false; SDL_SetHint(SDL_HINT_RENDER_VSYNC, 0); if (!SDL_Init(SDL_INIT_VIDEO)) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_Init failed: %s", SDL_GetError()); exit(EXIT_FAILURE); } if (!SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY)) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "Set atrribute SDL_GL_CONTEXT_PROFILE_MASK: %s", SDL_GetError()); exit(EXIT_FAILURE); } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); 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_ALPHA_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); PerformancePeriod = 1.0 / SDL_GetPerformanceFrequency(); timeCounter = GetTime(); glW.window = SDL_CreateWindow("Hello SDL", WIDTH, HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE); if (!glW.window) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_CreateWindow: %s", SDL_GetError()); exit(EXIT_FAILURE); } glW.glcontext = SDL_GL_CreateContext(glW.window); if (!glW.glcontext) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_GL_CreateContext: %s", SDL_GetError()); exit(EXIT_FAILURE); } SetTitle(glW.window); SDL_HideCursor(); glewExperimental = GL_TRUE; GLenum err = glewInit(); if (err != GLEW_OK) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "glewInit: %s", glewGetErrorString(err)); exit(EXIT_FAILURE); } SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &glProfile); SDL_GL_GetAttribute(SDL_GL_ACCELERATED_VISUAL, &glAccel); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &glVersionMa); SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &glVersionMi); SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &r); SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &g); SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &b); SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &alpha_s); SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &depth_s); SDL_GL_GetAttribute(SDL_GL_STENCIL_SIZE, &stencil_s); SDL_GL_GetAttribute(SDL_GL_DOUBLEBUFFER, &dbuffer); SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "OpenGL Version: %d.%d, OpenGL Accelerated: %d, OpenGL Profile Mask: %d", glVersionMa, glVersionMi, glAccel, glProfile); SDL_LogVerbose(SDL_LOG_CATEGORY_RENDER, "Red size: %d, Green size: %d, Blue size: %d, Alpha size: %d, Depth size: %d, Stencil size: %d, DoubleBuffer: %d", r, g, b, alpha_s, depth_s, stencil_s, dbuffer); SDL_GL_SetSwapInterval(0); startShaderProg(); while (!loopShouldStop) { SDL_Event e; SDL_zero(e); while (SDL_PollEvent(&e)) { if (e.type == SDL_EVENT_QUIT) loopShouldStop = true; else if (e.type == SDL_EVENT_WINDOW_RESIZED) { resizeWindow(e.window.data1, e.window.data2); } else if (e.type == SDL_EVENT_KEY_DOWN) { if (e.key.key == SDLK_X) { FPS -= 0.1; if (FPS < 1) { FPS = 1; } FrameTime = 1.0 / FPS; SetTitle(glW.window); } else if (e.key.key == SDLK_C) { FPS += 0.1; FrameTime = 1.0 / FPS; SetTitle(glW.window); } if (e.key.key == SDLK_ESCAPE) loopShouldStop = true; } } _GLBuffer(); if (!SDL_GL_SwapWindow(glW.window)) { SDL_LogCritical(SDL_LOG_CATEGORY_ASSERT, "SDL_GL_SwapWwindow: %s", SDL_GetError()); exit(EXIT_FAILURE); } sleepTime = timeCounter - GetTime(); if (sleepTime * 1000 > delayThreshold) { Uint32 ms = (Uint32)(sleepTime * 1000) - delayThreshold; SDL_Delay(ms); if (timeCounter < GetTime()) { delayThreshold++; SDL_Log("Slept too long. Increased threshold to %u ms", delayThreshold); } } while (timeCounter > GetTime()) { /* Waiting for the right moment. */ } timeCounter += FrameTime; } SDL_DestroyWindow(glW.window); SDL_GL_DestroyContext(glW.glcontext); SDL_Quit(); exit(EXIT_SUCCESS); }