diff --git a/CMakeLists.txt b/CMakeLists.txt index ca8049359..3b403ac2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,14 +251,8 @@ endif() include_directories(SYSTEM ${TinyXML_INCLUDE_DIRS}) find_package(OpenGL) -find_package(GLEW REQUIRED) -include_directories(${GLEW_INCLUDE_DIRS}) -add_definitions(${GLEW_DEFINITIONS}) -# On some platforms, GLEW declares the userParam parameter of -# GLDEBUGPROCARB as const void *, and on other platforms, it's void *. -# Test which one works here. -set(CMAKE_REQUIRED_INCLUDES "${GLEW_INCLUDE_DIRS}") -CHECK_CXX_SOURCE_COMPILES("#include \nvoid GLAPIENTRY OpenGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam) {}\nint main() { GLDEBUGPROCARB proc = &OpenGLDebugProc; }" GLDEBUGPROCARB_USERPARAM_IS_CONST) +find_package(Epoxy REQUIRED) +include_directories(${Epoxy_INCLUDE_DIRS}) if(USE_GTK AND UNIX) FINDLIB(X11_LIBRARIES X11) @@ -1096,7 +1090,7 @@ target_link_libraries(openclonk ${SDL2_LIBRARIES} ${Audio_LIBRARIES} ${GETOPT_LIBRARIES} - ${GLEW_LIBRARIES} + ${Epoxy_LIBRARIES} ${OPENGL_LIBRARIES} ${TinyXML_LIBRARIES} ${X11_LIBRARIES} diff --git a/cmake/FindEpoxy.cmake b/cmake/FindEpoxy.cmake new file mode 100644 index 000000000..3a21755f4 --- /dev/null +++ b/cmake/FindEpoxy.cmake @@ -0,0 +1,31 @@ +# OpenClonk, http://www.openclonk.org +# +# Copyright (c) 2016, The OpenClonk Team and contributors +# +# Distributed under the terms of the ISC license; see accompanying file +# "COPYING" for details. +# +# "Clonk" is a registered trademark of Matthes Bender, used with permission. +# See accompanying file "TRADEMARK" for details. +# +# To redistribute this file separately, substitute the full license texts +# for the above references. + +# Locate Epoxy. +# This module defines +# Epoxy_INCLUDE_DIRS - a list of directories that need to be added to the include path +# Epoxy_LIBRARIES - a list of libraries to link against to use Epoxy +# Epoxy_FOUND - if false, Epoxy cannot be used + +find_path(Epoxy_INCLUDE_DIR epoxy/gl.h) +mark_as_advanced(Epoxy_INCLUDE_DIR) +find_library(Epoxy_LIBRARY epoxy) +mark_as_advanced(Epoxy_LIBRARY) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(Epoxy REQUIRED_VARS Epoxy_LIBRARY Epoxy_INCLUDE_DIR) + +if (Epoxy_FOUND) + set(Epoxy_LIBRARIES "${Epoxy_LIBRARY}") + set(Epoxy_INCLUDE_DIRS "${Epoxy_INCLUDE_DIR}") +endif() diff --git a/cmake/FindGLEW.cmake b/cmake/FindGLEW.cmake deleted file mode 100644 index a897064cf..000000000 --- a/cmake/FindGLEW.cmake +++ /dev/null @@ -1,63 +0,0 @@ -# OpenClonk, http://www.openclonk.org -# -# Copyright (c) 2015, The OpenClonk Team and contributors -# -# Distributed under the terms of the ISC license; see accompanying file -# "COPYING" for details. -# -# "Clonk" is a registered trademark of Matthes Bender, used with permission. -# See accompanying file "TRADEMARK" for details. -# -# To redistribute this file separately, substitute the full license texts -# for the above references. - -# Locate GLEW. -# This module defines -# GLEW_INCLUDE_DIRS - a list of directories that need to be added to the include path -# GLEW_LIBRARIES - a list of libraries to link against to use GLEW -# GLEW_DEFINITIONS - a list of compile-time macros that need to be defined to use GLEW -# GLEW_FOUND - if false, GLEW cannot be used - -find_path(GLEW_INCLUDE_DIR GL/glew.h PATH_SUFFIXES) -mark_as_advanced(GLEW_INCLUDE_DIR) - -# Read GLEW version from header -if (GLEW_INCLUDE_DIR AND EXISTS "${GLEW_INCLUDE_DIR}/GL/glew.h") - file(STRINGS "${GLEW_INCLUDE_DIR}/GL/glew.h" glew_version_str REGEX "^VERSION .+") - string(REGEX REPLACE "^VERSION (.+)" "\\1" GLEW_VERSION_STRING "${glew_version_str}") - unset(glew_version_str) -endif() - -# On OS other than Windows, it doesn't matter whether we confuse the shared -# library and the static one. On Windows, we need to #define GLEW_STATIC if -# (and only if) we're linking against the static library. "glew32" may match -# the static library on MinGW, so we have to test for that explicitly. -find_library(GLEW_STATIC_LIBRARY glew32s) -mark_as_advanced(GLEW_STATIC_LIBRARY) -find_library(GLEW_SHARED_LIBRARY NAMES GLEW glew32) -mark_as_advanced(GLEW_SHARED_LIBRARY) - -if (GLEW_SHARED_LIBRARY) - set(GLEW_LIBRARY "${GLEW_SHARED_LIBRARY}") - if (WIN32 AND MINGW AND GLEW_SHARED_LIBRARY MATCHES "\\.a$") - # not actually a shared library - set(GLEW_DEFINITIONS "-DGLEW_STATIC") - else() - set(GLEW_DEFINITIONS) - endif() -elseif (GLEW_STATIC_LIBRARY) - set(GLEW_LIBRARY "${GLEW_STATIC_LIBRARY}") - set(GLEW_DEFINITIONS "-DGLEW_STATIC") -endif() - -include(FindPackageHandleStandardArgs) -if (NOT "${CMAKE_VERSION}" VERSION_LESS "2.8.3") - find_package_handle_standard_args(GLEW VERSION_VAR GLEW_VERSION_STRING REQUIRED_VARS GLEW_LIBRARY GLEW_INCLUDE_DIR) -else() - find_package_handle_standard_args(GLEW GLEW_LIBRARY GLEW_INCLUDE_DIR) -endif() - -if (GLEW_FOUND) - set(GLEW_LIBRARIES "${GLEW_LIBRARY}") - set(GLEW_INCLUDE_DIRS "${GLEW_INCLUDE_DIR}") -endif() diff --git a/config.h.cmake b/config.h.cmake index 7f7589dc3..7139cbe8a 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -89,10 +89,6 @@ /* MP3 music */ #cmakedefine USE_MP3 1 -/* Define to 1 if the userParam parameter to GLDEBUGPROCARB is const, as the - spec requires. */ -#cmakedefine GLDEBUGPROCARB_USERPARAM_IS_CONST 1 - /* Glib */ #cmakedefine WITH_GLIB 1 diff --git a/src/editor/C4ConsoleCocoa.mm b/src/editor/C4ConsoleCocoa.mm index 97098431d..3965f10ac 100644 --- a/src/editor/C4ConsoleCocoa.mm +++ b/src/editor/C4ConsoleCocoa.mm @@ -13,8 +13,6 @@ * for the above references. */ -#include - #include #include #include @@ -34,6 +32,8 @@ #include #include +#include + #import #import "C4AppDelegate.h" #import "C4EditorWindowController.h" diff --git a/src/editor/C4EditorWindowController.mm b/src/editor/C4EditorWindowController.mm index d555265ca..cf7035d70 100644 --- a/src/editor/C4EditorWindowController.mm +++ b/src/editor/C4EditorWindowController.mm @@ -12,8 +12,6 @@ * To redistribute this file separately, substitute the full license texts * for the above references. */ - -#include #include #include @@ -21,6 +19,8 @@ #include #include +#include + #import #import #import diff --git a/src/graphics/C4DrawGL.cpp b/src/graphics/C4DrawGL.cpp index d4bb7ef1b..8f05f5e75 100644 --- a/src/graphics/C4DrawGL.cpp +++ b/src/graphics/C4DrawGL.cpp @@ -80,13 +80,7 @@ namespace } } -#ifdef GLDEBUGPROCARB_USERPARAM_IS_CONST -#define USERPARAM_CONST const -#else -#define USERPARAM_CONST -#endif - - void GLAPIENTRY OpenGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, USERPARAM_CONST void* userParam) + void GLAPIENTRY OpenGLDebugProc(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam) { const char *msg_source = MsgSourceToStr(source); const char *msg_type = MsgTypeToStr(type); @@ -100,8 +94,6 @@ namespace } } -#undef USERPARAM_CONST - CStdGL::CStdGL(): pMainCtx(0), CurrentVBO(0), NextVAOID(VAOIDs.end()) { @@ -276,10 +268,8 @@ bool CStdGL::PrepareSpriteShader(C4Shader& shader, const char* name, int ssc, C4 void CStdGL::ObjectLabel(uint32_t identifier, uint32_t name, int32_t length, const char * label) { -#ifdef GL_KHR_debug - if (glObjectLabel) + if (has_khr_debug) glObjectLabel(identifier, name, length, label); -#endif } CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) @@ -295,16 +285,20 @@ CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) pMainCtx = pCtx; LogF(" gl: Create first %scontext...", Config.Graphics.DebugOpenGL ? "debug " : ""); } - bool success = pCtx->Init(pWindow, pApp); - if (Config.Graphics.DebugOpenGL && glDebugMessageCallbackARB) + if (!pCtx->Init(pWindow, pApp)) + { + Log(" gl: failed to create context."); + delete pCtx; + return NULL; + } + has_khr_debug = epoxy_has_gl_extension("GL_KHR_debug") || epoxy_gl_version() >= 43; + if (Config.Graphics.DebugOpenGL && (has_khr_debug || epoxy_has_gl_extension("GL_ARB_debug_output"))) { if (first_ctx) Log(" gl: Setting OpenGLDebugProc callback"); - glDebugMessageCallbackARB(&OpenGLDebugProc, nullptr); - glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); -#ifdef GL_KHR_debug - if (GLEW_KHR_debug) + glDebugMessageCallback(&OpenGLDebugProc, nullptr); + glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); + if (has_khr_debug) glEnable(GL_DEBUG_OUTPUT); -#endif } // First context: Log some information about hardware/drivers // Must log after context creation to get valid results @@ -317,7 +311,7 @@ CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) if (Config.Graphics.DebugOpenGL) { // Dump extension list - if (glGetStringi) + if (epoxy_is_desktop_gl() && epoxy_gl_version() >= 30) { GLint gl_extension_count = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &gl_extension_count); @@ -342,10 +336,6 @@ CStdGLCtx *CStdGL::CreateContext(C4Window * pWindow, C4AbstractApp *pApp) } } } - if (!success) - { - delete pCtx; Error(" gl: Error creating secondary context!"); return NULL; - } // creation selected the new context - switch back to previous context RenderTarget = NULL; pCurrCtx = NULL; diff --git a/src/graphics/C4DrawGL.h b/src/graphics/C4DrawGL.h index 1a0642e0d..6f6227f60 100644 --- a/src/graphics/C4DrawGL.h +++ b/src/graphics/C4DrawGL.h @@ -24,7 +24,7 @@ #include #endif -#include +#include #ifdef USE_COCOA #import "ObjectiveCAssociated.h" @@ -206,6 +206,8 @@ protected: std::set VAOIDs; std::set::iterator NextVAOID; + bool has_khr_debug; + public: // Create a new (unique) VAO ID. A VAO ID is a number that identifies // a certain VAO across all OpenGL contexts. This indirection is needed diff --git a/src/graphics/C4DrawGLCtx.cpp b/src/graphics/C4DrawGLCtx.cpp index a8b6cd01f..18f388fcc 100644 --- a/src/graphics/C4DrawGLCtx.cpp +++ b/src/graphics/C4DrawGLCtx.cpp @@ -57,7 +57,7 @@ void CStdGLCtx::SelectCommon() #ifdef USE_WGL -#include +#include static PIXELFORMATDESCRIPTOR pfd; // desired pixel format static HGLRC hrc = 0; @@ -70,7 +70,7 @@ static HGLRC hrc = 0; static std::vector EnumeratePixelFormats(HDC hdc) { std::vector result; - if(!wglGetPixelFormatAttribivARB) return result; + if(!epoxy_has_wgl_extension(hdc, "WGL_ARB_pixel_format")) return result; int n_formats; int attributes = WGL_NUMBER_PIXEL_FORMATS_ARB; @@ -262,14 +262,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) try { tempContext.reset(new GLTempContext); - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if(err != GLEW_OK) - { - // Problem: glewInit failed, something is seriously wrong. - pGL->Error(reinterpret_cast(glewGetErrorString(err))); - return false; - } } catch (const WinAPIError &e) { @@ -318,7 +310,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) else { // create context - if (wglCreateContextAttribsARB) + if (epoxy_has_wgl_extension(hDC, "WGL_ARB_create_context")) { const int attribs[] = { WGL_CONTEXT_FLAGS_ARB, Config.Graphics.DebugOpenGL ? WGL_CONTEXT_DEBUG_BIT_ARB : 0, @@ -348,17 +340,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) if (hrc) { Select(); - // After selecting the new context, we have to reinitialize GLEW to - // update its function pointers - the driver may elect to expose - // different extensions depending on the context attributes - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if (err != GLEW_OK) - { - // Uh. This is a problem. - pGL->Error(reinterpret_cast(glewGetErrorString(err))); - return false; - } this_context = contexts.insert(contexts.end(), this); return true; @@ -370,6 +351,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *pApp) std::vector CStdGLCtx::EnumerateMultiSamples() const { + assert(hrc != 0); std::vector result; std::vector vec = EnumeratePixelFormats(hDC); for(unsigned int i = 0; i < vec.size(); ++i) @@ -422,20 +404,10 @@ bool CStdGLCtx::PageFlip() } #elif defined(USE_GTK) -#include -#include +#include #include #include -namespace { -void InitGLXPointers() -{ - glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)(glXGetProcAddress((const GLubyte*)"glXGetVisualFromFBConfig")); - glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)(glXGetProcAddress((const GLubyte*)"glXChooseFBConfig")); - glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)(glXGetProcAddress((const GLubyte*)"glXCreateNewContext")); -} -} - CStdGLCtx::CStdGLCtx(): pWindow(0), ctx(0), this_context(contexts.end()) { } void CStdGLCtx::Clear(bool multisample_change) @@ -468,22 +440,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) // store window this->pWindow = pWindow; Display * const dpy = gdk_x11_display_get_xdisplay(gdk_display_get_default()); - InitGLXPointers(); - if (!glXGetVisualFromFBConfig || !glXChooseFBConfig || !glXCreateNewContext) - { - return pGL->Error(" gl: Unable to retrieve GLX 1.4 entry points"); - } - XVisualInfo *vis_info = glXGetVisualFromFBConfig(dpy, pWindow->Info); - // Create base context so we can initialize GLEW - GLXContext dummy_ctx = glXCreateContext(dpy, vis_info, 0, True); - XFree(vis_info); - glXMakeCurrent(dpy, pWindow->renderwnd, dummy_ctx); - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if (err != GLEW_OK) - { - return pGL->Error((const char*)glewGetErrorString(err)); - } // Create Context with sharing (if this is the main context, our ctx will be 0, so no sharing) const int attribs[] = { @@ -495,7 +451,7 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) }; GLXContext share_context = (pGL->pMainCtx != this) ? static_cast(pGL->pMainCtx->ctx) : 0; - if (glXCreateContextAttribsARB) + if (epoxy_has_glx_extension(dpy, gdk_x11_get_default_screen(), "GLX_ARB_create_context")) { int (*oldErrorHandler) (Display *, XErrorEvent *) = XSetErrorHandler(GLXErrorHandler); ctx = glXCreateContextAttribsARB(dpy, pWindow->Info, share_context, True, attribs); @@ -507,20 +463,9 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) ctx = glXCreateNewContext(dpy, pWindow->Info, GLX_RGBA_TYPE, share_context, True); } - glXMakeCurrent(dpy, None, NULL); - glXDestroyContext(dpy, dummy_ctx); - // No luck? if (!ctx) return pGL->Error(" gl: Unable to create context"); if (!Select(true)) return pGL->Error(" gl: Unable to select context"); - // init extensions - glewExperimental = GL_TRUE; - err = glewInit(); - if (GLEW_OK != err) - { - // Problem: glewInit failed, something is seriously wrong. - return pGL->Error(reinterpret_cast(glewGetErrorString(err))); - } this_context = contexts.insert(contexts.end(), this); return true; @@ -600,14 +545,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) ctx = SDL_GL_CreateContext(pWindow->window); // No luck at all? if (!Select(true)) return pGL->Error(" gl: Unable to select context"); - // init extensions - glewExperimental = GL_TRUE; - GLenum err = glewInit(); - if (GLEW_OK != err) - { - // Problem: glewInit failed, something is seriously wrong. - return pGL->Error(reinterpret_cast(glewGetErrorString(err))); - } this_context = contexts.insert(contexts.end(), this); return true; diff --git a/src/graphics/C4DrawGLMac.mm b/src/graphics/C4DrawGLMac.mm index 0164c123c..fd46fc703 100644 --- a/src/graphics/C4DrawGLMac.mm +++ b/src/graphics/C4DrawGLMac.mm @@ -588,14 +588,6 @@ bool CStdGLCtx::Init(C4Window * pWindow, C4AbstractApp *) setObjectiveCObject(ctx); // No luck at all? if (!Select(true)) return pGL->Error(" gl: Unable to select context"); - // init extensions - glewExperimental = GL_TRUE; // Init GL 3.0+ function pointers - GLenum err = glewInit(); - if (GLEW_OK != err) - { - // Problem: glewInit failed, something is seriously wrong. - return pGL->Error(reinterpret_cast(glewGetErrorString(err))); - } // set the openglview's context auto controller = pWindow->objectiveCObject(); if (controller && controller.openGLView) diff --git a/src/graphics/C4Shader.h b/src/graphics/C4Shader.h index edfbbf795..867181679 100644 --- a/src/graphics/C4Shader.h +++ b/src/graphics/C4Shader.h @@ -22,11 +22,7 @@ #include "StdMeshMath.h" #include "C4Surface.h" -#ifdef _WIN32 -#include -#endif - -#include +#include // Shader version const int C4Shader_Version = 150; // GLSL 1.50 / OpenGL 3.2 diff --git a/src/platform/C4AppDelegate+MainMenuActions.mm b/src/platform/C4AppDelegate+MainMenuActions.mm index 45bbd9674..66d56bb8e 100644 --- a/src/platform/C4AppDelegate+MainMenuActions.mm +++ b/src/platform/C4AppDelegate+MainMenuActions.mm @@ -13,13 +13,13 @@ * for the above references. */ -#include - #include #include #include #include +#include + #import "C4AppDelegate+MainMenuActions.h" #import "C4DrawGLMac.h" #import "C4EditorWindowController.h" diff --git a/src/platform/C4AppMac.mm b/src/platform/C4AppMac.mm index 459f844e3..2c750931f 100644 --- a/src/platform/C4AppMac.mm +++ b/src/platform/C4AppMac.mm @@ -16,14 +16,14 @@ // based on SDL implementation -#include -#include - #include +#include "C4App.h" + #include #include -#include "C4App.h" +#include + #import #ifndef USE_CONSOLE diff --git a/src/platform/C4WindowController.mm b/src/platform/C4WindowController.mm index 5f7e4f7d3..4fec6c82a 100644 --- a/src/platform/C4WindowController.mm +++ b/src/platform/C4WindowController.mm @@ -13,8 +13,6 @@ * for the above references. */ -#include - #include #include #include @@ -22,6 +20,8 @@ #include #include +#include + #import "C4WindowController.h" #import "C4DrawGLMac.h" #import "C4EditorWindowController.h" diff --git a/src/platform/C4WindowGTK.cpp b/src/platform/C4WindowGTK.cpp index 157ac4cb0..a3b539315 100644 --- a/src/platform/C4WindowGTK.cpp +++ b/src/platform/C4WindowGTK.cpp @@ -42,7 +42,7 @@ #ifdef GDK_WINDOWING_X11 #include #include -#include +#include // Some helper functions for choosing a proper visual diff --git a/tools/osx_bundle_libs b/tools/osx_bundle_libs index 548a48826..1f3689f69 100755 --- a/tools/osx_bundle_libs +++ b/tools/osx_bundle_libs @@ -23,7 +23,7 @@ _otool="${OTOOL:-otool}" _install_name_tool="${INSTALL_NAME_TOOL:-install_name_tool}" # This regexp should match every lib we want to bundle. -_libs_to_bundle=".*?/lib(jpeg|GLEW|llvm|SDL|SDL_mixer|freetype|ogg|vorbis|vorbisfile|z\.|png[0-9]*|alut)\.[^ ]+\.dylib" +_libs_to_bundle=".*?/lib(jpeg|epoxy|llvm|SDL|SDL_mixer|freetype|ogg|vorbis|vorbisfile|z\.|png[0-9]*|alut)\.[^ ]+\.dylib" if [ -n "${TARGET_BUILD_DIR}" ]; then cd "${TARGET_BUILD_DIR}"