From ef6d70c8ad32b517535a3aa7c51862bb2b2655e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 27 May 2012 15:50:47 +0200 Subject: [PATCH] First version of SDL2 context. --- modules/FindMagnum.cmake | 8 +++ modules/FindSDL2.cmake | 23 ++++++++ src/Contexts/CMakeLists.txt | 11 ++++ src/Contexts/Sdl2Context.cpp | 101 +++++++++++++++++++++++++++++++++++ src/Contexts/Sdl2Context.h | 87 ++++++++++++++++++++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 modules/FindSDL2.cmake create mode 100644 src/Contexts/Sdl2Context.cpp create mode 100644 src/Contexts/Sdl2Context.h diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index fbe8edb2e..bed282f48 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -76,6 +76,14 @@ foreach(component ${Magnum_FIND_COMPONENTS}) unset(MAGNUM_${_COMPONENT}_LIBRARY) endif() endif() + + # SDL2 context dependencies + if(${component} STREQUAL Sdl2Context) + find_package(SDL2) + if(NOT SDL2_FOUND) + unset(MAGNUM_${_COMPONENT}_LIBRARY) + endif() + endif() endif() # Mesh tools library diff --git a/modules/FindSDL2.cmake b/modules/FindSDL2.cmake new file mode 100644 index 000000000..9ac6e9020 --- /dev/null +++ b/modules/FindSDL2.cmake @@ -0,0 +1,23 @@ +# - Find SDL2 +# +# This module defines: +# +# SDL2_FOUND - True if SDL2 library is found +# SDL2_LIBRARY - SDL2 dynamic library +# SDL2_INCLUDE_DIR - Include dir +# + +# Library +find_library(SDL2_LIBRARY SDL2) + +# Include dir +find_path(SDL2_INCLUDE_DIR + NAMES SDL.h SDL_scancode.h + PATH_SUFFIXES SDL2 +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args("SDL2" DEFAULT_MSG + SDL2_LIBRARY + SDL2_INCLUDE_DIR +) diff --git a/src/Contexts/CMakeLists.txt b/src/Contexts/CMakeLists.txt index 9869c968c..155eda326 100644 --- a/src/Contexts/CMakeLists.txt +++ b/src/Contexts/CMakeLists.txt @@ -9,3 +9,14 @@ if(GLUT_FOUND) else() message(WARNING "GLUT library was not found. GLUT context library will not be generated.") endif() + +# SDL2 context +find_package(SDL2) +if(SDL2_FOUND) + include_directories(${SDL2_INCLUDE_DIR}) + add_library(MagnumSdl2Context STATIC Sdl2Context.cpp) + install(FILES Sdl2Context.h DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Contexts) + install(TARGETS MagnumSdl2Context DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) +else() + message(WARNING "SDL2 library was not found. SDL2 context library will not be generated.") +endif() diff --git a/src/Contexts/Sdl2Context.cpp b/src/Contexts/Sdl2Context.cpp new file mode 100644 index 000000000..d5fc2cfb0 --- /dev/null +++ b/src/Contexts/Sdl2Context.cpp @@ -0,0 +1,101 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "Sdl2Context.h" + +using namespace Corrade::Utility; + +namespace Magnum { namespace Contexts { + +Sdl2Context::Sdl2Context(int argc, char** argv, const std::string& name, const Math::Vector2& size): _redraw(true) { + if(SDL_Init(SDL_INIT_VIDEO) < 0) { + Error() << "Cannot initialize SDL."; + exit(1); + } + + /* Request OpenGL 3.3 */ + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + + /* Enable double buffering and 24bt depth buffer */ + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + + window = SDL_CreateWindow(name.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + size.x(), size.y(), SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); + if(!window) { + Error() << "Cannot create window."; + exit(2); + } + + context = SDL_GL_CreateContext(window); + + /* This must be enabled, otherwise (on my NVidia) it crashes when creating + VAO. WTF. */ + glewExperimental = true; + + /* Init GLEW */ + GLenum err = glewInit(); + if(err != GLEW_OK) { + Error() << "Sdl2Context: cannot initialize GLEW:" << glewGetErrorString(err); + exit(1); + } + + /* Push resize event, so viewportEvent() is called at startup */ + SDL_Event* sizeEvent = new SDL_Event; + sizeEvent->type = SDL_WINDOWEVENT; + sizeEvent->window.event = SDL_WINDOWEVENT_RESIZED; + sizeEvent->window.data1 = size.x(); + sizeEvent->window.data2 = size.y(); + SDL_PushEvent(sizeEvent); +} + +Sdl2Context::~Sdl2Context() { + SDL_GL_DeleteContext(context); + SDL_DestroyWindow(window); + SDL_Quit(); +} + +int Sdl2Context::exec() { + for(;;) { + SDL_Event event; + + while(SDL_PollEvent(&event)) { + switch(event.type) { + case SDL_WINDOWEVENT: + switch(event.window.event) { + case SDL_WINDOWEVENT_RESIZED: + viewportEvent({event.window.data1, event.window.data2}); + _redraw = true; + break; + case SDL_WINDOWEVENT_EXPOSED: + _redraw = true; + break; + } break; + case SDL_QUIT: + return 0; + } + } + + if(_redraw) { + drawEvent(); + _redraw = false; + } else Corrade::Utility::sleep(5); + } + + return 0; +} + +}} diff --git a/src/Contexts/Sdl2Context.h b/src/Contexts/Sdl2Context.h new file mode 100644 index 000000000..efa71f157 --- /dev/null +++ b/src/Contexts/Sdl2Context.h @@ -0,0 +1,87 @@ +#ifndef Magnum_Contexts_Sdl2Context_h +#define Magnum_Contexts_Sdl2Context_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Contexts::Sdl2Context + */ + +#include "Magnum.h" +#include + +#include "AbstractContext.h" +#include + +namespace Magnum { namespace Contexts { + +/** @nosubgrouping +@brief SDL2 context + +Currently doesn't have any mouse/keyboard handling. + +You need to implement at least drawEvent() and viewportEvent() to be able to +draw on the screen. +*/ +class Sdl2Context: public AbstractContext { + public: + /** + * @brief Constructor + * @param argc Count of arguments of `main()` function + * @param argv Arguments of `main()` function + * @param title Window title + * @param size Window size + * + * Creates centered non-resizable window with double-buffered + * OpenGL 3.3 context with 24bit depth buffer. + */ + Sdl2Context(int argc, char** argv, const std::string& title = "Magnum SDL2 context", const Math::Vector2& size = Math::Vector2(800, 600)); + + /** + * @brief Destructors + * + * Deletes context and destroys the window. + */ + ~Sdl2Context(); + + int exec(); + + /** @{ @name Drawing functions */ + + protected: + /** @copydoc GlutContext::viewportEvent() */ + virtual void viewportEvent(const Math::Vector2& size) = 0; + + /** @copydoc GlutContext::drawEvent() */ + virtual void drawEvent() = 0; + + /** @copydoc GlutContext::swapBuffers() */ + inline void swapBuffers() { SDL_GL_SwapWindow(window); } + + /** @copydoc GlutContext::redraw() */ + inline void redraw() { _redraw = true; } + + /*@}*/ + + private: + SDL_Window* window; + SDL_GLContext context; + + bool _redraw; +}; + +}} + +#endif