Browse Source

Platform: added WindowlessWindowsEglApplication.

Windowless application on Windows, OpenGL ES and EGL. Works with ANGLE.
pull/110/head
Vladimír Vondruš 11 years ago
parent
commit
500b18f657
  1. 8
      CMakeLists.txt
  2. 1
      doc/building.dox
  3. 1
      doc/cmake.dox
  4. 10
      modules/FindMagnum.cmake
  5. 31
      src/Magnum/Platform/CMakeLists.txt
  6. 32
      src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp
  7. 12
      src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h
  8. 170
      src/Magnum/Platform/WindowlessWindowsEglApplication.cpp
  9. 228
      src/Magnum/Platform/WindowlessWindowsEglApplication.h

8
CMakeLists.txt

@ -81,8 +81,12 @@ elseif(CORRADE_TARGET_UNIX)
# Windows-specific application libraries # Windows-specific application libraries
elseif(CORRADE_TARGET_WINDOWS) elseif(CORRADE_TARGET_WINDOWS)
cmake_dependent_option(WITH_WINDOWLESSWGLAPPLICATION "Build WindowlessWglApplication library" OFF "NOT WITH_MAGNUMINFO;NOT WITH_FONTCONVERTER;NOT WITH_DISTANCEFIELDCONVERTER" ON) if(NOT TARGET_GLES)
option(WITH_WGLCONTEXT "Build WglContext library" OFF) 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() endif()
# Platform-independent (almost) application libraries # Platform-independent (almost) application libraries

1
doc/building.dox

@ -210,6 +210,7 @@ platform best:
- `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" - `WITH_WINDOWLESSGLXAPPLICATION` - @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WITH_WINDOWLESSNACLAPPLICATION` - @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication" - `WITH_WINDOWLESSNACLAPPLICATION` - @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
- `WITH_WINDOWLESSWGLAPPLICATION` - @ref Platform::WindowlessWglApplication "WindowlessWglApplication" - `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 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 choose to not use any application library (see @ref platform-custom for more

1
doc/cmake.dox

@ -105,6 +105,7 @@ Platform namespace is split into more components:
- `WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication" - `WindowlessGlxApplication` -- @ref Platform::WindowlessGlxApplication "WindowlessGlxApplication"
- `WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication" - `WindowlessNaClApplication` -- @ref Platform::WindowlessNaClApplication "WindowlessNaClApplication"
- `WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication" - `WindowlessWglApplication` -- @ref Platform::WindowlessWglApplication "WindowlessWglApplication"
- `WindowlessWindowsEglApplication` -- @ref Platform::WindowlessWindowsEglApplication "WindowlessWindowsEglApplication"
For manual context creation (without application wrappers) there are also For manual context creation (without application wrappers) there are also
platform-specific context libraries (see @ref platform-custom for more platform-specific context libraries (see @ref platform-custom for more

10
modules/FindMagnum.cmake

@ -57,6 +57,7 @@
# WindowlessGlxApplication - Windowless GLX application # WindowlessGlxApplication - Windowless GLX application
# WindowlessNaClApplication - Windowless NaCl application # WindowlessNaClApplication - Windowless NaCl application
# WindowlessWglApplication - Windowless WGL application # WindowlessWglApplication - Windowless WGL application
# WindowlessWindowsEglApplication - Windowless Windows/EGL application
# CglContext - CGL context # CglContext - CGL context
# EglContext - EGL context # EglContext - EGL context
# GlxContext - GLX context # GlxContext - GLX context
@ -420,6 +421,15 @@ foreach(component ${Magnum_FIND_COMPONENTS})
# Windowless CGL application has no additional dependencies # Windowless CGL application has no additional dependencies
# Windowless WGL 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 # X/EGL application dependencies
elseif(${component} STREQUAL XEglApplication) elseif(${component} STREQUAL XEglApplication)
find_package(EGL) find_package(EGL)

31
src/Magnum/Platform/CMakeLists.txt

@ -321,6 +321,37 @@ if(WITH_WINDOWLESSWGLAPPLICATION)
ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) ARCHIVE DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR})
endif() endif()
# Windowless Windows/EGL application
if(WITH_WINDOWLESSWINDOWSEGLAPPLICATION)
set(NEED_EGLCONTEXT 1)
set(MagnumWindowlessWindowsEglApplication_SRCS
WindowlessWindowsEglApplication.cpp
Implementation/Egl.cpp
$<TARGET_OBJECTS:MagnumEglContextObjects>)
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 # Windowless CGL application
if(WITH_WINDOWLESSCGLAPPLICATION) if(WITH_WINDOWLESSCGLAPPLICATION)
set(NEED_CGLCONTEXT 1) set(NEED_CGLCONTEXT 1)

32
src/Magnum/Platform/Implementation/OpenGLFunctionLoader.cpp

@ -27,8 +27,12 @@
#include <Corrade/Utility/Assert.h> #include <Corrade/Utility/Assert.h>
/* EGL-specific includes */
#ifdef MAGNUM_PLATFORM_USE_EGL
#include <EGL/egl.h>
/* CGL-specific includes */ /* CGL-specific includes */
#if defined(CORRADE_TARGET_APPLE) #elif defined(CORRADE_TARGET_APPLE)
#include <dlfcn.h> #include <dlfcn.h>
/* WGL-specific stuff */ /* WGL-specific stuff */
@ -42,10 +46,6 @@
#elif defined(CORRADE_TARGET_UNIX) && defined(MAGNUM_PLATFORM_USE_GLX) #elif defined(CORRADE_TARGET_UNIX) && defined(MAGNUM_PLATFORM_USE_GLX)
#include <GL/glx.h> #include <GL/glx.h>
/* EGL-specific includes */
#elif defined(MAGNUM_PLATFORM_USE_EGL)
#include <EGL/egl.h>
/* Otherwise unsupported */ /* Otherwise unsupported */
#else #else
#error unsupported platform #error unsupported platform
@ -53,8 +53,18 @@
namespace Magnum { namespace Platform { namespace Implementation { 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 */ /* CGL-specific implementation */
#ifdef CORRADE_TARGET_APPLE #elif defined(CORRADE_TARGET_APPLE)
OpenGLFunctionLoader::OpenGLFunctionLoader() { OpenGLFunctionLoader::OpenGLFunctionLoader() {
CORRADE_INTERNAL_ASSERT_OUTPUT(library = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY)); 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<const GLubyte*>(name)); return glXGetProcAddressARB(reinterpret_cast<const GLubyte*>(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 */ /* Otherwise unsupported */
#else #else
#error unsupported platform #error unsupported platform

12
src/Magnum/Platform/Implementation/OpenGLFunctionLoader.h

@ -27,7 +27,7 @@
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#ifdef CORRADE_TARGET_WINDOWS #if defined(CORRADE_TARGET_WINDOWS) && !defined(MAGNUM_PLATFORM_USE_EGL)
#define WIN32_LEAN_AND_MEAN 1 #define WIN32_LEAN_AND_MEAN 1
#include <windows.h> #include <windows.h>
#endif #endif
@ -36,7 +36,7 @@ namespace Magnum { namespace Platform { namespace Implementation {
class OpenGLFunctionLoader { class OpenGLFunctionLoader {
public: public:
#ifndef CORRADE_TARGET_WINDOWS #if !defined(CORRADE_TARGET_WINDOWS) || defined(MAGNUM_PLATFORM_USE_EGL)
using FunctionPointer = void(*)(); using FunctionPointer = void(*)();
#else #else
using FunctionPointer = PROC; using FunctionPointer = PROC;
@ -48,8 +48,11 @@ class OpenGLFunctionLoader {
FunctionPointer load(const char* name); FunctionPointer load(const char* name);
private: private:
/* EGL-specific handles (nothing needed) */
#ifdef MAGNUM_PLATFORM_USE_EGL
/* CGL-specific handles */ /* CGL-specific handles */
#ifdef CORRADE_TARGET_APPLE #elif defined(CORRADE_TARGET_APPLE)
void* library; void* library;
/* WGL-specific handles */ /* WGL-specific handles */
@ -59,9 +62,6 @@ class OpenGLFunctionLoader {
/* GLX-specific handles (nothing needed) */ /* GLX-specific handles (nothing needed) */
#elif defined(CORRADE_TARGET_UNIX) && defined(MAGNUM_PLATFORM_USE_GLX) #elif defined(CORRADE_TARGET_UNIX) && defined(MAGNUM_PLATFORM_USE_GLX)
/* EGL-specific handles (nothing needed) */
#elif defined(MAGNUM_PLATFORM_USE_EGL)
/* Otherwise unsupported */ /* Otherwise unsupported */
#else #else
#error unsupported platform #error unsupported platform

170
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š <mosra@centrum.cz>
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 <Corrade/Utility/Assert.h>
#include <Corrade/Utility/Debug.h>
#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);
}
}}

228
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š <mosra@centrum.cz>
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 <memory>
#ifndef DOXYGEN_GENERATING_OUTPUT
#define WIN32_LEAN_AND_MEAN 1
#define VC_EXTRALEAN
#endif
#include <windows.h>
#include <EGL/egl.h>
#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<Platform::Context> _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
Loading…
Cancel
Save