From 8bc1793cab0a5c3acd7d9fa696d1df95de60f000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 21:41:50 +0100 Subject: [PATCH] Platform: make viewportEvent() only optional. Don't do anything to respond to viewport size by default, as the window has fixed size in most cases anyway (always fullscreen, canvas of fixed size in browser etc.). Makes the initial implementation requirements much simpler and shorter. --- doc/platform.dox | 35 +++++++++++++++++------- src/Platform/AbstractXApplication.cpp | 1 + src/Platform/AbstractXApplication.h | 2 +- src/Platform/GlutApplication.cpp | 1 + src/Platform/GlutApplication.h | 11 ++++---- src/Platform/GlxApplication.h | 9 +++--- src/Platform/NaClApplication.cpp | 1 + src/Platform/NaClApplication.h | 11 ++++---- src/Platform/ScreenedApplication.h | 12 +++----- src/Platform/ScreenedApplication.hpp | 2 ++ src/Platform/Sdl2Application.cpp | 1 + src/Platform/Sdl2Application.h | 26 ++++++++++-------- src/Platform/WindowlessGlxApplication.h | 3 +- src/Platform/WindowlessNaClApplication.h | 5 ++-- src/Platform/XEglApplication.h | 9 +++--- 15 files changed, 78 insertions(+), 51 deletions(-) diff --git a/doc/platform.dox b/doc/platform.dox index 92574996b..fe4f82af3 100644 --- a/doc/platform.dox +++ b/doc/platform.dox @@ -47,10 +47,9 @@ Windowed applications provide a window and keyboard and mouse handling. The most basic toolkit (and toolkit packaged for most systems) is GLUT, which is implemented in @ref Platform::GlutApplication. As said above, the usage is similar for all toolkits, you must provide one-argument constructor and -implement at least @ref GlutApplication::viewportEvent() "viewportEvent()" and -@ref GlutApplication::drawEvent() "drawEvent()". The class can be then used -directly in `main()`, but for convenience and portability it's better to use -@ref MAGNUM_GLUTAPPLICATION_MAIN() macro. +implement at least @ref GlutApplication::drawEvent() "drawEvent()" function. +The class can be then used directly in `main()`, but for convenience and +portability it's better to use @ref MAGNUM_GLUTAPPLICATION_MAIN() macro. To simplify the porting, the library provides `Platform::Application` typedef and `MAGNUM_APPLICATION_MAIN()` macro (but only if only one application header @@ -78,7 +77,6 @@ class MyApplication: public Platform::Application { MyApplication(const Arguments& arguments); private: - void viewportEvent(const Vector2i& viewport) override; void drawEvent() override; }; @@ -87,11 +85,6 @@ MyApplication::MyApplication(const Arguments& arguments): Platform::Application( 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(DefaultFramebuffer::Clear::Color); @@ -104,6 +97,28 @@ void MyApplication::drawEvent() { MAGNUM_APPLICATION_MAIN(MyApplication) @endcode +@subsection platform-windowed-viewport Responding to viewport size changes + +By default the application doesn't respond to window size changes in any way, +as the window has fixed size in most cases. To respond to size change for +example by resizing the default framebuffer, you need to reimplement +@ref GlutApplication::viewportEvent() "viewportEvent()" function and pass the +new size to the framebuffer: +@code +class MyApplication: public Platform::Application { + // ... + + private: + void viewportEvent(const Vector2i& size) override; +}; + +// ... + +void MyApplication::viewportEvent(const Vector2i& size) { + defaultFramebuffer.setViewport({{}, size}); +} +@endcode + @section platform-windowless Windowless applications Windowless applications provide just a context for ofscreen rendering or diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index b01fbddd9..20c33d53b 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -169,6 +169,7 @@ int AbstractXApplication::exec() { return 0; } +void AbstractXApplication::viewportEvent(const Vector2i&) {} void AbstractXApplication::keyPressEvent(KeyEvent&) {} void AbstractXApplication::keyReleaseEvent(KeyEvent&) {} void AbstractXApplication::mousePressEvent(MouseEvent&) {} diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index b1cd8c867..653a24092 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -125,7 +125,7 @@ class AbstractXApplication { private: #endif /** @copydoc Sdl2Application::viewportEvent() */ - virtual void viewportEvent(const Vector2i& size) = 0; + virtual void viewportEvent(const Vector2i& size); /** @copydoc Sdl2Application::drawEvent() */ virtual void drawEvent() = 0; diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index cce9242c0..f1e178d8a 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -111,6 +111,7 @@ void GlutApplication::staticMouseMoveEvent(int x, int y) { instance->mouseMoveEvent(e); } +void GlutApplication::viewportEvent(const Vector2i&) {} void GlutApplication::keyPressEvent(KeyEvent&) {} void GlutApplication::keyReleaseEvent(KeyEvent&) {} void GlutApplication::mousePressEvent(MouseEvent&) {} diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index e7267abe7..8e7391078 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -58,13 +58,14 @@ in CMake, add `${MAGNUM_GLUTAPPLICATION_INCLUDE_DIRS}` to include path and link to `${MAGNUM_GLUTAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See -@ref building, @ref cmake and @ref platform for more information. +@ref building and @ref cmake for more information. @section GlutApplication-usage Usage -You need to implement at least @ref drawEvent() and @ref viewportEvent() to be -able to draw on the screen. The subclass can be then used directly in `main()` --- see convenience macro @ref MAGNUM_GLUTAPPLICATION_MAIN(). +You need to implement at least @ref drawEvent() to be able to draw on the +screen. The subclass can be then used directly in `main()` -- see convenience +macro @ref MAGNUM_GLUTAPPLICATION_MAIN(). See @ref platform for more +information. @code class MyApplication: public Platform::GlutApplication { // implement required methods... @@ -151,7 +152,7 @@ class GlutApplication { private: #endif /** @copydoc Sdl2Application::viewportEvent() */ - virtual void viewportEvent(const Vector2i& size) = 0; + virtual void viewportEvent(const Vector2i& size); /** @copydoc Sdl2Application::drawEvent() */ virtual void drawEvent() = 0; diff --git a/src/Platform/GlxApplication.h b/src/Platform/GlxApplication.h index a0042304b..66fa3e4a4 100644 --- a/src/Platform/GlxApplication.h +++ b/src/Platform/GlxApplication.h @@ -46,13 +46,14 @@ CMake. To use it, you need to request `%GlxApplication` component in CMake, add `${MAGNUM_GLXAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See -@ref building, @ref cmake and @ref platform for more information. +@ref building and @ref cmake for more information. @section GlxApplication-usage Usage -You need to implement at least @ref drawEvent() and @ref viewportEvent() to be -able to draw on the screen. The subclass can be then used directly in `main()` --- see convenience macro @ref MAGNUM_GLXAPPLICATION_MAIN(). +You need to implement at least @ref drawEvent() to be able to draw on the +screen. The subclass can be then used directly in `main()` -- see convenience +macro @ref MAGNUM_GLXAPPLICATION_MAIN(). See @ref platform for more +information. @code class MyApplication: public Platform::GlxApplication { // implement required methods... diff --git a/src/Platform/NaClApplication.cpp b/src/Platform/NaClApplication.cpp index bdb34e5e6..4e8385543 100644 --- a/src/Platform/NaClApplication.cpp +++ b/src/Platform/NaClApplication.cpp @@ -251,6 +251,7 @@ void NaClApplication::mouseLockCallback(void* applicationInstance, std::int32_t) instance->flags |= Flag::MouseLocked; } +void NaClApplication::viewportEvent(const Vector2i&) {} void NaClApplication::keyPressEvent(KeyEvent&) {} void NaClApplication::keyReleaseEvent(KeyEvent&) {} void NaClApplication::mousePressEvent(MouseEvent&) {} diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 0c9203f03..0377f76b8 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -63,13 +63,14 @@ to request `%NaClApplication` component in CMake, add `${MAGNUM_NACLAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See -@ref building, @ref cmake and @ref platform for more information. +@ref building and @ref cmake for more information. @section NaClApplication-usage Usage -You need to implement at least @ref drawEvent() and @ref viewportEvent() to be -able to draw on the screen. The subclass must be then registered to NaCl API -using @ref MAGNUM_NACLAPPLICATION_MAIN() macro. +You need to implement at least @ref drawEvent() to be able to draw on the +screen. The subclass must be then registered to NaCl API using +@ref MAGNUM_NACLAPPLICATION_MAIN() macro. See @ref platform for more +information. @code class MyApplication: public Platform::NaClApplication { // implement required methods... @@ -218,7 +219,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public private: #endif /** @copydoc Sdl2Application::viewportEvent() */ - virtual void viewportEvent(const Vector2i& size) = 0; + virtual void viewportEvent(const Vector2i& size); /** @copydoc Sdl2Application::drawEvent() */ virtual void drawEvent() = 0; diff --git a/src/Platform/ScreenedApplication.h b/src/Platform/ScreenedApplication.h index 2836a63b1..fc7e0a468 100644 --- a/src/Platform/ScreenedApplication.h +++ b/src/Platform/ScreenedApplication.h @@ -170,15 +170,11 @@ template class BasicScreenedApplication: public Application, * @brief Global viewport event * * Called when window size changes, *before* all screens' - * @ref BasicScreen::viewportEvent() "viewportEvent()". You should at - * least pass the new size to @ref DefaultFramebuffer::setViewport(). - * - * Note that this function might not get called at all if the window - * size doesn't change. You are responsible for configuring the initial - * state yourself, viewport of default framebuffer can be retrieved - * from @ref DefaultFramebuffer::viewport(). + * @ref BasicScreen::viewportEvent() "viewportEvent()". Default + * implementation does nothing. See @ref Sdl2Application::viewportEvent() "*Application::viewportEvent()" + * for more information. */ - virtual void globalViewportEvent(const Vector2i& size) = 0; + virtual void globalViewportEvent(const Vector2i& size); /** * @brief Draw event diff --git a/src/Platform/ScreenedApplication.hpp b/src/Platform/ScreenedApplication.hpp index 2063c51fb..1a27d2269 100644 --- a/src/Platform/ScreenedApplication.hpp +++ b/src/Platform/ScreenedApplication.hpp @@ -72,6 +72,8 @@ template BasicScreenedApplication& BasicScreened return *this; } +template void BasicScreenedApplication::globalViewportEvent(const Vector2i&) {} + template void BasicScreenedApplication::viewportEvent(const Vector2i& size) { /* Call viewport event after all other (because of framebuffer resizing) */ globalViewportEvent(size); diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index 2f5b7785a..417daa0e4 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -244,6 +244,7 @@ void Sdl2Application::setMouseLocked(bool enabled) { #endif } +void Sdl2Application::viewportEvent(const Vector2i&) {} void Sdl2Application::keyPressEvent(KeyEvent&) {} void Sdl2Application::keyReleaseEvent(KeyEvent&) {} void Sdl2Application::mousePressEvent(MouseEvent&) {} diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 7df1cbf30..073ea799b 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -64,13 +64,14 @@ to find SDL2), request `%Sdl2Application` component in CMake, add `${MAGNUM_SDL2APPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See -@ref building, @ref cmake and @ref platform for more information. +@ref building and @ref cmake for more information. @section Sdl2Application-usage Usage -You need to implement at least @ref drawEvent() and @ref viewportEvent() to be -able to draw on the screen. The subclass can be then used directly in `main()` --- see convenience macro @ref MAGNUM_SDL2APPLICATION_MAIN(). +You need to implement at least @ref drawEvent() to be able to draw on the +screen. The subclass can be then used directly in `main()` -- see convenience +macro @ref MAGNUM_SDL2APPLICATION_MAIN(). See @ref platform for more +information. @code class MyApplication: public Platform::Sdl2Application { // implement required methods... @@ -235,16 +236,19 @@ class Sdl2Application { /** * @brief Viewport event * - * Called when window size changes. You should pass the new size to - * @ref DefaultFramebuffer::setViewport() and possibly elsewhere - * (cameras, other framebuffers...). + * Called when window size changes. The default implementation does + * nothing, if you want to respond to size changes, you should pass the + * new size to @ref DefaultFramebuffer::setViewport() and possibly + * elsewhere (to @ref SceneGraph::AbstractCamera::setViewport() "SceneGraph::Camera*D::setViewport()", + * other framebuffers...). * * Note that this function might not get called at all if the window - * size doesn't change. You are responsible for configuring the initial - * state yourself, viewport of default framebuffer can be retrieved - * from @ref DefaultFramebuffer::viewport(). + * size doesn't change. You should configure the initial state of your + * cameras, framebuffers etc. in application constructor rather than + * relying on this function to be called. Viewport of default + * framebuffer can be retrieved via @ref DefaultFramebuffer::viewport(). */ - virtual void viewportEvent(const Vector2i& size) = 0; + virtual void viewportEvent(const Vector2i& size); /** * @brief Draw event diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index 3b531f85e..dd5ec4193 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -56,12 +56,13 @@ include path and link to `${MAGNUM_WINDOWLESSGLXAPPLICATION_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. See -@ref building, @ref cmake and @ref platform for more information. +@ref building and @ref cmake for more information. @section WindowlessGlxApplication-usage Usage Place your code into @ref exec(). The subclass can be then used directly in `main()` -- see convenience macro @ref MAGNUM_WINDOWLESSGLXAPPLICATION_MAIN(). +See @ref platform for more information. @code class MyApplication: public Platform::WindowlessGlxApplication { // implement required methods... diff --git a/src/Platform/WindowlessNaClApplication.h b/src/Platform/WindowlessNaClApplication.h index 277b82111..a6f2a55ef 100644 --- a/src/Platform/WindowlessNaClApplication.h +++ b/src/Platform/WindowlessNaClApplication.h @@ -60,12 +60,13 @@ you need to request `%WindowlessNaClApplication` component in CMake, add application is requested, you can also use generic `${MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS}` and `${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` aliases to simplify porting. See -@ref building, @ref cmake and @ref platform for more information. +@ref building and @ref cmake for more information. @section WindowlessNaClApplication-usage Usage Place your code into @ref exec(). The subclass must be then registered to NaCl -API using @ref MAGNUM_WINDOWLESSNACLAPPLICATION_MAIN() macro. +API using @ref MAGNUM_WINDOWLESSNACLAPPLICATION_MAIN() macro. See @ref platform +for more information. @code class MyApplication: public Platform::WindowlessNaClApplication { // implement required methods... diff --git a/src/Platform/XEglApplication.h b/src/Platform/XEglApplication.h index dc7aae7f2..67f75d4d6 100644 --- a/src/Platform/XEglApplication.h +++ b/src/Platform/XEglApplication.h @@ -47,13 +47,14 @@ request `%XEglApplication` component in CMake, add `${MAGNUM_XEGLAPPLICATION_INC to include path and link to `${MAGNUM_XEGLAPPLICATION_LIBRARIES}`. If no other application is requested, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_APPLICATION_LIBRARIES}` aliases to simplify porting. See -@ref building, @ref cmake and @ref platform for more information. +@ref building and @ref cmake for more information. @section XEglApplication-usage Usage -You need to implement at least @ref drawEvent() and @ref viewportEvent() to be -able to draw on the screen. The subclass can be then used directly in `main()` --- see convenience macro @ref MAGNUM_XEGLAPPLICATION_MAIN(). +You need to implement at least @ref drawEvent() to be able to draw on the +screen. The subclass can be then used directly in `main()` -- see convenience +macro @ref MAGNUM_XEGLAPPLICATION_MAIN(). See @ref platform for more +information. @code class MyApplication: public Platform::XEglApplication { // implement required methods...