diff --git a/CMakeLists.txt b/CMakeLists.txt index 8020028ca..d596586ea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -81,8 +81,12 @@ elseif(CORRADE_TARGET_UNIX) # Windows-specific application libraries elseif(CORRADE_TARGET_WINDOWS) - cmake_dependent_option(WITH_WINDOWLESSWGLAPPLICATION "Build WindowlessWglApplication library" OFF "NOT WITH_MAGNUMINFO;NOT WITH_FONTCONVERTER;NOT WITH_DISTANCEFIELDCONVERTER" ON) - option(WITH_WGLCONTEXT "Build WglContext library" OFF) + if(NOT TARGET_GLES) + cmake_dependent_option(WITH_WINDOWLESSWGLAPPLICATION "Build WindowlessWglApplication library" OFF "NOT WITH_MAGNUMINFO;NOT WITH_FONTCONVERTER;NOT WITH_DISTANCEFIELDCONVERTER" ON) + option(WITH_WGLCONTEXT "Build WglContext library" OFF) + else() + cmake_dependent_option(WITH_WINDOWLESSWINDOWSEGLAPPLICATION "Build WindowlessWindowsEglApplication library" OFF "NOT WITH_MAGNUMINFO;NOT WITH_FONTCONVERTER;NOT WITH_DISTANCEFIELDCONVERTER" ON) + endif() endif() # Platform-independent (almost) application libraries diff --git a/doc/building.dox b/doc/building.dox index a5ea66a67..00f629ce1 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -210,6 +210,7 @@ platform best: - `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" - `WITH_WINDOWLESSNACLAPPLICATION` - @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication" - `WITH_WINDOWLESSWGLAPPLICATION` - @ref Platform::WindowlessWglApplication "WindowlessWglApplication" +- `WITH_WINDOWLESSWINDOWSEGLAPPLICATION` - @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" None of the context libraries is built by default. You need them only if you choose to not use any application library (see @ref platform-custom for more diff --git a/doc/cmake.dox b/doc/cmake.dox index fb69fff09..6253a29d0 100644 --- a/doc/cmake.dox +++ b/doc/cmake.dox @@ -105,6 +105,7 @@ Platform namespace is split into more components: - `WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" - `WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication" - `WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" +- `WindowlessWindowsEglApplication` -- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication" For manual context creation (without application wrappers) there are also platform-specific context libraries (see @ref platform-custom for more diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 884fd3c59..e1bb827bb 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -57,6 +57,7 @@ # WindowlessGlxApplication - Windowless GLX application # WindowlessNaClApplication - Windowless NaCl application # WindowlessWglApplication - Windowless WGL application +# WindowlessWindowsEglApplication - Windowless Windows/EGL application # CglContext - CGL context # EglContext - EGL context # GlxContext - GLX context @@ -420,6 +421,15 @@ foreach(component ${Magnum_FIND_COMPONENTS}) # Windowless CGL application has no additional dependencies # Windowless WGL application has no additional dependencies + # Windowless Windows/EGL application dependencies + elseif(${component} STREQUAL WindowlessWindowsEglApplication) + find_package(EGL) + if(EGL_FOUND) + set(_MAGNUM_${_COMPONENT}_LIBRARIES ${EGL_LIBRARY}) + else() + unset(MAGNUM_${_COMPONENT}_LIBRARY) + endif() + # X/EGL application dependencies elseif(${component} STREQUAL XEglApplication) find_package(EGL) diff --git a/src/Magnum/Platform/CMakeLists.txt b/src/Magnum/Platform/CMakeLists.txt index 7625585a4..ecbc2d359 100644 --- a/src/Magnum/Platform/CMakeLists.txt +++ b/src/Magnum/Platform/CMakeLists.txt @@ -321,6 +321,37 @@ if(WITH_WINDOWLESSWGLAPPLICATION) ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) endif() +# Windowless Windows/EGL application +if(WITH_WINDOWLESSWINDOWSEGLAPPLICATION) + set(NEED_EGLCONTEXT 1) + + set(MagnumWindowlessWindowsEglApplication_SRCS + WindowlessWindowsEglApplication.cpp + Implementation/Egl.cpp + $) + set(MagnumWindowlessWindowsEglApplication_HEADERS + WindowlessWindowsEglApplication.h) + set(MagnumWindowlessWindowsEglApplication_PRIVATE_HEADERS + Implementation/Egl.h) + + add_library(MagnumWindowlessWindowsEglApplication STATIC + ${MagnumWindowlessWindowsEglApplication_SRCS} + ${MagnumWindowlessWindowsEglApplication_HEADERS} + ${MagnumWindowlessWindowsEglApplication_PRIVATE_HEADERS}) + set_target_properties(MagnumWindowlessWindowsEglApplication PROPERTIES + COMPILE_FLAGS "-DUNICODE" + DEBUG_POSTFIX "-d") + target_link_libraries(MagnumWindowlessWindowsEglApplication Magnum ${EGL_LIBRARY}) + # Assuming that PIC is not needed because the Application lib is always + # linked to the executable and not to any intermediate shared lib + + install(FILES ${MagnumWindowlessWindowsEglApplication_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Platform) + install(TARGETS MagnumWindowlessWindowsEglApplication + RUNTIME DESTINATION ${MAGNUM_BINARY_INSTALL_DIR} + LIBRARY DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR} + ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) +endif() + # Windowless CGL application if(WITH_WINDOWLESSCGLAPPLICATION) set(NEED_CGLCONTEXT 1) diff --git a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp index 4a4a7cd54..c96476fe0 100644 --- a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp +++ b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp @@ -27,8 +27,12 @@ #include +/* EGL-specific includes */ +#ifdef MAGNUM_PLATFORM_USE_EGL +#include + /* CGL-specific includes */ -#if defined(CORRADE_TARGET_APPLE) +#elif defined(CORRADE_TARGET_APPLE) #include /* WGL-specific stuff */ @@ -42,10 +46,6 @@ #elif defined(CORRADE_TARGET_UNIX) && defined(MAGNUM_PLATFORM_USE_GLX) #include -/* EGL-specific includes */ -#elif defined(MAGNUM_PLATFORM_USE_EGL) -#include - /* Otherwise unsupported */ #else #error unsupported platform @@ -53,8 +53,18 @@ namespace Magnum { namespace Platform { namespace Implementation { +/* EGL-specific implementation */ +#ifdef MAGNUM_PLATFORM_USE_EGL +OpenGLFunctionLoader::OpenGLFunctionLoader() = default; + +OpenGLFunctionLoader::~OpenGLFunctionLoader() = default; + +auto OpenGLFunctionLoader::load(const char* const name) -> FunctionPointer { + return eglGetProcAddress(name); +} + /* CGL-specific implementation */ -#ifdef CORRADE_TARGET_APPLE +#elif defined(CORRADE_TARGET_APPLE) OpenGLFunctionLoader::OpenGLFunctionLoader() { CORRADE_INTERNAL_ASSERT_OUTPUT(library = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY)); } @@ -96,16 +106,6 @@ auto OpenGLFunctionLoader::load(const char* const name) -> FunctionPointer { return glXGetProcAddressARB(reinterpret_cast(name)); } -/* EGL-specific implementation */ -#elif defined(MAGNUM_PLATFORM_USE_EGL) -OpenGLFunctionLoader::OpenGLFunctionLoader() = default; - -OpenGLFunctionLoader::~OpenGLFunctionLoader() = default; - -auto OpenGLFunctionLoader::load(const char* const name) -> FunctionPointer { - return eglGetProcAddress(name); -} - /* Otherwise unsupported */ #else #error unsupported platform diff --git a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h index 2d89eb37d..9b2cb260a 100644 --- a/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h +++ b/src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h @@ -27,7 +27,7 @@ #include "Magnum/Magnum.h" -#ifdef CORRADE_TARGET_WINDOWS +#if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_PLATFORM_USE_EGL) #define WIN32_LEAN_AND_MEAN 1 #include #endif @@ -36,7 +36,7 @@ namespace Magnum { namespace Platform { namespace Implementation { class OpenGLFunctionLoader { public: - #ifndef CORRADE_TARGET_WINDOWS + #if !defined(CORRADE_TARGET_WINDOWS) || defined(MAGNUM_PLATFORM_USE_EGL) using FunctionPointer = void(*)(); #else using FunctionPointer = PROC; @@ -48,8 +48,11 @@ class OpenGLFunctionLoader { FunctionPointer load(const char* name); private: + /* EGL-specific handles (nothing needed) */ + #ifdef MAGNUM_PLATFORM_USE_EGL + /* CGL-specific handles */ - #ifdef CORRADE_TARGET_APPLE + #elif defined(CORRADE_TARGET_APPLE) void* library; /* WGL-specific handles */ @@ -59,9 +62,6 @@ class OpenGLFunctionLoader { /* GLX-specific handles (nothing needed) */ #elif defined(CORRADE_TARGET_UNIX) && defined(MAGNUM_PLATFORM_USE_GLX) - /* EGL-specific handles (nothing needed) */ - #elif defined(MAGNUM_PLATFORM_USE_EGL) - /* Otherwise unsupported */ #else #error unsupported platform diff --git a/src/Magnum/Platform/WindowlessWindowsEglApplication.cpp b/src/Magnum/Platform/WindowlessWindowsEglApplication.cpp new file mode 100644 index 000000000..16807f8c5 --- /dev/null +++ b/src/Magnum/Platform/WindowlessWindowsEglApplication.cpp @@ -0,0 +1,170 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "WindowlessWindowsEglApplication.h" + +#include +#include + +#include "Magnum/Platform/Context.h" + +#include "Implementation/Egl.h" + +namespace Magnum { namespace Platform { + +#ifndef DOXYGEN_GENERATING_OUTPUT +int WindowlessWindowsEglApplication::create(LRESULT(CALLBACK windowProcedure)(HWND, UINT, WPARAM, LPARAM)) { + const WNDCLASS wc{ + 0, + windowProcedure, + 0, + 0, + GetModuleHandle(nullptr), + nullptr, + nullptr, + HBRUSH(COLOR_BACKGROUND), + nullptr, + L"Magnum Windowless Application" + }; + if(!RegisterClass(&wc)) return 1; + + CreateWindowW(wc.lpszClassName, L"Magnum Windowless Application", + WS_OVERLAPPEDWINDOW, 0, 0, 32, 32, 0, 0, wc.hInstance, 0); + + /* Hammer the return code out of the messaging thingy */ + MSG msg; + do {} while(GetMessageW(&msg, nullptr, 0, 0) != 0); + return msg.wParam; +} +#endif + +#ifndef DOXYGEN_GENERATING_OUTPUT +WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(const Arguments& arguments): WindowlessWindowsEglApplication{arguments, Configuration{}} {} +#endif + +WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(const Arguments& arguments, const Configuration& configuration): WindowlessWindowsEglApplication{arguments, nullptr} { + createContext(configuration); +} + +WindowlessWindowsEglApplication::WindowlessWindowsEglApplication(const Arguments& arguments, std::nullptr_t): _window(arguments.window) {} + +void WindowlessWindowsEglApplication::createContext() { createContext({}); } + +void WindowlessWindowsEglApplication::createContext(const Configuration& configuration) { + if(!tryCreateContext(configuration)) std::exit(1); +} + +bool WindowlessWindowsEglApplication::tryCreateContext(const Configuration&) { + CORRADE_ASSERT(!_context, "Platform::WindowlessWindowsEglApplication::tryCreateContext(): context already created", false); + + /* Initialize */ + _display = eglGetDisplay(GetDC(_window)); + if(!eglInitialize(_display, nullptr, nullptr)) { + Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot initialize EGL:" << Implementation::eglErrorString(eglGetError()); + return false; + } + + const EGLenum api = + #ifndef MAGNUM_TARGET_GLES + EGL_OPENGL_API + #else + EGL_OPENGL_ES_API + #endif + ; + if(!eglBindAPI(api)) { + Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot bind EGL API:" << Implementation::eglErrorString(eglGetError()); + return false; + } + + /* Choose EGL config */ + static const EGLint attribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_DEPTH_SIZE, 1, + #ifndef MAGNUM_TARGET_GLES + EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, + #elif defined(MAGNUM_TARGET_GLES3) + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, + #elif defined(MAGNUM_TARGET_GLES2) + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + #else + #error unsupported OpenGL edition + #endif + EGL_NONE + }; + EGLint configCount; + if(!eglChooseConfig(_display, attribs, &_config, 1, &configCount)) { + Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot get EGL visual config:" << Implementation::eglErrorString(eglGetError()); + return false; + } + + if(!configCount) { + Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): no matching EGL visual config available"; + return false; + } + + static const EGLint attributes[] = { + #ifdef MAGNUM_TARGET_GLES + EGL_CONTEXT_CLIENT_VERSION, + #ifdef MAGNUM_TARGET_GLES3 + 3, + #elif defined(MAGNUM_TARGET_GLES2) + 2, + #else + #error unsupported OpenGL ES version + #endif + #endif + + EGL_NONE + }; + + if(!(_glContext = eglCreateContext(_display, _config, EGL_NO_CONTEXT, attributes))) { + Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot create EGL context:" << Implementation::eglErrorString(eglGetError()); + return false; + } + if(!(_surface = eglCreateWindowSurface(_display, _config, _window, nullptr))) { + Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot create window surface:" << Implementation::eglErrorString(eglGetError()); + return false; + } + + if(!eglMakeCurrent(_display, _surface, _surface, _glContext)) { + Error() << "Platform::WindowlessWindowsEglApplication::tryCreateContext(): cannot make context current:" << Implementation::eglErrorString(eglGetError()); + return false; + } + + _context.reset(new Platform::Context); + return true; +} + +WindowlessWindowsEglApplication::~WindowlessWindowsEglApplication() { + _context.reset(); + + eglDestroyContext(_display, _glContext); + eglDestroySurface(_display, _surface); + eglTerminate(_display); +} + +}} diff --git a/src/Magnum/Platform/WindowlessWindowsEglApplication.h b/src/Magnum/Platform/WindowlessWindowsEglApplication.h new file mode 100644 index 000000000..21467616a --- /dev/null +++ b/src/Magnum/Platform/WindowlessWindowsEglApplication.h @@ -0,0 +1,228 @@ +#ifndef Magnum_Platform_WindowlessWindowsEglApplication_h +#define Magnum_Platform_WindowlessWindowsEglApplication_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Platform::WindowlessWindowsEglApplication, macro @ref MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN() + */ + +#include +#ifndef DOXYGEN_GENERATING_OUTPUT +#define WIN32_LEAN_AND_MEAN 1 +#define VC_EXTRALEAN +#endif +#include +#include + +#include "Magnum/Magnum.h" +#include "Magnum/OpenGL.h" +#include "Magnum/Platform/Context.h" + +namespace Magnum { namespace Platform { + +/** +@brief Windowless Windows/EGL application + +Application for offscreen rendering using pure WINAPI and EGL. + +This application library is available on OpenGL ES (also ANGLE) on Windows. It +is built if `WITH_WINDOWLESSWINDOWSEGLAPPLICATION` is enabled in CMake. + +## Bootstrap application + +Fully contained windowless application using @ref WindowlessWindowsEglApplication +along with CMake setup is available in `windowless` branch of +[Magnum Bootstrap](https://github.com/mosra/magnum-bootstrap) repository, +download it as [tar.gz](https://github.com/mosra/magnum-bootstrap/archive/windowless.tar.gz) +or [zip](https://github.com/mosra/magnum-bootstrap/archive/windowless.zip) +file. After extracting the downloaded archive you can build and run the +application with these four commands: + + mkdir build && cd build + cmake .. + cmake --build . + ./src/MyApplication # or ./src/Debug/MyApplication + +See @ref cmake for more information. + +## General usage + +In CMake you need to request `WindowlessWindowsEglApplication` component, add +`${MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_INCLUDE_DIRS}` to include path and +link to `${MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_LIBRARIES}`. If no other +windowless application is requested, you can also use generic +`${MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS}` and +`${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. Again, +see @ref building and @ref cmake for more information. + +Place your code into @ref exec(). The subclass can be then used in main +function using @ref MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN() macro. See +@ref platform for more information. +@code +class MyApplication: public Platform::WindowlessWindowsEglApplication { + // implement required methods... +}; +MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN(MyApplication) +@endcode + +If no other application header is included, this class is also aliased to +`Platform::WindowlessApplication` and the macro is aliased to +`MAGNUM_WINDOWLESSAPPLICATION_MAIN()` to simplify porting. +*/ +class WindowlessWindowsEglApplication { + public: + /** @brief Application arguments */ + struct Arguments { + /** @brief Constructor */ + /*implicit*/ constexpr Arguments(int& argc, char** argv, HWND window) noexcept: argc{argc}, argv{argv}, window{window} {} + + int& argc; /**< @brief Argument count */ + char** argv; /**< @brief Argument values */ + #ifndef DOXYGEN_GENERATING_OUTPUT + HWND window; + #endif + }; + + class Configuration; + + #ifndef DOXYGEN_GENERATING_OUTPUT + static int create(LRESULT(CALLBACK windowProcedure)(HWND, UINT, WPARAM, LPARAM)); + #endif + + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ + #ifdef DOXYGEN_GENERATING_OUTPUT + explicit WindowlessWindowsEglApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); + #else + /* To avoid "invalid use of incomplete type" */ + explicit WindowlessWindowsEglApplication(const Arguments& arguments, const Configuration& configuration); + explicit WindowlessWindowsEglApplication(const Arguments& arguments); + #endif + + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ + explicit WindowlessWindowsEglApplication(const Arguments& arguments, std::nullptr_t); + + /** @brief Copying is not allowed */ + WindowlessWindowsEglApplication(const WindowlessWindowsEglApplication&) = delete; + + /** @brief Moving is not allowed */ + WindowlessWindowsEglApplication(WindowlessWindowsEglApplication&&) = delete; + + /** @brief Copying is not allowed */ + WindowlessWindowsEglApplication& operator=(const WindowlessWindowsEglApplication&) = delete; + + /** @brief Moving is not allowed */ + WindowlessWindowsEglApplication& operator=(WindowlessWindowsEglApplication&&) = delete; + + /** + * @brief Execute application + * @return Value for returning from `main()` + * + * See @ref MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN() for usage + * information. + */ + virtual int exec() = 0; + + protected: + /* Nobody will need to have (and delete) WindowlessWindowsEglApplication*, + thus this is faster than public pure virtual destructor */ + ~WindowlessWindowsEglApplication(); + + /** @copydoc Sdl2Application::createContext() */ + #ifdef DOXYGEN_GENERATING_OUTPUT + void createContext(const Configuration& configuration = Configuration()); + #else + /* To avoid "invalid use of incomplete type" */ + void createContext(const Configuration& configuration); + void createContext(); + #endif + + /** @copydoc Sdl2Application::tryCreateContext() */ + bool tryCreateContext(const Configuration& configuration); + + private: + HWND _window; + EGLDisplay _display; + EGLConfig _config; + EGLSurface _surface; + EGLContext _glContext; + + std::unique_ptr _context; +}; + +/** +@brief Configuration + +@see @ref WindowlessWindowsEglApplication(), @ref createContext(), + @ref tryCreateContext() +*/ +class WindowlessWindowsEglApplication::Configuration { + public: + constexpr /*implicit*/ Configuration() {} +}; + +/** @hideinitializer +@brief Entry point for windowless WGL application +@param className Class name + +See @ref Magnum::Platform::WindowlessWindowsEglApplication "Platform::WindowlessWindowsEglApplication" +for usage information. This macro abstracts out platform-specific entry point +code, see @ref portability-applications for more information. When no other +windowless application header is included this macro is also aliased to +`MAGNUM_WINDOWLESSAPPLICATION_MAIN()`. +*/ +#define MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN(className) \ + int globalArgc; char** globalArgv; \ + LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); \ + LRESULT CALLBACK windowProcedure(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { \ + switch(message) { \ + case WM_CREATE: \ + { \ + className app({globalArgc, globalArgv, hWnd}); \ + PostQuitMessage(app.exec()); \ + } \ + break; \ + default: return DefWindowProc(hWnd, message, wParam, lParam); \ + } \ + return 0; \ + } \ + int main(int argc, char** argv) { \ + globalArgc = argc; \ + globalArgv = argv; \ + return Magnum::Platform::WindowlessWindowsEglApplication::create(windowProcedure); \ + } + +#ifndef DOXYGEN_GENERATING_OUTPUT +#ifndef MAGNUM_WINDOWLESSAPPLICATION_MAIN +typedef WindowlessWindowsEglApplication WindowlessApplication; +#define MAGNUM_WINDOWLESSAPPLICATION_MAIN(className) MAGNUM_WINDOWLESSWINDOWSEGLAPPLICATION_MAIN(className) +#else +#undef MAGNUM_WINDOWLESSAPPLICATION_MAIN +#endif +#endif + +}} + +#endif