From 72c0188ec37c3783133baf6960d72cb3c9d12a6c Mon Sep 17 00:00:00 2001
From: Piotr Dziwinski <piotrdz@gmail.com>
Date: Sat, 28 Jul 2012 23:36:12 +0200
Subject: [PATCH] GLEW

Added GLEW for loading OpenGL extensions
---
 CMakeLists.txt                   | 20 +++++++++----
 HOWTO.txt                        | 26 ++++++++++++----
 cmake/FindGLEW.cmake             | 51 ++++++++++++++++++++++++++++++++
 src/CMakeLists.txt               | 24 +++++++++++++++
 src/common/config.h.cmake        |  2 ++
 src/graphics/opengl/gldevice.cpp | 36 ++++++++++++++++++----
 6 files changed, 144 insertions(+), 15 deletions(-)
 create mode 100644 cmake/FindGLEW.cmake

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82a6e80f..092a8127 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,12 +5,19 @@ cmake_minimum_required(VERSION 2.8)
 project(colobot C CXX)
 
 # Required packages
-find_package(OpenGL REQUIRED)
-find_package(SDL REQUIRED)
-find_package(SDL_image REQUIRED)
-find_package(PNG REQUIRED)
+find_package(OpenGL 1.4 REQUIRED)
+find_package(SDL 1.2.10 REQUIRED)
+find_package(SDL_image 1.2 REQUIRED)
+find_package(PNG 1.2 REQUIRED)
 
-# TODO: check for SDL version. Should be >= 1.2.10
+# GLEW requirement depends on platform
+# By default it is auto detected
+# This setting may be used to override
+# Possible values:
+# - auto -> determine automatically
+# - 1 -> always enable
+# - 0 -> always disable
+set(USE_GLEW auto)
 
 # Build with debugging symbols
 set(CMAKE_BUILD_TYPE debug)
@@ -19,5 +26,8 @@ set(CMAKE_BUILD_TYPE debug)
 set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wall -std=gnu++0x")
 set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -std=gnu++0x")
 
+# Include cmake directory
+SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${colobot_SOURCE_DIR}/cmake")
+
 # Subdirectory with sources
 add_subdirectory(src bin)
diff --git a/HOWTO.txt b/HOWTO.txt
index f93bb0e4..4c17234f 100644
--- a/HOWTO.txt
+++ b/HOWTO.txt
@@ -13,16 +13,19 @@ How to...
       http://www.cmake.org/cmake/resources/software.html (the Windows zip file)
      Unpack the contents of the archive to where MinGW is installed (files from bin/ should go into bin/, etc.)
   3. Download the following libraries, installing them in your MinGW directory like with CMake:
-     SDL, SDL_imgage, SDL_ttf, libpng
+     SDL >=1.2.10, SDL_imgage >= 1.2, SDL_ttf >= 2.0, libpng >= 1.2, GLEW >= 1.8.0
+     Note #1: For most libraries, you can download binary packages with compiled files.
+              However, you must ensure that they work with MinGW as some are built with MSVC
+              and may be incompatible. If that is the case, you should compile the libraries from sources
+              using MinGW.
+     Note #2: For GLEW, you need to compile from source under MinGW. Since there is no automated
+              make script for that, follow the instructions here: http://stackoverflow.com/questions/6005076/
   4. Run MinGW console from the shortcut in menu start.
   5. Change to the directory where you have the Colobot sources by typing "cd /c/where/the/sources/are"
   6. Type "cmake -G 'MSYS Makefiles' ."
   7. Type "make"
   8. Everything should compile without errors.
 
-  Note: you might experience some troubles with OpenGL headers, as Windows (used to?) ship with outdated header files.
-  Download the newest ones from SDK of your graphics card vendor.
-
  1.2 Linux:
 
   Since you're running Linux, you probably know how to do this anyway ;)
@@ -32,6 +35,9 @@ How to...
     $ cmake .
     $ make
 
+  Note: If you experience problems with OpenGL's extensions, install GLEW library and enable
+        it in compilation by setting USE_GLEW to 1 in CMakeLists.txt
+
  1.3 Other platforms, compilers, etc.
 
    We haven't checked other platforms yet but the code isn't particularly tied to any compiler or platform, so in theory it should work.
@@ -60,7 +66,14 @@ Jak...
      http://www.cmake.org/cmake/resources/software.html (plik zip dla Windowsa)
      Zip rozpakowujemy do katalogu, gdzie zainstalowany jest MinGW (pliki z bin/ mają trafić do bin/ itd.).
   3. Ścągamy następujące biblioteki i instalujemy je tam, gdzie MinGW, podobnie jak z CMake:
-     SDL, SDL_image, SDL_ttf, libpng
+     SDL >= 1.2.10, SDL_image >= 1.2, SDL_ttf >= 2.0, libpng >= 1.2
+     Uwaga #1: W większości wymienionych bibliotek można ściągnąć paczki binarne ze skompilowanymi plikami.
+               Jednak musisz się upewnić, że pliki te będą współpracowały z MinGW, bo część z nich
+               jest kompilowana MSVC i może być niezgodna. W takim wypadku, musisz skompilować bibliotekę
+               ze źródeł pod MinGW.
+
+     Uwaga #2: W przypadku GLEW, musisz skompilować bibiotekę ze źródeł pod MinGW. Ponieważ nie ma skryptu
+               make do tego, użyj poleceń opisanych tutaj: http://stackoverflow.com/questions/6005076/
   4. Uruchamiamy MinGW console ze skrótu w menu start.
   5. Przechodzimy do katalogu, gdzie są źródła wpisując "cd /c/tam/gdzie/sa/zrodla"
   6. Wpisujemy "cmake -G 'MSYS Makefiles' ."
@@ -76,6 +89,9 @@ Jak...
     $ cmake .
     $ make
 
+  Uwaga: Jeśli natrafisz na problemy z rozszerzeniami OpenGL, zainstaluj bibliotekę GLEW i włącz ją
+         przy kompilacji, ustawiając USE_GLEW na 1 w CMakeLists.txt
+
  1.3 Inne platformy, kompilatory, etc.
 
    Nie sprawdzaliśmy jeszcze innych platform, ale kod nie jest jakoś specjalnie związany z danym kompilatorem czy platformą, więc w teorii powinien zadziałać.
diff --git a/cmake/FindGLEW.cmake b/cmake/FindGLEW.cmake
new file mode 100644
index 00000000..94c9b327
--- /dev/null
+++ b/cmake/FindGLEW.cmake
@@ -0,0 +1,51 @@
+# CMake module to find GLEW
+# Borrowed from http://code.google.com/p/nvidia-texture-tools/
+# MIT license Copyright (c) 2007 NVIDIA Corporation
+
+# Try to find GLEW library and include path.
+# Once done this will define
+#
+# GLEW_FOUND
+# GLEW_INCLUDE_PATH
+# GLEW_LIBRARY
+#
+
+IF (WIN32)
+    FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
+    $ENV{PROGRAMFILES}/GLEW/include
+    ${PROJECT_SOURCE_DIR}/src/nvgl/glew/include
+    DOC "The directory where GL/glew.h resides")
+    FIND_LIBRARY( GLEW_LIBRARY
+    NAMES glew GLEW glew32 glew32s
+    PATHS
+    /mingw/bin # for MinGW's MSYS
+    /mingw/lib
+    ${PROJECT_SOURCE_DIR}/glew/bin # or in local directory
+    ${PROJECT_SOURCE_DIR}/glew/lib
+    DOC "The GLEW library")
+ELSE (WIN32)
+    FIND_PATH( GLEW_INCLUDE_PATH GL/glew.h
+    /usr/include
+    /usr/local/include
+    /sw/include
+    /opt/local/include
+    DOC "The directory where GL/glew.h resides")
+    FIND_LIBRARY( GLEW_LIBRARY
+    NAMES GLEW glew
+    PATHS
+    /usr/lib64
+    /usr/lib
+    /usr/local/lib64
+    /usr/local/lib
+    /sw/lib
+    /opt/local/lib
+    DOC "The GLEW library")
+ENDIF (WIN32)
+
+IF (GLEW_INCLUDE_PATH)
+    SET( GLEW_FOUND 1 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
+ELSE (GLEW_INCLUDE_PATH)
+    SET( GLEW_FOUND 0 CACHE STRING "Set to 1 if GLEW is found, 0 otherwise")
+ENDIF (GLEW_INCLUDE_PATH)
+
+MARK_AS_ADVANCED( GLEW_FOUND )
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index da8463bf..3896e402 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -11,18 +11,40 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
   set(PLATFORM_WINDOWS 1)
   set(PLATFORM_LINUX   0)
   set(PLATFORM_OTHER   0)
+  # On Windows, GLEW is required
+  if (${USE_GLEW} MATCHES "auto")
+    set(USE_GLEW 1)
+  endif()
 elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
   set(PLATFORM_WINDOWS 0)
   set(PLATFORM_LINUX   1)
   set(PLATFORM_OTHER   0)
+  # On Linux, we should be fine without GLEW
+  if (${USE_GLEW} MATCHES "auto")
+    set(USE_GLEW 0)
+  endif()
   # for clock_gettime
   set(PLATFORM_LIBS "-lrt")
 else()
   set(PLATFORM_WINDOWS 0)
   set(PLATFORM_LINUX   0)
   set(PLATFORM_OTHER   1)
+  # Use GLEW to be safe
+  if (${USE_GLEW} MATCHES "auto")
+    set(USE_GLEW 1)
+  endif()
 endif()
 
+set(OPTIONAL_LIBS "")
+set(OPTIONAL_INCLUDE_DIRS "")
+
+if(${USE_GLEW} EQUAL 1)
+  find_package(GLEW REQUIRED)
+  set(OPTIONAL_LIBS ${OPTIONAL_LIBS} ${GLEW_LIBRARY})
+  set(OPTIONAL_INCLUDE_DIRS ${OPTIONAL_INCLUDE_DIRS} ${GLEW_INCLUDE_PATH})
+endif()
+
+
 # Configure file
 configure_file(common/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/common/config.h)
 
@@ -156,6 +178,7 @@ ${SDL_LIBRARY}
 ${SDLIMAGE_LIBRARY}
 ${OPENGL_LIBRARY}
 ${PNG_LIBRARIES}
+${OPTIONAL_LIBS}
 ${PLATFORM_LIBS}
 CBot
 )
@@ -165,6 +188,7 @@ ${SDL_INCLUDE_DIR}
 ${SDL_IMAGE_INCLUDE_DIR}
 ${SDLTTF_INCLUDE_DIR}
 ${PNG_INCLUDE_DIRS}
+${OPTIONAL_INCLUDE_DIRS}
 )
 
 link_directories(${CMAKE_CURRENT_SOURCE_DIR}/CBot)
diff --git a/src/common/config.h.cmake b/src/common/config.h.cmake
index d8bff912..f496db0f 100644
--- a/src/common/config.h.cmake
+++ b/src/common/config.h.cmake
@@ -2,7 +2,9 @@
 
 // Macros set by CMake
 #cmakedefine DEBUG
+
 #cmakedefine PLATFORM_WINDOWS @PLATFORM_WINDOWS@
 #cmakedefine PLATFORM_LINUX @PLATFORM_LINUX@
 #cmakedefine PLATFORM_OTHER @PLATFORM_OTHER@
 
+#cmakedefine USE_GLEW @USE_GLEW@
diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp
index d31d007e..bfe7fd75 100644
--- a/src/graphics/opengl/gldevice.cpp
+++ b/src/graphics/opengl/gldevice.cpp
@@ -16,10 +16,20 @@
 
 // gldevice.cpp
 
-#include "common/image.h"
 #include "graphics/opengl/gldevice.h"
+
+#include "common/config.h"
+#include "common/image.h"
 #include "math/geometry.h"
 
+
+#if defined(USE_GLEW)
+
+// When using GLEW, only glew.h is needed
+#include <GL/glew.h>
+
+#else
+
 // Should define prototypes of used extensions as OpenGL functions
 #define GL_GLEXT_PROTOTYPES
 
@@ -27,9 +37,11 @@
 #include <GL/glu.h>
 #include <GL/glext.h>
 
+#endif // if defined(GLEW)
+
 #include <SDL/SDL.h>
 
-#include <assert.h>
+#include <cassert>
 
 
 
@@ -73,9 +85,23 @@ std::string Gfx::CGLDevice::GetError()
 
 bool Gfx::CGLDevice::Create()
 {
-    /* NOTE: extension testing is not done here as the assumed version of OpenGL to be used (1.4+)
-      must already have the required extensions. The used extensions are listed here for reference:
-        GL_ARB_multitexture, GL_EXT_texture_env_combine, GL_EXT_secondary_color */
+#if defined(USE_GLEW)
+    if (glewInit() != GLEW_OK)
+    {
+        m_error = "GLEW initialization failed";
+        return false;
+    }
+
+    if ( (! GLEW_ARB_multitexture) || (! GLEW_EXT_texture_env_combine) || (! GLEW_EXT_secondary_color) )
+    {
+        m_error = "GLEW reports required extensions not supported";
+        return false;
+    }
+
+#endif
+
+    /* NOTE: when not using GLEW, extension testing is not performed, as it is assumed that
+             glext.h is up-to-date and the OpenGL shared library has the required functions present. */
 
     m_wasInit = true;