Implemented desktop_size discovery in GLRenderer
[supertux.git] / src / video / gl / gl_renderer.cpp
index 2f1f505..950ee40 100644 (file)
@@ -1,5 +1,6 @@
 //  SuperTux
 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
+//     Updated by GiBy 2013 for SDL2 <giby_the_kid@yahoo.fr>
 //
 //  This program is free software: you can redistribute it and/or modify
 //  it under the terms of the GNU General Public License as published by
@@ -19,6 +20,7 @@
 #include <iomanip>
 #include <iostream>
 #include <physfs.h>
+#include "SDL.h"
 
 #include "supertux/gameconfig.hpp"
 #include "supertux/globals.hpp"
@@ -32,6 +34,7 @@
 #endif
 
 GLRenderer::GLRenderer() :
+  window(),
   desktop_size(-1, -1),
   screen_size(-1, -1),
   fullscreen_active(false),
@@ -39,30 +42,27 @@ GLRenderer::GLRenderer() :
 {
   Renderer::instance_ = this;
 
-#if SDL_MAJOR_VERSION > 1 || SDL_MINOR_VERSION > 2 || (SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 10)
-  // unfortunately only newer SDLs have these infos.
-  // This must be called before SDL_SetVideoMode() or it will return
-  // the window size instead of the desktop size.
-  const SDL_VideoInfo *info = SDL_GetVideoInfo();
-  if (info)
-  {
-    desktop_size = Size(info->current_w, info->current_h);
-  }
-#endif
+  SDL_DisplayMode mode;
+  SDL_GetCurrentDisplayMode(0, &mode);
+  desktop_size = Size(mode.w, mode.h);
 
   if(texture_manager != 0)
     texture_manager->save_textures();
 
-#ifdef SDL_GL_SWAP_CONTROL
-  if(config->try_vsync) {
+  if(g_config->try_vsync) {
     /* we want vsync for smooth scrolling */
-    SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
+    if (SDL_GL_SetSwapInterval(-1) != 0)
+    {
+      log_info << "no support for late swap tearing vsync: " << SDL_GetError() << std::endl;
+      if (SDL_GL_SetSwapInterval(1))
+      {
+        log_info << "no support for vsync: " << SDL_GetError() << std::endl;
+      }
+    }
   }
-#endif
 
   SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 
-  // FIXME: Hu? 16bit rendering?
   SDL_GL_SetAttribute(SDL_GL_RED_SIZE,   5);
   SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
   SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,  5);
@@ -108,14 +108,28 @@ GLRenderer::GLRenderer() :
 
 GLRenderer::~GLRenderer()
 {
+  SDL_GL_DeleteContext(glcontext);
+  SDL_DestroyWindow(window);
 }
 
 void
 GLRenderer::draw_surface(const DrawingRequest& request)
 {
   const Surface* surface = (const Surface*) request.request_data;
+  if(surface == NULL)
+  {
+    return;
+  }
   GLTexture* gltexture = static_cast<GLTexture*>(surface->get_texture().get());
+  if(gltexture == NULL)
+  {
+    return;
+  }
   GLSurfaceData *surface_data = static_cast<GLSurfaceData*>(surface->get_surface_data());
+  if(surface_data == NULL)
+  {
+    return;
+  }
 
   GLuint th = gltexture->get_handle();
   if (th != last_texture) {
@@ -186,9 +200,9 @@ GLRenderer::draw_gradient(const DrawingRequest& request)
 
   float vertices[] = {
     0, 0,
-    SCREEN_WIDTH, 0,
-    SCREEN_WIDTH, SCREEN_HEIGHT,
-    0, SCREEN_HEIGHT
+    float(SCREEN_WIDTH), 0,
+    float(SCREEN_WIDTH), float(SCREEN_HEIGHT),
+    0, float(SCREEN_HEIGHT)
   };
   glVertexPointer(2, GL_FLOAT, 0, vertices);
 
@@ -442,18 +456,17 @@ void
 GLRenderer::flip()
 {
   assert_gl("drawing");
-  SDL_GL_SwapBuffers();
+  SDL_GL_SwapWindow(window);
 }
 
 void
 GLRenderer::resize(int w, int h)
 {
-  // This causes the screen to go black, which is annoying, but seems
-  // unavoidable with SDL at the moment
-  SDL_SetVideoMode(w, h, 0, SDL_OPENGL | SDL_RESIZABLE);
-
   g_config->window_size = Size(w, h);
 
+  PHYSICAL_SCREEN_WIDTH = w;
+  PHYSICAL_SCREEN_HEIGHT = h;
+
   apply_config();
 }
 
@@ -559,9 +572,9 @@ GLRenderer::apply_config()
 
     // Clear both buffers so that we get a clean black border without junk
     glClear(GL_COLOR_BUFFER_BIT);
-    SDL_GL_SwapBuffers();
+    SDL_GL_SwapWindow(window);
     glClear(GL_COLOR_BUFFER_BIT);
-    SDL_GL_SwapBuffers();
+    SDL_GL_SwapWindow(window);
 
     glViewport(std::max(0, (screen_size.width  - new_size.width)  / 2),
                std::max(0, (screen_size.height - new_size.height) / 2),
@@ -583,32 +596,87 @@ GLRenderer::apply_config()
 void
 GLRenderer::apply_video_mode(const Size& size, bool fullscreen)
 {
-  // Only change video mode when its different from the current one
-  if (screen_size != size || fullscreen_active != fullscreen)
+  if (window)
   {
-    int flags = SDL_OPENGL;
+    SDL_SetWindowSize(window, size.width, size.height);
 
     if (fullscreen)
     {
-      flags |= SDL_FULLSCREEN;
+      int fullscreen_flags = SDL_WINDOW_FULLSCREEN; // SDL_WINDOW_FULLSCREEN_DESKTOP or 0
+      SDL_SetWindowDisplayMode(window, NULL);
+
+      SDL_DisplayMode mode;
+      mode.format = SDL_PIXELFORMAT_RGB888;
+      mode.w = g_config->fullscreen_size.width;
+      mode.h = g_config->fullscreen_size.height;
+      mode.refresh_rate = g_config->fullscreen_refresh_rate;
+      mode.driverdata = 0;
+
+      if (SDL_SetWindowDisplayMode(window, &mode) != 0)
+      {
+        log_warning << "failed to set display mode: "
+                    << mode.w << "x" << mode.h << "@" << mode.refresh_rate << ": "
+                    << SDL_GetError() << std::endl;
+      }
+      else
+      {
+        SDL_SetWindowFullscreen(window, fullscreen_flags);
+      }
     }
     else
     {
-      flags |= SDL_RESIZABLE;
+      SDL_SetWindowFullscreen(window, 0);
     }
-
-    if (SDL_Surface *screen = SDL_SetVideoMode(size.width, size.height, 0, flags))
-    {
-      screen_size = Size(screen->w, screen->h);
-      fullscreen_active = fullscreen; 
-    }
-    else
+  }
+  else
+  {
+    // Only change video mode when its different from the current one
+    if (screen_size != size || fullscreen_active != fullscreen)
     {
-      std::ostringstream msg;
-      msg << "Couldn't set video mode " << size.width << "x" << size.height << ": " << SDL_GetError();
-      throw std::runtime_error(msg.str());
+      int flags = SDL_WINDOW_OPENGL;
+
+      if (fullscreen)
+      {
+        flags |= SDL_WINDOW_FULLSCREEN;
+      }
+      else
+      {
+        flags |= SDL_WINDOW_RESIZABLE;
+      }
+
+      window = SDL_CreateWindow("SuperTux",
+                                SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
+                                size.width, size.height,
+                                flags);
+      if (!window)
+      {
+        std::ostringstream msg;
+        msg << "Couldn't set video mode " << size.width << "x" << size.height << ": " << SDL_GetError();
+        throw std::runtime_error(msg.str());
+      }
+      else
+      {
+        glcontext = SDL_GL_CreateContext(window);
+        screen_size = size;
+        
+        PHYSICAL_SCREEN_WIDTH = size.width;
+        PHYSICAL_SCREEN_HEIGHT = size.height;
+
+        SCREEN_WIDTH = size.width;
+        SCREEN_HEIGHT = size.height;
+        
+        fullscreen_active = fullscreen;
+      }
     }
   }
 }
 
+void
+GLRenderer::set_gamma(float gamma)
+{
+  Uint16 ramp[256];
+  SDL_CalculateGammaRamp(gamma, ramp);
+  SDL_SetWindowGammaRamp(window, ramp, ramp, ramp);
+}
+
 /* EOF */