mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
197 lines
6.8 KiB
197 lines
6.8 KiB
/* |
|
This file is part of Magnum. |
|
|
|
Copyright © 2010, 2011, 2012, 2013 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. |
|
*/ |
|
|
|
namespace Magnum { namespace Platform { |
|
/** @page platform Platform support |
|
|
|
@brief Integration into windowing toolkits and creation of windowless contexts |
|
|
|
@tableofcontents |
|
|
|
Platform namespace provides classes integrating %Magnum engine into various |
|
toolkits, both windowed and windowless. All the classes have common API to |
|
achieve static polymorphism, so basically you can use different toolkits on |
|
different platforms and the only thing you need to change is the class name, |
|
everything else is the same. |
|
|
|
Basic usage is to subclass the chosen `*Application` class and implement |
|
required methods. |
|
|
|
@section platform-windowed Windowed applications |
|
|
|
Windowed applications provide a window and keyboard and mouse handling. The |
|
most basic toolkit (and toolkit available on most platforms) is GLUT, which is |
|
is implemented in GlutApplication. As said above, the usage is similar for all |
|
toolkits, you must provide two-argument constructor and implement at least |
|
@ref GlutApplication::viewportEvent() "viewportEvent()" and |
|
@ref GlutApplication::drawEvent() "drawEvent()". |
|
|
|
Barebone application implementation which will just clear the window to dark |
|
blue color: |
|
@code |
|
#include <DefaultFramebuffer.h> |
|
#include <Renderer.h> |
|
#include <Platform/GlutApplication.h> |
|
|
|
using namespace Magnum; |
|
|
|
class MyApplication: public Platform::GlutApplication { |
|
public: |
|
MyApplication(const Arguments& arguments); |
|
|
|
void viewportEvent(const Vector2i& viewport) override; |
|
void drawEvent() override; |
|
}; |
|
|
|
MyApplication::MyApplication(const Arguments& arguments): Platform::GlutApplication(arguments) { |
|
// Set clear color to dark blue |
|
Renderer::setClearColor({0.0f, 0.0f, 0.4f}); |
|
} |
|
|
|
void MyApplication::viewportEvent(const Vector2i& size) { |
|
// Resize the framebuffer to new window size |
|
defaultFramebuffer.setViewport({{}, size}); |
|
} |
|
|
|
void MyApplication::drawEvent() { |
|
// Clear the window |
|
defaultFramebuffer.clear(); |
|
|
|
// The context is double-buffered, swap buffers |
|
swapBuffers(); |
|
} |
|
|
|
// main() function implementation |
|
MAGNUM_GLUTAPPLICATION_MAIN(MyApplication) |
|
@endcode |
|
|
|
@section platform-windowless Windowless applications |
|
|
|
Windowless applications provide just a context for ofscreen rendering or |
|
performing tasks on GPU. There is not yet any platform-independent toolkit |
|
which could handle this in portable way, thus you have to use platform-specific |
|
ones. As example we use WindowlessGlxApplication, you need to implement just |
|
@ref WindowlessGlxApplication::exec() "exec()" function. |
|
|
|
Barebone application which will just print out current OpenGL version and |
|
renderer string and exits: |
|
@code |
|
#include <Context.h> |
|
#include <Platform/WindowlessGlxApplication.h> |
|
|
|
using namespace Magnum; |
|
|
|
class MyApplication: public Platform::WindowlessGlxApplication { |
|
public: |
|
MyApplication(const Arguments& arguments); |
|
|
|
int exec() override; |
|
}; |
|
|
|
MyApplication::MyApplication(const Arguments& arguments): Platform::WindowlessGlxApplication(arguments) {} |
|
|
|
int MyApplication::exec() { |
|
Debug() << "OpenGL version:" << Context::current()->versionString(); |
|
Debug() << "OpenGL renderer:" << Context::current()->rendererString(); |
|
|
|
// Exit with success |
|
return 0; |
|
} |
|
|
|
// main() function implementation |
|
MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN(MyApplication) |
|
@endcode |
|
|
|
@section platform-compilation Compilation with CMake |
|
|
|
Barebone compilation consists just of finding %Magnum library with required |
|
`*Application` component, compilation of the executable and linking the |
|
libraries to it: |
|
@code |
|
find_package(Magnum REQUIRED GlutApplication) |
|
|
|
include_directories(${MAGNUM_INCLUDE_DIRS}) |
|
|
|
add_executable(myapplication MyApplication.cpp) |
|
target_link_libraries(myapplication |
|
${MAGNUM_LIBRARIES} |
|
${MAGNUM_GLUTAPPLICATION_LIBRARIES}) |
|
@endcode |
|
|
|
@section platform-configuration Specifying configuration |
|
|
|
By default the application is created with some reasonable defaults (e.g. |
|
window size 800x600 pixels). If you want something else, you can pass |
|
@ref GlutApplication::Configuration "Configuration" instance to application |
|
constructor. Using method chaining it can be done conveniently like this: |
|
@code |
|
MyApplication::MyApplication(int& argc, char** argv): |
|
Platform::GlutApplication(argc, argv, (new Configuration()) |
|
->setTitle("My Application")->setSize({800, 600}) { |
|
// ... |
|
} |
|
@endcode |
|
|
|
However, sometimes you would need to configure the application based on some |
|
configuration file or system introspection. In that case you can pass `nullptr` |
|
instead of Configuration instance and then specify it later with |
|
@ref GlutApplication::createContext() "createContext()": |
|
@code |
|
MyApplication::MyApplication(int& argc, char** argv): Platform::GlutApplication(argc, argv, nullptr) { |
|
// ... |
|
|
|
createContext((new Configuration()) |
|
->setTitle("My Application") |
|
->setSize(size)); |
|
|
|
// ... |
|
} |
|
@endcode |
|
|
|
The configuration passed to constructor and @ref GlutApplication::createContext() "createContext()" |
|
is automaticall deleted afterwards and if the context creation fails, the |
|
application exits. However, it is also possible to negotiate the context using |
|
@ref GlutApplication::tryCreateContext() "tryCreateContext()". The major |
|
difference is that this function returns `false` instead of exiting and it |
|
doesn't delete the configuration afterwards so you can reuse it. You can for |
|
example try enabling MSAA and if the context creation fails, fall back to |
|
no-AA rendering: |
|
@code |
|
MyApplication::MyApplication(int& argc, char** argv): Platform::GlutApplication(argc, argv, nullptr) { |
|
// ... |
|
|
|
auto conf = new Configuration; |
|
conf->setTitle("My Application") |
|
->setSampleCount(16); |
|
|
|
if(!tryCreateContext(conf)) |
|
createContext(conf->setSampleCount(0)); |
|
else delete conf; |
|
|
|
// ... |
|
} |
|
@endcode |
|
|
|
*/ |
|
}}
|
|
|