From 2e21577254601c3e0b7553f93b5f60a3e818e392 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 6 Dec 2013 13:19:31 +0100 Subject: [PATCH 01/32] Math: really install deprecated headers. Dammit. Sorry about this :-) --- src/Math/Geometry/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Math/Geometry/CMakeLists.txt b/src/Math/Geometry/CMakeLists.txt index ad0e92d5e..fafc17d75 100644 --- a/src/Math/Geometry/CMakeLists.txt +++ b/src/Math/Geometry/CMakeLists.txt @@ -26,14 +26,14 @@ set(MagnumMathGeometry_HEADERS Distance.h Intersection.h) -install(FILES ${MagnumMathGeometry_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Math/Geometry) - # Deprecated headers if(BUILD_DEPRECATED) set(MagnumMathGeometry_HEADERS ${MagnumMathGeometry_HEADERS} Rectangle.h) endif() +install(FILES ${MagnumMathGeometry_HEADERS} DESTINATION ${MAGNUM_INCLUDE_INSTALL_DIR}/Math/Geometry) + if(BUILD_TESTS) add_subdirectory(Test) endif() From cf3ae0eee7fb252ecc9760e721cded29dbf894ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 6 Dec 2013 13:45:04 +0100 Subject: [PATCH 02/32] Revert "Math: don't allow *::data() to be called on rvalues." The pointer conversion can be done only explicitly, thus the users will always know what they are doing. With that change, perfectly valid things like this couldn't be done (the result of a + b is kept until the semicolon): Vector3 a, b; void foo(float* data); foo((a + b).data()); Moreover this conversion wasn't even properly tested, leading to issues as in mosra/corrade@781f5df38a7b1b366f3de477dd5fe641eca6ed20. This reverts commit add989703e694f7719e015cc12717d9953de0322. --- src/Math/RectangularMatrix.h | 16 ++-------------- src/Math/Vector.h | 16 ++-------------- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/src/Math/RectangularMatrix.h b/src/Math/RectangularMatrix.h index 89b365c56..cbb0a685f 100644 --- a/src/Math/RectangularMatrix.h +++ b/src/Math/RectangularMatrix.h @@ -164,20 +164,8 @@ template class RectangularMatrix { * * @see operator[] */ - T* data() - #ifndef CORRADE_GCC47_COMPATIBILITY - & - #endif - { return _data[0].data(); } - - /** @overload */ - constexpr const T* data() - #ifndef CORRADE_GCC47_COMPATIBILITY - const & - #else - const - #endif - { return _data[0].data(); } + T* data() { return _data[0].data(); } + constexpr const T* data() const { return _data[0].data(); } /**< @overload */ /** * @brief %Matrix column diff --git a/src/Math/Vector.h b/src/Math/Vector.h index d4a1f6950..89e7b8f55 100644 --- a/src/Math/Vector.h +++ b/src/Math/Vector.h @@ -184,20 +184,8 @@ template class Vector { * * @see operator[]() */ - T* data() - #ifndef CORRADE_GCC47_COMPATIBILITY - & - #endif - { return _data; } - - /** @overload */ - constexpr const T* data() - #ifndef CORRADE_GCC47_COMPATIBILITY - const & - #else - const - #endif - { return _data; } + T* data() { return _data; } + constexpr const T* data() const { return _data; } /**< @overload */ /** * @brief Value at given position From 3b03da5d5ed195f0ae37055359bd9c29afbd83f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 6 Dec 2013 14:00:05 +0100 Subject: [PATCH 03/32] Made ImageReference data pointer constant. ImageReference is supposed to be wrapper around existing data array of some type which is passed to Magnum functions. Thus modifying the original data array (which must be kept somewhere for proper deletion) is much better option than casting the pointer returned by data() to some proper type and then operating on that. Hopefully this won't break any existing code. --- src/ImageReference.h | 12 +++++------- .../TgaImageConverter/Test/TgaImageConverterTest.cpp | 3 +-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/ImageReference.h b/src/ImageReference.h index f41007d2c..7532c103e 100644 --- a/src/ImageReference.h +++ b/src/ImageReference.h @@ -48,7 +48,6 @@ to change image properties, only data pointer. Interchangeable with Image, BufferImage or Trade::ImageData. @see ImageReference1D, ImageReference2D, ImageReference3D -@todo Provide const version somewhat */ template class ImageReference: public AbstractImage { public: @@ -61,7 +60,7 @@ template class ImageReference: public AbstractImage { * @param size %Image size * @param data %Image data */ - constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} + constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, const void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast(data)) {} /** * @brief Constructor @@ -78,8 +77,7 @@ template class ImageReference: public AbstractImage { constexpr typename DimensionTraits::VectorType size() const { return _size; } /** @brief Pointer to raw data */ - unsigned char* data() { return _data; } - constexpr const unsigned char* data() const { return _data; } /**< @overload */ + constexpr const unsigned char* data() const { return _data; } /** * @brief Set image data @@ -89,13 +87,13 @@ template class ImageReference: public AbstractImage { * passed in constructor. The data are not copied nor deleted on * destruction. */ - void setData(void* data) { - _data = reinterpret_cast(data); + void setData(const void* data) { + _data = reinterpret_cast(data); } private: Math::Vector _size; - unsigned char* _data; + const unsigned char* _data; }; /** @brief One-dimensional image wrapper */ diff --git a/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp index a63aa1c14..0a03fcd45 100644 --- a/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp +++ b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp @@ -49,8 +49,7 @@ class TgaImageConverterTest: public TestSuite::Tester { }; namespace { - /** @todo `const` when ImageReference is sane */ - char originalData[] = { + constexpr const char originalData[] = { 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7, 6, 7, 8 From fb1a8490ea2ee4e5bfdbc2696e230f5d1f7d3ed2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 6 Dec 2013 14:04:16 +0100 Subject: [PATCH 04/32] Disallow conversion of const {Image,Trade::ImageData}&& to ImageReference. The conversion is done implicitly, thus this seemingly innocent code would be allowed: ImageReference2D reference = Image2D(...); foo(reference.data()); // crash on access, data already deleted --- src/Image.h | 26 +++++++++++++++++++------- src/Test/ImageTest.cpp | 11 ++++++++++- src/Trade/ImageData.h | 26 +++++++++++++++++++------- src/Trade/Test/ImageDataTest.cpp | 11 ++++++++++- 4 files changed, 58 insertions(+), 16 deletions(-) diff --git a/src/Image.h b/src/Image.h index 6c171af4e..18dcd3b9b 100644 --- a/src/Image.h +++ b/src/Image.h @@ -80,12 +80,18 @@ template class Image: public AbstractImage { /** @brief Destructor */ ~Image() { delete[] _data; } - /** - * @brief Conversion to reference - * - * @todo GCC 4.8: don't allow this on rvalue-ref - */ - /*implicit*/ operator ImageReference() const; + /** @brief Conversion to reference */ + /*implicit*/ operator ImageReference() + #ifndef CORRADE_GCC47_COMPATIBILITY + const &; + #else + const; + #endif + + #ifndef CORRADE_GCC47_COMPATIBILITY + /** @overload */ + /*implicit*/ operator ImageReference() const && = delete; + #endif /** @brief %Image size */ typename DimensionTraits::VectorType size() const { return _size; } @@ -132,7 +138,13 @@ template inline Image& Image::op return *this; } -template inline Image::operator ImageReference() const { +template inline Image::operator ImageReference() +#ifndef CORRADE_GCC47_COMPATIBILITY +const & +#else +const +#endif +{ return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } diff --git a/src/Test/ImageTest.cpp b/src/Test/ImageTest.cpp index 6948f9c8d..75849d5f7 100644 --- a/src/Test/ImageTest.cpp +++ b/src/Test/ImageTest.cpp @@ -71,13 +71,22 @@ void ImageTest::moveAssignment() { void ImageTest::toReference() { unsigned char* data = new unsigned char[3]; - Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); + const Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); ImageReference2D b = a; CORRADE_COMPARE(b.format(), ColorFormat::Red); CORRADE_COMPARE(b.type(), ColorType::UnsignedByte); CORRADE_COMPARE(b.size(), Vector2i(1, 3)); CORRADE_VERIFY(b.data() == data); + + CORRADE_VERIFY((std::is_convertible::value)); + { + #ifdef CORRADE_GCC47_COMPATIBILITY + CORRADE_EXPECT_FAIL("Rvalue references for *this are not supported in GCC < 4.8.1."); + #endif + CORRADE_VERIFY(!(std::is_convertible::value)); + CORRADE_VERIFY(!(std::is_convertible::value)); + } } }} diff --git a/src/Trade/ImageData.h b/src/Trade/ImageData.h index 098461302..e06f973f0 100644 --- a/src/Trade/ImageData.h +++ b/src/Trade/ImageData.h @@ -70,12 +70,18 @@ template class ImageData: public AbstractImage { /** @brief Destructor */ ~ImageData() { delete[] _data; } - /** - * @brief Conversion to reference - * - * @todo GCC 4.8: don't allow this on rvalue-ref - */ - /*implicit*/ operator ImageReference() const; + /** @brief Conversion to reference */ + /*implicit*/ operator ImageReference() + #ifndef CORRADE_GCC47_COMPATIBILITY + const &; + #else + const; + #endif + + #ifndef CORRADE_GCC47_COMPATIBILITY + /** @overload */ + /*implicit*/ operator ImageReference() const && = delete; + #endif /** @brief %Image size */ typename DimensionTraits::VectorType size() const { return _size; } @@ -110,7 +116,13 @@ template inline ImageData& ImageData inline ImageData::operator ImageReference() const { +template inline ImageData::operator ImageReference() +#ifndef CORRADE_GCC47_COMPATIBILITY +const & +#else +const +#endif +{ return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } diff --git a/src/Trade/Test/ImageDataTest.cpp b/src/Trade/Test/ImageDataTest.cpp index bf1b9bb41..da3a7d39d 100644 --- a/src/Trade/Test/ImageDataTest.cpp +++ b/src/Trade/Test/ImageDataTest.cpp @@ -71,13 +71,22 @@ void ImageDataTest::moveAssignment() { void ImageDataTest::toReference() { unsigned char* data = new unsigned char[3]; - Trade::ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); + const Trade::ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 3}, data); ImageReference2D b = a; CORRADE_COMPARE(b.format(), ColorFormat::Red); CORRADE_COMPARE(b.type(), ColorType::UnsignedByte); CORRADE_COMPARE(b.size(), Vector2i(1, 3)); CORRADE_COMPARE(b.data(), data); + + CORRADE_VERIFY((std::is_convertible::value)); + { + #ifdef CORRADE_GCC47_COMPATIBILITY + CORRADE_EXPECT_FAIL("Rvalue references for *this are not supported in GCC < 4.8.1."); + #endif + CORRADE_VERIFY(!(std::is_convertible::value)); + CORRADE_VERIFY(!(std::is_convertible::value)); + } } }}} From 1c928424ae94cfbff975132336868224bdd64034 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 6 Dec 2013 16:28:32 +0100 Subject: [PATCH 05/32] Documentation updates for Image classes. --- src/BufferImage.h | 15 +++++++-------- src/Image.h | 12 ++++++------ src/ImageReference.h | 12 ++++++------ src/Trade/ImageData.h | 8 ++++---- 4 files changed, 23 insertions(+), 24 deletions(-) diff --git a/src/BufferImage.h b/src/BufferImage.h index fbc472d64..d92d62ef5 100644 --- a/src/BufferImage.h +++ b/src/BufferImage.h @@ -26,7 +26,7 @@ #ifndef MAGNUM_TARGET_GLES2 /** @file - * @brief Class Magnum::BufferImage, typedef Magnum::BufferImage1D, Magnum::BufferImage2D, Magnum::BufferImage3D + * @brief Class @ref Magnum::BufferImage, typedef @ref Magnum::BufferImage1D, @ref Magnum::BufferImage2D, @ref Magnum::BufferImage3D */ #endif @@ -41,9 +41,9 @@ namespace Magnum { /** @brief %Buffer image -Stores image data in GPU memory. Interchangeable with Image, ImageReference or -Trade::ImageData. -@see BufferImage1D, BufferImage2D, BufferImage3D, Buffer +Stores image data in GPU memory. Interchangeable with @ref Image, +@ref ImageReference or @ref Trade::ImageData. +@see @ref BufferImage1D, @ref BufferImage2D, @ref BufferImage3D, @ref Buffer @requires_gles30 Pixel buffer objects are not available in OpenGL ES 2.0. */ template class MAGNUM_EXPORT BufferImage: public AbstractImage { @@ -55,8 +55,8 @@ template class MAGNUM_EXPORT BufferImage: public Abstrac * @param format Format of pixel data * @param type Data type of pixel data * - * Dimensions and buffer are empty, call setData() to fill the image - * with data. + * Dimensions and buffer are empty, call @ref setData() to fill the + * image with data. */ explicit BufferImage(ColorFormat format, ColorType type): AbstractImage(format, type) { _buffer.setTargetHint(Buffer::Target::PixelPack); @@ -78,8 +78,7 @@ template class MAGNUM_EXPORT BufferImage: public Abstrac * * Updates the image buffer with given data. The data are not deleted * after filling the buffer. - * - * @see Buffer::setData() + * @see @ref Buffer::setData() */ void setData(const typename DimensionTraits::VectorType& size, ColorFormat format, ColorType type, const void* data, BufferUsage usage); diff --git a/src/Image.h b/src/Image.h index 18dcd3b9b..c66291ba0 100644 --- a/src/Image.h +++ b/src/Image.h @@ -25,7 +25,7 @@ */ /** @file - * @brief Class Magnum::Image, typedef Magnum::Image1D, Magnum::Image2D, Magnum::Image3D + * @brief Class @ref Magnum::Image, typedef @ref Magnum::Image1D, @ref Magnum::Image2D, @ref Magnum::Image3D */ #include "ImageReference.h" @@ -35,9 +35,9 @@ namespace Magnum { /** @brief %Image -Stores image data on client memory. Interchangeable with ImageReference, -BufferImage or Trade::ImageData. -@see Image1D, Image2D, Image3D +Stores image data on client memory. Interchangeable with @ref ImageReference, +@ref BufferImage or @ref Trade::ImageData. +@see @ref Image1D, @ref Image2D, @ref Image3D */ template class Image: public AbstractImage { public: @@ -60,8 +60,8 @@ template class Image: public AbstractImage { * @param format Format of pixel data * @param type Data type of pixel data * - * Dimensions and data pointer are set to zero, call setData() to fill - * the image with data. + * Dimensions are set to zero and data pointer to `nullptr`, call + * @ref setData() to fill the image with data. */ explicit Image(ColorFormat format, ColorType type): AbstractImage(format, type), _data(nullptr) {} diff --git a/src/ImageReference.h b/src/ImageReference.h index 7532c103e..d2f754e16 100644 --- a/src/ImageReference.h +++ b/src/ImageReference.h @@ -25,7 +25,7 @@ */ /** @file - * @brief Class Magnum::ImageReference + * @brief Class @ref Magnum::ImageReference, typedef @ref Magnum::ImageReference1D, @ref Magnum::ImageReference2D, @ref Magnum::ImageReference3D */ #include "Math/Vector3.h" @@ -40,14 +40,14 @@ namespace Magnum { Adds information about dimensions, color components and component type to some data in memory. -Unlike Image, this class doesn't delete the data on destruction, so it is +Unlike @ref Image, this class doesn't delete the data on destruction, so it is targeted for wrapping data which are either stored in stack/constant memory (and shouldn't be deleted) or they are managed by someone else and have the same properties for each frame, such as video stream. Thus it is not possible to change image properties, only data pointer. -Interchangeable with Image, BufferImage or Trade::ImageData. -@see ImageReference1D, ImageReference2D, ImageReference3D +Interchangeable with @ref Image, @ref BufferImage or @ref Trade::ImageData. +@see @ref ImageReference1D, @ref ImageReference2D, @ref ImageReference3D */ template class ImageReference: public AbstractImage { public: @@ -68,8 +68,8 @@ template class ImageReference: public AbstractImage { * @param type Data type of pixel data * @param size %Image size * - * Data pointer is set to zero, call setData() to fill the image with - * data. + * Data pointer is set to `nullptr`, call @ref setData() to fill the + * image with data. */ constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size): AbstractImage(format, type), _size(size), _data(nullptr) {} diff --git a/src/Trade/ImageData.h b/src/Trade/ImageData.h index e06f973f0..2c3652b26 100644 --- a/src/Trade/ImageData.h +++ b/src/Trade/ImageData.h @@ -25,7 +25,7 @@ */ /** @file - * @brief Class Magnum::Trade::ImageData + * @brief Class @ref Magnum::Trade::ImageData, typedef @ref Magnum::Trade::ImageData1D, @ref Magnum::Trade::ImageData2D, @ref Magnum::Trade::ImageData3D */ #include "ImageReference.h" @@ -35,9 +35,9 @@ namespace Magnum { namespace Trade { /** @brief %Image data -Access to image data provided by AbstractImporter subclasses. Interchangeable -with Image, ImageReference or BufferImage. -@see ImageData1D, ImageData2D, ImageData3D +Access to image data provided by @ref AbstractImporter subclasses. +Interchangeable with @ref Image, @ref ImageReference or @ref BufferImage. +@see @ref ImageData1D, @ref ImageData2D, @ref ImageData3D */ template class ImageData: public AbstractImage { public: From 5ae723c8d18ced03b1985120e0623d3ef39a4581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 6 Dec 2013 16:43:21 +0100 Subject: [PATCH 06/32] Added release() function to Image and Trade::ImageData. Allows the image to release ownership of the data. --- src/Image.h | 24 +++++++++++++++++++++++- src/Test/ImageTest.cpp | 13 ++++++++++++- src/Trade/ImageData.h | 23 ++++++++++++++++++++++- src/Trade/Test/ImageDataTest.cpp | 13 ++++++++++++- 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/Image.h b/src/Image.h index c66291ba0..1bdc52633 100644 --- a/src/Image.h +++ b/src/Image.h @@ -96,7 +96,11 @@ template class Image: public AbstractImage { /** @brief %Image size */ typename DimensionTraits::VectorType size() const { return _size; } - /** @brief Pointer to raw data */ + /** + * @brief Pointer to raw data + * + * @see @ref release() + */ unsigned char* data() { return _data; } const unsigned char* data() const { return _data; } /**< @overload */ @@ -109,9 +113,19 @@ template class Image: public AbstractImage { * * Deletes previous data and replaces them with new. Note that the * data are not copied, but they are deleted on destruction. + * @see @ref release() */ void setData(ColorFormat format, ColorType type, const typename DimensionTraits::VectorType& size, void* data); + /** + * @brief Release data storage + * + * Returns the data pointer and resets internal state to default. + * Deleting the returned array is user responsibility. + * @see @ref setData() + */ + unsigned char* release(); + private: Math::Vector _size; unsigned char* _data; @@ -148,6 +162,14 @@ const return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } +template inline unsigned char* Image::release() { + /** @todo I need `std::exchange` NOW. */ + unsigned char* const data = _data; + _size = {}; + _data = nullptr; + return data; +} + } #endif diff --git a/src/Test/ImageTest.cpp b/src/Test/ImageTest.cpp index 75849d5f7..1f81ace24 100644 --- a/src/Test/ImageTest.cpp +++ b/src/Test/ImageTest.cpp @@ -36,12 +36,14 @@ class ImageTest: public TestSuite::Tester { void moveConstructor(); void moveAssignment(); void toReference(); + void release(); }; ImageTest::ImageTest() { addTests({&ImageTest::moveConstructor, &ImageTest::moveAssignment, - &ImageTest::toReference}); + &ImageTest::toReference, + &ImageTest::release}); } void ImageTest::moveConstructor() { @@ -89,6 +91,15 @@ void ImageTest::toReference() { } } +void ImageTest::release() { + unsigned char data[] = {'c', 'a', 'f', 'e'}; + Image2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 4}, data); + const unsigned char* const pointer = a.release(); + CORRADE_COMPARE(pointer, data); + CORRADE_VERIFY(!a.data()); + CORRADE_VERIFY(a.size().isZero()); +} + }} CORRADE_TEST_MAIN(Magnum::Test::ImageTest) diff --git a/src/Trade/ImageData.h b/src/Trade/ImageData.h index 2c3652b26..a5e8691ba 100644 --- a/src/Trade/ImageData.h +++ b/src/Trade/ImageData.h @@ -86,10 +86,23 @@ template class ImageData: public AbstractImage { /** @brief %Image size */ typename DimensionTraits::VectorType size() const { return _size; } - /** @brief Pointer to raw data */ + /** + * @brief Pointer to raw data + * + * @see @ref release() + */ unsigned char* data() { return _data; } const unsigned char* data() const { return _data; } /**< @overload */ + /** + * @brief Release data storage + * + * Returns the data pointer and resets internal state to default. + * Deleting the returned array is user responsibility. + * @see @ref data() + */ + unsigned char* release(); + private: Math::Vector _size; unsigned char* _data; @@ -126,6 +139,14 @@ const return ImageReference(AbstractImage::format(), AbstractImage::type(), _size, _data); } +template inline unsigned char* ImageData::release() { + /** @todo I need `std::exchange` NOW. */ + unsigned char* const data = _data; + _size = {}; + _data = nullptr; + return data; +} + }} #endif diff --git a/src/Trade/Test/ImageDataTest.cpp b/src/Trade/Test/ImageDataTest.cpp index da3a7d39d..b805d2be9 100644 --- a/src/Trade/Test/ImageDataTest.cpp +++ b/src/Trade/Test/ImageDataTest.cpp @@ -36,12 +36,14 @@ class ImageDataTest: public TestSuite::Tester { void moveConstructor(); void moveAssignment(); void toReference(); + void release(); }; ImageDataTest::ImageDataTest() { addTests({&ImageDataTest::moveConstructor, &ImageDataTest::moveAssignment, - &ImageDataTest::toReference}); + &ImageDataTest::toReference, + &ImageDataTest::release}); } void ImageDataTest::moveConstructor() { @@ -89,6 +91,15 @@ void ImageDataTest::toReference() { } } +void ImageDataTest::release() { + unsigned char data[] = {'b', 'e', 'e', 'r'}; + ImageData2D a(ColorFormat::Red, ColorType::UnsignedByte, {1, 4}, data); + const unsigned char* const pointer = a.release(); + CORRADE_COMPARE(pointer, data); + CORRADE_VERIFY(!a.data()); + CORRADE_VERIFY(a.size().isZero()); +} + }}} CORRADE_TEST_MAIN(Magnum::Trade::Test::ImageDataTest) From af3ecdc126c1899a21a62d2f3abd4a932592e9cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 18:49:37 +0100 Subject: [PATCH 07/32] Platform: no need to have GlutApplication::redraw() virtual. The other implementations aren't virtual too. --- src/Platform/GlutApplication.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 6259be010..275c319ce 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -187,7 +187,7 @@ class GlutApplication { * Marks the window for redrawing, resulting in call to drawEvent() * in the next iteration. */ - virtual void redraw() { glutPostRedisplay(); } + void redraw() { glutPostRedisplay(); } /*@}*/ From 75ac846df1bd0bbb9c0ee039a44b82cba0ac5ba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 19:38:30 +0100 Subject: [PATCH 08/32] Platform: documentation updates. Sdl2Application is now taken as base implementation (it was GLUT previously) and all others are copying/referencing the documentation from it. When SDL2 is included in all major distributions (Ubuntu, I'm looking at you), it will replace GLUT as the default application. --- src/Platform/AbstractXApplication.h | 36 +++--- src/Platform/GlutApplication.h | 133 +++++----------------- src/Platform/GlxApplication.h | 10 +- src/Platform/NaClApplication.h | 55 ++++----- src/Platform/Sdl2Application.h | 139 ++++++++++++++++++----- src/Platform/WindowlessGlxApplication.h | 12 +- src/Platform/WindowlessNaClApplication.h | 18 +-- src/Platform/XEglApplication.h | 10 +- 8 files changed, 211 insertions(+), 202 deletions(-) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index ac7058384..12affaaa9 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -87,21 +87,21 @@ class AbstractXApplication { this is faster than public pure virtual destructor */ ~AbstractXApplication(); - /** @copydoc GlutApplication::createContext() */ + /** @copydoc Sdl2Application::createContext() */ void createContext(const Configuration& configuration); /** @{ @name Drawing functions */ - /** @copydoc GlutApplication::viewportEvent() */ + /** @copydoc Sdl2Application::viewportEvent() */ virtual void viewportEvent(const Vector2i& size) = 0; - /** @copydoc GlutApplication::drawEvent() */ + /** @copydoc Sdl2Application::drawEvent() */ virtual void drawEvent() = 0; - /** @copydoc GlutApplication::swapBuffers() */ + /** @copydoc Sdl2Application::swapBuffers() */ void swapBuffers(); - /** @copydoc GlutApplication::redraw() */ + /** @copydoc Sdl2Application::redraw() */ void redraw() { flags |= Flag::Redraw; } /*@}*/ @@ -170,7 +170,8 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::Flags) @brief %Configuration Double-buffered OpenGL context. -@see AbstractXApplication(), createContext() +@see @ref GlxApplication(), @ref XEglApplication(), @ref createContext(), + @ref tryCreateContext() @todo GLX_ARB_create_context_robustness/EGL_EXT_create_context_robustness */ class AbstractXApplication::Configuration { @@ -219,8 +220,9 @@ class AbstractXApplication::Configuration { /** @brief Base for input events -@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), keyReleaseEvent(), - mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent() +@see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(), + @ref keyReleaseEvent(), @ref mousePressEvent(), @ref mouseReleaseEvent(), + @ref mouseMoveEvent() */ class AbstractXApplication::InputEvent { InputEvent(const InputEvent&) = delete; @@ -233,7 +235,7 @@ class AbstractXApplication::InputEvent { /** * @brief %Modifier * - * @see Modifiers, modifiers() + * @see @ref Modifiers, @ref modifiers() */ enum class Modifier: unsigned int { Shift = ShiftMask, /**< Shift */ @@ -274,7 +276,7 @@ class AbstractXApplication::InputEvent { /** * @brief Set of modifiers * - * @see modifiers() + * @see @ref modifiers() */ typedef Containers::EnumSet Modifiers; @@ -296,10 +298,10 @@ class AbstractXApplication::InputEvent { */ typedef Containers::EnumSet Buttons; - /** @copydoc GlutApplication::InputEvent::setAccepted() */ + /** @copydoc Sdl2Application::InputEvent::setAccepted() */ void setAccepted(bool accepted = true) { _accepted = accepted; } - /** @copydoc GlutApplication::InputEvent::isAccepted() */ + /** @copydoc Sdl2Application::InputEvent::isAccepted() */ constexpr bool isAccepted() const { return _accepted; } /** @brief Modifiers */ @@ -326,7 +328,7 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::InputEvent::Buttons) /** @brief Key event -@see keyPressEvent(), keyReleaseEvent() +@see @ref keyPressEvent(), @ref keyReleaseEvent() */ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent { friend class AbstractXApplication; @@ -335,7 +337,7 @@ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent { /** * @brief Key * - * @see key() + * @see @ref key() */ enum class Key: KeySym { Enter = XK_Return, /**< Enter */ @@ -426,7 +428,7 @@ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent { /** @brief Mouse event -@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() +@see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent { friend class AbstractXApplication; @@ -435,7 +437,7 @@ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent /** * @brief Mouse button * - * @see button() + * @see @ref button() */ enum class Button: unsigned int { Left = Button1, /**< Left button */ @@ -461,7 +463,7 @@ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent /** @brief Mouse move event -@see MouseEvent, mouseMoveEvent() +@see @ref MouseEvent, @ref mouseMoveEvent() */ class AbstractXApplication::MouseMoveEvent: public AbstractXApplication::InputEvent { friend class AbstractXApplication; diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 275c319ce..6ad4c246a 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -90,15 +90,7 @@ class GlutApplication { class MouseEvent; class MouseMoveEvent; - /** - * @brief Default constructor - * @param arguments Application arguments - * @param configuration %Configuration - * - * Creates application with default or user-specified configuration. - * See Configuration for more information. The program exits if the - * context cannot be created, see below for an alternative. - */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ #ifdef DOXYGEN_GENERATING_OUTPUT explicit GlutApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); #else @@ -107,19 +99,10 @@ class GlutApplication { explicit GlutApplication(const Arguments& arguments); #endif - /** - * @brief Constructor - * @param arguments Application arguments - * - * Unlike above, the context is not created and must be created later - * with createContext() or tryCreateContext(). - */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit GlutApplication(const Arguments& arguments, std::nullptr_t); - /** - * @brief Execute main loop - * @return Value for returning from `main()`. - */ + /** @copydoc Sdl2Application::exec() */ int exec() { glutMainLoop(); return 0; @@ -130,74 +113,31 @@ class GlutApplication { faster than public pure virtual destructor */ ~GlutApplication(); - /** - * @brief Create context with given configuration - * - * Must be called if and only if the context wasn't created by the - * constructor itself. The program exits if the context cannot be - * created, see tryCreateContext() for an alternative. - */ + /** @copydoc Sdl2Application::createContext() */ void createContext(const Configuration& configuration); - /** - * @brief Try to create context with given configuration - * - * Unlike createContext() returns `false` if the context cannot be - * created, `true` otherwise. - */ + /** @copydoc Sdl2Application::tryCreateContext() */ bool tryCreateContext(const Configuration& configuration); /** @{ @name Drawing functions */ - /** - * @brief Viewport event - * - * Called when window size changes. You should pass the new size to - * DefaultFramebuffer::setViewport() and possibly elsewhere (cameras, - * 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(). - */ + /** @copydoc Sdl2Application::viewportEvent() */ virtual void viewportEvent(const Vector2i& size) = 0; - /** - * @brief Draw event - * - * Called when the screen is redrawn. You should clean the framebuffer - * using Framebuffer::clear() and then add your own drawing functions, - * such as calling SceneGraph::AbstractCamera::draw(). After drawing - * is finished, call swapBuffers(). If you want to draw immediately - * again, call also redraw(). - */ + /** @copydoc Sdl2Application::drawEvent() */ virtual void drawEvent() = 0; - /** - * @brief Swap buffers - * - * Paints currently rendered framebuffer on screen. - */ + /** @copydoc Sdl2Application::swapBuffers() */ void swapBuffers() { glutSwapBuffers(); } - /** - * @brief Redraw immediately - * - * Marks the window for redrawing, resulting in call to drawEvent() - * in the next iteration. - */ + /** @copydoc Sdl2Application::redraw() */ void redraw() { glutPostRedisplay(); } /*@}*/ /** @{ @name Keyboard handling */ - /** - * @brief Key press event - * - * Called when an key is pressed. Default implementation does nothing. - */ + /** @copydoc Sdl2Application::keyPressEvent() */ virtual void keyPressEvent(KeyEvent& event); /** @@ -226,7 +166,7 @@ class GlutApplication { /** * @brief Enable or disable mouse tracking * - * When mouse tracking is enabled, mouseMoveEvent() is called even + * When mouse tracking is enabled, @ref mouseMoveEvent() is called even * when no button is pressed. Mouse tracking is disabled by default. */ void setMouseTracking(bool enabled) { @@ -244,20 +184,10 @@ class GlutApplication { } protected: - /** - * @brief Mouse press event - * - * Called when mouse button is pressed. Default implementation does - * nothing. - */ + /** @copydoc Sdl2Application::mousePressEvent() */ virtual void mousePressEvent(MouseEvent& event); - /** - * @brief Mouse release event - * - * Called when mouse button is released. Default implementation does - * nothing. - */ + /** @copydoc Sdl2Application::mouseReleaseEvent() */ virtual void mouseReleaseEvent(MouseEvent& event); /** @@ -265,7 +195,7 @@ class GlutApplication { * * Called when any mouse button is pressed and mouse is moved. Default * implementation does nothing. - * @see setMouseTracking() + * @see @ref setMouseTracking() */ virtual void mouseMoveEvent(MouseMoveEvent& event); @@ -297,7 +227,7 @@ class GlutApplication { @brief %Configuration Double-buffered RGBA window with depth and stencil buffers. -@see GlutApplication(), createContext() +@see @ref GlutApplication(), @ref createContext(), @ref tryCreateContext() */ class GlutApplication::Configuration { Configuration(const Configuration&) = delete; @@ -362,8 +292,8 @@ class GlutApplication::Configuration { /** @brief Base for input events -@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), mousePressEvent(), - mouseReleaseEvent(), mouseMoveEvent() +@see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(), + @ref mousePressEvent(), @ref mouseReleaseEvent(), @ref mouseMoveEvent() */ class GlutApplication::InputEvent { InputEvent(const InputEvent&) = delete; @@ -372,15 +302,10 @@ class GlutApplication::InputEvent { InputEvent& operator=(InputEvent&&) = delete; public: - /** - * @brief Set event as accepted - * - * If the event is ignored (i.e., not set as accepted), it might be - * propagated elsewhere. By default is each event ignored. - */ + /** @copydoc Sdl2Application::InputEvent::setAccepted() */ void setAccepted(bool accepted = true) { _accepted = accepted; } - /** @brief Whether the event is accepted */ + /** @copydoc Sdl2Application::InputEvent::isAccepted() */ constexpr bool isAccepted() const { return _accepted; } protected: @@ -395,7 +320,7 @@ class GlutApplication::InputEvent { /** @brief Key event -@see keyPressEvent() +@see @ref keyPressEvent() */ class GlutApplication::KeyEvent: public GlutApplication::InputEvent { friend class GlutApplication; @@ -404,7 +329,7 @@ class GlutApplication::KeyEvent: public GlutApplication::InputEvent { /** * @brief Key * - * @see key() + * @see @ref key() */ enum class Key: int { Up = GLUT_KEY_UP, /**< Up arrow */ @@ -445,7 +370,7 @@ class GlutApplication::KeyEvent: public GlutApplication::InputEvent { /** @brief Mouse event -@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() +@see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class GlutApplication::MouseEvent: public GlutApplication::InputEvent { friend class GlutApplication; @@ -454,7 +379,7 @@ class GlutApplication::MouseEvent: public GlutApplication::InputEvent { /** * @brief Mouse button * - * @see button() + * @see @ref button() */ enum class Button: int { Left = GLUT_LEFT_BUTTON, /**< Left button */ @@ -480,7 +405,7 @@ class GlutApplication::MouseEvent: public GlutApplication::InputEvent { /** @brief Mouse move event -@see MouseEvent, mouseMoveEvent() +@see @ref MouseEvent, @ref mouseMoveEvent() */ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent { friend class GlutApplication; @@ -489,7 +414,7 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent { /** * @brief Mouse button * - * @see Buttons, buttons() + * @see @ref Buttons, @ref buttons() */ enum class Button: UnsignedByte { /** @@ -502,7 +427,7 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent { /** * @brief Set of mouse buttons * - * @see buttons() + * @see @ref buttons() */ typedef Containers::EnumSet Buttons; @@ -523,9 +448,9 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent { @brief Entry point for GLUT-based applications @param className Class name -Can be with GlutApplication subclasses used as equivalent to the following -code to achieve better portability, see @ref portability-applications for more -information. +Can be with @ref Magnum::Platform::GlutApplication "Platform::GlutApplication" +subclasses used as equivalent to the following code to achieve better +portability, see @ref portability-applications for more information. @code int main(int argc, char** argv) { className app({argc, argv}); diff --git a/src/Platform/GlxApplication.h b/src/Platform/GlxApplication.h index 03567f595..a0042304b 100644 --- a/src/Platform/GlxApplication.h +++ b/src/Platform/GlxApplication.h @@ -66,10 +66,10 @@ to simplify porting. */ class GlxApplication: public AbstractXApplication { public: - /** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ + /** @copydoc Sdl2Application::GlutApplication(const Arguments&, const Configuration&) */ explicit GlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); - /** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ + /** @copydoc Sdl2Application::GlutApplication(const Arguments&, std::nullptr_t) */ explicit GlxApplication(const Arguments& arguments, std::nullptr_t); protected: @@ -82,9 +82,9 @@ class GlxApplication: public AbstractXApplication { @brief Entry point for GLX-based applications @param className Class name -Can be used with GlxApplication subclasses as equivalent to the following code -to achieve better portability, see @ref portability-applications for more -information. +Can be used with @ref Magnum::Platform::GlxApplication "Platform::GlxApplication" +subclasses as equivalent to the following code to achieve better portability, +see @ref portability-applications for more information. @code int main(int argc, char** argv) { className app({argc, argv}); diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 5a5bd9dc8..34d8d88b3 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -148,7 +148,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public class MouseEvent; class MouseMoveEvent; - /** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ #ifdef DOXYGEN_GENERATING_OUTPUT explicit NaClApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); #else @@ -157,7 +157,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public explicit NaClApplication(const Arguments& arguments); #endif - /** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit NaClApplication(const Arguments& arguments, std::nullptr_t); /** @brief Whether the application runs fullscreen */ @@ -178,24 +178,24 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public faster than public pure virtual destructor */ ~NaClApplication(); - /** @copydoc GlutApplication::createContext() */ + /** @copydoc Sdl2Application::createContext() */ void createContext(const Configuration& configuration); - /** @copydoc GlutApplication::tryCreateContext() */ + /** @copydoc Sdl2Application::tryCreateContext() */ bool tryCreateContext(const Configuration& configuration); /** @{ @name Drawing functions */ - /** @copydoc GlutApplication::viewportEvent() */ + /** @copydoc Sdl2Application::viewportEvent() */ virtual void viewportEvent(const Vector2i& size) = 0; - /** @copydoc GlutApplication::drawEvent() */ + /** @copydoc Sdl2Application::drawEvent() */ virtual void drawEvent() = 0; - /** @copydoc GlutApplication::swapBuffers() */ + /** @copydoc Sdl2Application::swapBuffers() */ void swapBuffers(); - /** @copydoc GlutApplication::redraw() */ + /** @copydoc Sdl2Application::redraw() */ void redraw() { flags |= Flag::Redraw; } /*@}*/ @@ -232,8 +232,8 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public * @brief Enable or disable mouse locking * * When mouse is locked, the cursor is hidden and only - * MouseMoveEvent::relativePosition() is changing, absolute position - * stays the same. + * @ref MouseMoveEvent::relativePosition() is changing, absolute + * position stays the same. */ void setMouseLocked(bool enabled); @@ -309,7 +309,7 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public @brief %Configuration Double-buffered RGBA canvas with depth and stencil buffers. -@see NaClApplication(), createContext() +@see @ref NaClApplication(), @ref createContext() */ class NaClApplication::Configuration { Configuration(const Configuration&) = delete; @@ -357,10 +357,11 @@ class NaClApplication::Configuration { /** @brief Base for input events -If you accept the event, call setAccepted(), otherwise the event will be +If you accept the event, call @ref setAccepted(), otherwise the event will be propagated to the browser. -@see KeyEvent, MouseEvent, MouseMoveEvent, keyPressEvent(), keyReleaseEvent(), - mousePressEvent(), mouseReleaseEvent(), mouseMoveEvent() +@see @ref KeyEvent, @ref MouseEvent, @ref MouseMoveEvent, @ref keyPressEvent(), + @ref keyReleaseEvent(), @ref mousePressEvent(), @ref mouseReleaseEvent(), + @ref mouseMoveEvent() */ class NaClApplication::InputEvent { InputEvent(const InputEvent&) = delete; @@ -373,7 +374,7 @@ class NaClApplication::InputEvent { * @brief %Modifier * * @todo AltGr + PP_INPUTEVENT_MODIFIER_ISKEYPAD, PP_INPUTEVENT_MODIFIER_ISAUTOREPEAT - * @see Modifiers, modifiers() + * @see @ref Modifiers, @ref modifiers() */ enum class Modifier: std::uint32_t { Shift = PP_INPUTEVENT_MODIFIER_SHIFTKEY, /**< Shift */ @@ -414,7 +415,7 @@ class NaClApplication::InputEvent { /** * @brief Set of modifiers * - * @see modifiers() + * @see @ref modifiers() */ typedef Containers::EnumSet Modifiers; @@ -469,8 +470,8 @@ class NaClApplication::InputEvent { /** @brief Key event -See InputEvent for more information. -@see keyPressEvent(), keyReleaseEvent() +See also @ref InputEvent for more information. +@see @ref keyPressEvent(), @ref keyReleaseEvent() */ class NaClApplication::KeyEvent: public NaClApplication::InputEvent { friend class NaClApplication; @@ -480,7 +481,7 @@ class NaClApplication::KeyEvent: public NaClApplication::InputEvent { * @brief Key * * @todo Slash, percent, equal to be compatible with *XApplication - * @see key() + * @see @ref key() */ enum class Key: std::uint32_t { Enter = 0x0D, /**< Enter */ @@ -564,8 +565,8 @@ class NaClApplication::KeyEvent: public NaClApplication::InputEvent { /** @brief Mouse event -See InputEvent for more information. -@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() +See also @ref InputEvent for more information. +@see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class NaClApplication::MouseEvent: public NaClApplication::InputEvent { friend class NaClApplication; @@ -574,7 +575,7 @@ class NaClApplication::MouseEvent: public NaClApplication::InputEvent { /** * @brief Button * - * @see button() + * @see @ref button() */ enum class Button: unsigned int { Left = PP_INPUTEVENT_MOUSEBUTTON_LEFT, /**< Left button */ @@ -598,8 +599,8 @@ class NaClApplication::MouseEvent: public NaClApplication::InputEvent { /** @brief Mouse move event -See InputEvent for more information. -@see MouseEvent, mouseMoveEvent() +See also @ref InputEvent for more information. +@see @ref MouseEvent, @ref mouseMoveEvent() */ class NaClApplication::MouseMoveEvent: public NaClApplication::InputEvent { friend class NaClApplication; @@ -642,9 +643,9 @@ namespace Implementation { @brief Entry point for NaCl application @param application Application class name -See NaClApplication and @ref portability-applications for more information. -When no other application header is included this macro is also aliased to -`MAGNUM_APPLICATION_MAIN()`. +See @ref Magnum::Platform::NaClApplication "Platform::NaClApplication" and +@ref portability-applications for more information. When no other application +header is included this macro is also aliased to `MAGNUM_APPLICATION_MAIN()`. */ /* look at that insane placement of __attribute__. WTF. */ #define MAGNUM_NACLAPPLICATION_MAIN(application) \ diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 690ad475f..925f3443b 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -135,7 +135,15 @@ class Sdl2Application { class MouseEvent; class MouseMoveEvent; - /** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ + /** + * @brief Default constructor + * @param arguments Application arguments + * @param configuration %Configuration + * + * Creates application with default or user-specified configuration. + * See @ref Configuration for more information. The program exits if + * the context cannot be created, see below for an alternative. + */ #ifdef DOXYGEN_GENERATING_OUTPUT explicit Sdl2Application(const Arguments& arguments, const Configuration& configuration = Configuration()); #else @@ -144,10 +152,19 @@ class Sdl2Application { explicit Sdl2Application(const Arguments& arguments); #endif - /** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ + /** + * @brief Constructor + * @param arguments Application arguments + * + * Unlike above, the context is not created and must be created later + * with @ref createContext() or @ref tryCreateContext(). + */ explicit Sdl2Application(const Arguments& arguments, std::nullptr_t); - /** @copydoc GlutApplication::exec() */ + /** + * @brief Execute main loop + * @return Value for returning from `main()`. + */ int exec(); /** @brief Exit application main loop */ @@ -158,31 +175,73 @@ class Sdl2Application { faster than public pure virtual destructor */ ~Sdl2Application(); - /** @copydoc GlutApplication::createContext() */ + /** + * @brief Create context with given configuration + * + * Must be called if and only if the context wasn't created by the + * constructor itself. The program exits if the context cannot be + * created, see @ref tryCreateContext() for an alternative. + */ void createContext(const Configuration& configuration); - /** @copydoc GlutApplication::tryCreateContext() */ + /** + * @brief Try to create context with given configuration + * + * Unlike @ref createContext() returns `false` if the context cannot be + * created, `true` otherwise. + */ bool tryCreateContext(const Configuration& configuration); /** @{ @name Drawing functions */ - /** @copydoc GlutApplication::viewportEvent() */ + /** + * @brief Viewport event + * + * Called when window size changes. You should pass the new size to + * @ref DefaultFramebuffer::setViewport() and possibly elsewhere + * (cameras, 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(). + */ virtual void viewportEvent(const Vector2i& size) = 0; - /** @copydoc GlutApplication::drawEvent() */ + /** + * @brief Draw event + * + * Called when the screen is redrawn. You should clean the framebuffer + * using @ref DefaultFramebuffer::clear() and then add your own drawing + * functions. After drawing is finished, call @ref swapBuffers(). If + * you want to draw immediately again, call also @ref redraw(). + */ virtual void drawEvent() = 0; - /** @copydoc GlutApplication::swapBuffers() */ + /** + * @brief Swap buffers + * + * Paints currently rendered framebuffer on screen. + */ void swapBuffers(); - /** @copydoc GlutApplication::redraw() */ + /** + * @brief Redraw immediately + * + * Marks the window for redrawing, resulting in call to @ref drawEvent() + * in the next iteration. + */ void redraw() { flags |= Flag::Redraw; } /*@}*/ /** @{ @name Keyboard handling */ - /** @copydoc GlutApplication::keyPressEvent() */ + /** + * @brief Key press event + * + * Called when an key is pressed. Default implementation does nothing. + */ virtual void keyPressEvent(KeyEvent& event); /** @@ -210,10 +269,20 @@ class Sdl2Application { void setMouseLocked(bool enabled); protected: - /** @copydoc GlutApplication::mousePressEvent() */ + /** + * @brief Mouse press event + * + * Called when mouse button is pressed. Default implementation does + * nothing. + */ virtual void mousePressEvent(MouseEvent& event); - /** @copydoc GlutApplication::mouseReleaseEvent() */ + /** + * @brief Mouse release event + * + * Called when mouse button is released. Default implementation does + * nothing. + */ virtual void mouseReleaseEvent(MouseEvent& event); /** @@ -263,7 +332,7 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::Flags) Centered non-resizable window with double-buffered OpenGL context and 24bit depth buffer. -@see Sdl2Application(), createContext() +@see @ref Sdl2Application(), @ref createContext(), @ref tryCreateContext() */ class Sdl2Application::Configuration { Configuration(const Configuration&) = delete; @@ -275,7 +344,7 @@ class Sdl2Application::Configuration { /** * @brief Window flag * - * @see Flags, setFlags() + * @see @ref Flags, @ref setFlags() */ enum class Flag: Uint32 { Resizable = SDL_WINDOW_RESIZABLE, /**< Resizable window */ @@ -289,7 +358,7 @@ class Sdl2Application::Configuration { /** * @brief Window flags * - * @see setFlags() + * @see @ref setFlags() */ typedef Containers::EnumSet Modifiers; - /** @copydoc GlutApplication::InputEvent::setAccepted() */ + /** + * @brief Set event as accepted + * + * If the event is ignored (i.e., not set as accepted), it might be + * propagated elsewhere, for example to another screen when using + * @ref BasicScreenedApplication "ScreenedApplication". By default is + * each event ignored and thus propagated. + */ void setAccepted(bool accepted = true) { _accepted = accepted; } - /** @copydoc GlutApplication::InputEvent::isAccepted() */ + /** @brief Whether the event is accepted */ constexpr bool isAccepted() const { return _accepted; } #ifndef DOXYGEN_GENERATING_OUTPUT @@ -421,7 +498,7 @@ class Sdl2Application::InputEvent { /** @brief Key event -@see keyPressEvent(), keyReleaseEvent() +@see @ref keyPressEvent(), @ref keyReleaseEvent() */ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { friend class Sdl2Application; @@ -430,7 +507,7 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { /** * @brief Key * - * @see key() + * @see @ref key() */ enum class Key: SDL_Keycode { Enter = SDLK_RETURN, /**< Enter */ @@ -521,7 +598,7 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent { /** @brief Mouse event -@see MouseMoveEvent, mousePressEvent(), mouseReleaseEvent() +@see @ref MouseMoveEvent, @ref mousePressEvent(), @ref mouseReleaseEvent() */ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent { friend class Sdl2Application; @@ -530,7 +607,7 @@ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent { /** * @brief Mouse button * - * @see button() + * @see @ref button() */ enum class Button: Uint8 { Left = SDL_BUTTON_LEFT, /**< Left button */ @@ -565,7 +642,7 @@ class Sdl2Application::MouseEvent: public Sdl2Application::InputEvent { /** @brief Mouse move event -@see MouseEvent, mouseMoveEvent() +@see @ref MouseEvent, @ref mouseMoveEvent() */ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent { friend class Sdl2Application; @@ -624,9 +701,9 @@ class Sdl2Application::MouseMoveEvent: public Sdl2Application::InputEvent { @brief Entry point for SDL2-based applications @param className Class name -Can be used with Sdl2Application subclasses as equivalent to the following -code to achieve better portability, see @ref portability-applications for more -information. +Can be used with @ref Magnum::Platform::Sdl2Application "Platform::Sdl2Application" +subclasses as equivalent to the following code to achieve better portability, +see @ref portability-applications for more information. @code int main(int argc, char** argv) { className app({argc, argv}); diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index 61658699e..921721f27 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -83,7 +83,7 @@ class WindowlessGlxApplication { class Configuration; - /** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ #ifdef DOXYGEN_GENERATING_OUTPUT explicit WindowlessGlxApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); #else @@ -92,7 +92,7 @@ class WindowlessGlxApplication { explicit WindowlessGlxApplication(const Arguments& arguments); #endif - /** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit WindowlessGlxApplication(const Arguments& arguments, std::nullptr_t); /** @@ -106,7 +106,7 @@ class WindowlessGlxApplication { thus this is faster than public pure virtual destructor */ ~WindowlessGlxApplication(); - /** @copydoc GlutApplication::createContext() */ + /** @copydoc Sdl2Application::createContext() */ void createContext(const Configuration& configuration); private: @@ -120,7 +120,8 @@ class WindowlessGlxApplication { /** @brief %Configuration -@see WindowlessGlxApplication(), createContext() +@see @ref WindowlessGlxApplication(), @ref createContext(), + @ref tryCreateContext() */ class WindowlessGlxApplication::Configuration { Configuration(const Configuration&) = delete; @@ -137,7 +138,8 @@ class WindowlessGlxApplication::Configuration { @brief Entry point for windowless GLX application @param className Class name -Can be used as equivalent to the following code to achieve better portability, +Can be used with @ref Magnum::Platform::WindowlessGlxApplication "Platform::WindowlessGlxApplication" +subclasses as equivalent to the following code to achieve better portability, see @ref portability-applications for more information. @code int main(int argc, char** argv) { diff --git a/src/Platform/WindowlessNaClApplication.h b/src/Platform/WindowlessNaClApplication.h index b73bd77a7..32aaa8f20 100644 --- a/src/Platform/WindowlessNaClApplication.h +++ b/src/Platform/WindowlessNaClApplication.h @@ -100,7 +100,7 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien class Configuration; - /** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, const Configuration&) */ #ifdef DOXYGEN_GENERATING_OUTPUT explicit WindowlessNaClApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); #else @@ -109,7 +109,7 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien explicit WindowlessNaClApplication(const Arguments& arguments); #endif - /** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ + /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit WindowlessNaClApplication(const Arguments& arguments, std::nullptr_t); /** @@ -123,10 +123,10 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien thus this is faster than public pure virtual destructor */ ~WindowlessNaClApplication(); - /** @copydoc GlutApplication::createContext() */ + /** @copydoc Sdl2Application::createContext() */ void createContext(const Configuration& configuration); - /** @copydoc GlutApplication::tryCreateContext() */ + /** @copydoc Sdl2Application::tryCreateContext() */ bool tryCreateContext(const Configuration& configuration); private: @@ -146,7 +146,8 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien /** @brief %Configuration -@see WindowlessNaClApplication(), createContext(), tryCreateContext() +@see @ref WindowlessNaClApplication(), @ref createContext(), + @ref tryCreateContext() */ class WindowlessNaClApplication::Configuration { Configuration(const Configuration&) = delete; @@ -177,9 +178,10 @@ namespace Implementation { @brief Entry point for windowless NaCl application @param application Application class name -See WindowlessNaClApplication and @ref portability-applications for more -information. When no other windowless application header is included this macro -is also aliased to `MAGNUM_WINDOWLESSAPPLICATION_MAIN()`. +See @ref Magnum::Platform::WindowlessNaClApplication "Platform::WindowlessNaClApplication" +and @ref portability-applications for more information. When no other +windowless application header is included this macro is also aliased to +`MAGNUM_WINDOWLESSAPPLICATION_MAIN()`. */ /* look at that insane placement of __attribute__. WTF. */ #define MAGNUM_WINDOWLESSNACLAPPLICATION_MAIN(application) \ diff --git a/src/Platform/XEglApplication.h b/src/Platform/XEglApplication.h index 5c436c101..dc7aae7f2 100644 --- a/src/Platform/XEglApplication.h +++ b/src/Platform/XEglApplication.h @@ -67,10 +67,10 @@ to simplify porting. */ class XEglApplication: public AbstractXApplication { public: - /** @copydoc GlutApplication::GlutApplication(const Arguments&, const Configuration&) */ + /** @copydoc Sdl2Application::GlutApplication(const Arguments&, const Configuration&) */ explicit XEglApplication(const Arguments& arguments, const Configuration& configuration = Configuration()); - /** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */ + /** @copydoc Sdl2Application::GlutApplication(const Arguments&, std::nullptr_t) */ explicit XEglApplication(const Arguments& arguments, std::nullptr_t); protected: @@ -83,9 +83,9 @@ class XEglApplication: public AbstractXApplication { @brief Entry point for X/EGL-based applications @param className Class name -Can be used with XEglApplication subclasses as equivalent to the following code -to achieve better portability, see @ref portability-applications for more -information. +Can be used with @ref Magnum::Platform::XEglApplication "Platform::XEglApplication" +subclasses as equivalent to the following code to achieve better portability, +see @ref portability-applications for more information. @code int main(int argc, char** argv) { className app({argc, argv}); From fea61e60f745643b83a1e77fe321ae9f8aae7d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 19:42:16 +0100 Subject: [PATCH 09/32] Platform: cleaned up unneeded includes. Also deinlined pure virtual function implementation. --- src/Platform/WindowlessNaClApplication.cpp | 5 +++++ src/Platform/WindowlessNaClApplication.h | 5 +---- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Platform/WindowlessNaClApplication.cpp b/src/Platform/WindowlessNaClApplication.cpp index c1e72711f..e0065b82c 100644 --- a/src/Platform/WindowlessNaClApplication.cpp +++ b/src/Platform/WindowlessNaClApplication.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include "Context.h" @@ -112,4 +113,8 @@ bool WindowlessNaClApplication::Init(uint32_t , const char* , const char*) { return exec() == 0; } +void WindowlessNaClApplication::Graphics3DContextLost() { + CORRADE_ASSERT(false, "NaClApplication: context unexpectedly lost", ); +} + }} diff --git a/src/Platform/WindowlessNaClApplication.h b/src/Platform/WindowlessNaClApplication.h index 32aaa8f20..010a6ba41 100644 --- a/src/Platform/WindowlessNaClApplication.h +++ b/src/Platform/WindowlessNaClApplication.h @@ -35,7 +35,6 @@ #include #include -#include "Math/Vector2.h" #include "Magnum.h" #include "corradeCompatibility.h" @@ -132,9 +131,7 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien private: struct ConsoleDebugOutput; - void Graphics3DContextLost() override { - CORRADE_ASSERT(false, "NaClApplication: context unexpectedly lost", ); - } + void Graphics3DContextLost() override; bool Init(std::uint32_t, const char*, const char*) override; From 77677ff48d505486d30e902c3411b3526913b870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 19:55:50 +0100 Subject: [PATCH 10/32] Platform: unified and cleaned up context creation. Added missing tryCreateContext() implementations. Error messages are printed only by tryCreateContext(), createContext() is only a thin wrapper which exits the application if tryCreateContext() fails and doesn't print any additional information on the output. Hopefully I didn't break anything :-) --- src/Platform/AbstractXApplication.cpp | 11 +++++++--- src/Platform/AbstractXApplication.h | 3 +++ src/Platform/GlutApplication.cpp | 9 ++++---- src/Platform/NaClApplication.cpp | 10 ++++----- src/Platform/Sdl2Application.cpp | 10 ++++----- src/Platform/WindowlessGlxApplication.cpp | 25 +++++++++++++--------- src/Platform/WindowlessGlxApplication.h | 3 +++ src/Platform/WindowlessNaClApplication.cpp | 10 ++++----- 8 files changed, 48 insertions(+), 33 deletions(-) diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index 84bbf4e6c..c6c846bcd 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -51,7 +51,11 @@ AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandle AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, std::nullptr_t): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {} void AbstractXApplication::createContext(const Configuration& configuration) { - CORRADE_ASSERT(!c, "AbstractXApplication::createContext(): context already created", ); + if(!tryCreateContext(configuration)) std::exit(1); +} + +bool AbstractXApplication::tryCreateContext(const Configuration& configuration) { + CORRADE_ASSERT(!c, "AbstractXApplication::tryCreateContext(): context already created", ); viewportSize = configuration.size(); @@ -67,8 +71,8 @@ void AbstractXApplication::createContext(const Configuration& configuration) { visTemplate.visualid = visualId; visInfo = XGetVisualInfo(display, VisualIDMask, &visTemplate, &visualCount); if(!visInfo) { - Error() << "Cannot get X visual"; - std::exit(1); + Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot get X visual"; + return false; } /* Create X Window */ @@ -97,6 +101,7 @@ void AbstractXApplication::createContext(const Configuration& configuration) { contextHandler->makeCurrent(); c = new Context; + return true; } AbstractXApplication::~AbstractXApplication() { diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 12affaaa9..ab10cea23 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -90,6 +90,9 @@ class AbstractXApplication { /** @copydoc Sdl2Application::createContext() */ void createContext(const Configuration& configuration); + /** @copydoc Sdl2Application::tryCreateContext() */ + bool tryCreateContext(const Configuration& configuration); + /** @{ @name Drawing functions */ /** @copydoc Sdl2Application::viewportEvent() */ diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index 661e360c2..394546f98 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -60,10 +60,7 @@ void GlutApplication::initialize(int& argc, char** argv) { } void GlutApplication::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) { - Error() << "Platform::GlutApplication::createContext(): cannot create context"; - std::exit(1); - } + if(!tryCreateContext(configuration)) std::exit(1); } bool GlutApplication::tryCreateContext(const Configuration& configuration) { @@ -76,8 +73,10 @@ bool GlutApplication::tryCreateContext(const Configuration& configuration) { glutInitDisplayMode(flags); glutInitWindowSize(configuration.size().x(), configuration.size().y()); - if(!glutCreateWindow(configuration.title().data())) + if(!glutCreateWindow(configuration.title().data())) { + Error() << "Platform::GlutApplication::tryCreateContext(): cannot create context"; return false; + } glutReshapeFunc(staticViewportEvent); glutSpecialFunc(staticKeyEvent); glutMouseFunc(staticMouseEvent); diff --git a/src/Platform/NaClApplication.cpp b/src/Platform/NaClApplication.cpp index 1094316f8..3b6648ba2 100644 --- a/src/Platform/NaClApplication.cpp +++ b/src/Platform/NaClApplication.cpp @@ -69,10 +69,7 @@ NaClApplication::NaClApplication(const Arguments& arguments, std::nullptr_t): In } void NaClApplication::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) { - Error() << "Platform::NaClApplication::createContext(): cannot create context"; - std::exit(1); - } + if(!tryCreateContext(configuration)) std::exit(1); } bool NaClApplication::tryCreateContext(const Configuration& configuration) { @@ -93,13 +90,16 @@ bool NaClApplication::tryCreateContext(const Configuration& configuration) { graphics = new pp::Graphics3D(this, attributes); if(graphics->is_null()) { + Error() << "Platform::NaClApplication::tryCreateContext(): cannot create context"; delete graphics; graphics = nullptr; return false; } if(!BindGraphics(*graphics)) { Error() << "Platform::NaClApplication::tryCreateContext(): cannot bind graphics"; - std::exit(1); + delete graphics; + graphics = nullptr; + return false; } fullscreen = new pp::Fullscreen(this); diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index 9d791e729..4377aaca5 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -89,10 +89,7 @@ void Sdl2Application::initialize() { } void Sdl2Application::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) { - Error() << "Platform::Sdl2Application::createContext(): cannot create context:" << SDL_GetError(); - std::exit(1); - } + if(!tryCreateContext(configuration)) std::exit(1); } bool Sdl2Application::tryCreateContext(const Configuration& configuration) { @@ -115,10 +112,13 @@ bool Sdl2Application::tryCreateContext(const Configuration& configuration) { if(!(window = SDL_CreateWindow(configuration.title().data(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, configuration.size().x(), configuration.size().y(), - SDL_WINDOW_OPENGL|flags))) + SDL_WINDOW_OPENGL|flags))) { + Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create window:" << SDL_GetError(); return false; + } if(!(context = SDL_GL_CreateContext(window))) { + Error() << "Platform::Sdl2Application::tryCreateContext(): cannot create context:" << SDL_GetError(); SDL_DestroyWindow(window); window = nullptr; return false; diff --git a/src/Platform/WindowlessGlxApplication.cpp b/src/Platform/WindowlessGlxApplication.cpp index 5feedb01f..1940e704f 100644 --- a/src/Platform/WindowlessGlxApplication.cpp +++ b/src/Platform/WindowlessGlxApplication.cpp @@ -47,8 +47,12 @@ WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&): c(nullptr) WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, std::nullptr_t): c(nullptr) {} -void WindowlessGlxApplication::createContext(const Configuration&) { - CORRADE_ASSERT(!c, "WindowlessGlxApplication::createContext(): context already created", ); +void WindowlessGlxApplication::createContext(const Configuration& configuration) { + if(!tryCreateContext(configuration)) std::exit(1); +} + +bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { + CORRADE_ASSERT(!c, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", ); display = XOpenDisplay(nullptr); @@ -56,8 +60,8 @@ void WindowlessGlxApplication::createContext(const Configuration&) { int major, minor; glXQueryVersion(display, &major, &minor); if(major == 1 && minor < 4) { - Error() << "WindowlessGlxApplication: GLX version 1.4 or greater is required."; - std::exit(1); + Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): GLX version 1.4 or greater is required"; + return false; } /* Choose config */ @@ -65,8 +69,8 @@ void WindowlessGlxApplication::createContext(const Configuration&) { static const int fbAttributes[] = { None }; GLXFBConfig* configs = glXChooseFBConfig(display, DefaultScreen(display), fbAttributes, &configCount); if(!configCount) { - Error() << "WindowlessGlxApplication: no supported framebuffer configuration found."; - std::exit(1); + Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): no supported framebuffer configuration found"; + return false; } GLint contextAttributes[] = { @@ -82,8 +86,8 @@ void WindowlessGlxApplication::createContext(const Configuration&) { PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB"); context = glXCreateContextAttribsARB(display, configs[0], nullptr, True, contextAttributes); if(!context) { - Error() << "WindowlessGlxApplication: cannot create context."; - std::exit(1); + Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot create context"; + return false; } /* Create pbuffer */ @@ -98,11 +102,12 @@ void WindowlessGlxApplication::createContext(const Configuration&) { /* Set OpenGL context as current */ if(!glXMakeContextCurrent(display, pbuffer, pbuffer, context)) { - Error() << "WindowlessGlxApplication: cannot make context current"; - std::exit(1); + Error() << "Platform::WindowlessGlxApplication::tryCreateContext(): cannot make context current"; + return false; } c = new Context; + return true; } WindowlessGlxApplication::~WindowlessGlxApplication() { diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index 921721f27..937d7b3fb 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -109,6 +109,9 @@ class WindowlessGlxApplication { /** @copydoc Sdl2Application::createContext() */ void createContext(const Configuration& configuration); + /** @copydoc Sdl2Application::tryCreateContext() */ + bool tryCreateContext(const Configuration& configuration); + private: Display* display; GLXContext context; diff --git a/src/Platform/WindowlessNaClApplication.cpp b/src/Platform/WindowlessNaClApplication.cpp index e0065b82c..f28e27e67 100644 --- a/src/Platform/WindowlessNaClApplication.cpp +++ b/src/Platform/WindowlessNaClApplication.cpp @@ -68,10 +68,7 @@ WindowlessNaClApplication::WindowlessNaClApplication(const Arguments& arguments, } void WindowlessNaClApplication::createContext(const Configuration& configuration) { - if(!tryCreateContext(configuration)) { - Error() << "Platform::WindowlessNaClApplication::createContext(): cannot create context"; - std::exit(1); - } + if(!tryCreateContext(configuration)) std::exit(1); } bool WindowlessNaClApplication::tryCreateContext(const Configuration&) { @@ -88,13 +85,16 @@ bool WindowlessNaClApplication::tryCreateContext(const Configuration&) { graphics = new pp::Graphics3D(this, attributes); if(graphics->is_null()) { + Error() << "Platform::WindowlessNaClApplication::tryCreateContext(): cannot create context"; delete graphics; graphics = nullptr; return false; } if(!BindGraphics(*graphics)) { Error() << "Platform::WindowlessNaClApplication::tryCreateContext(): cannot bind graphics"; - std::exit(1); + delete graphics; + graphics = nullptr; + return false; } glSetCurrentContextPPAPI(graphics->pp_resource()); From a2dbe53c7d35becef7689a0bb2686666ccf98c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 20:07:02 +0100 Subject: [PATCH 11/32] Platform: no need to have convenience overload of internal constructor. --- src/Platform/AbstractXApplication.cpp | 6 ------ src/Platform/AbstractXApplication.h | 3 --- 2 files changed, 9 deletions(-) diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index c6c846bcd..6ef777eea 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -42,12 +42,6 @@ AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandle createContext(configuration); } -#ifndef DOXYGEN_GENERATING_OUTPUT -AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) { - createContext({}); -} -#endif - AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, std::nullptr_t): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {} void AbstractXApplication::createContext(const Configuration& configuration) { diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index ab10cea23..6a3464d2f 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -137,10 +137,7 @@ class AbstractXApplication { #else protected: #endif - /* These two are split to avoid "invalid use of incomplete type" when - using default argument for configuration */ explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, const Configuration& configuration); - explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments); explicit AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments& arguments, std::nullptr_t); From 5c0747359a8c88fb5cdc521ab27644d88ec382aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 20:10:11 +0100 Subject: [PATCH 12/32] Platform: add default argument to createContext(). Somebody would just want to defer context creation after parsing arguments or doing some validations without any particular setup, thus having to write even the {} is annoying. --- src/Platform/AbstractXApplication.cpp | 2 ++ src/Platform/AbstractXApplication.h | 6 ++++++ src/Platform/GlutApplication.cpp | 4 +++- src/Platform/GlutApplication.h | 6 ++++++ src/Platform/NaClApplication.cpp | 4 +++- src/Platform/NaClApplication.h | 6 ++++++ src/Platform/Sdl2Application.cpp | 4 +++- src/Platform/Sdl2Application.h | 6 ++++++ src/Platform/WindowlessGlxApplication.cpp | 4 +++- src/Platform/WindowlessGlxApplication.h | 6 ++++++ src/Platform/WindowlessNaClApplication.cpp | 4 +++- src/Platform/WindowlessNaClApplication.h | 6 ++++++ src/Platform/magnum-info.cpp | 2 +- src/Text/fontconverter.cpp | 2 +- src/TextureTools/distancefieldconverter.cpp | 2 +- 15 files changed, 56 insertions(+), 8 deletions(-) diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index 6ef777eea..b01fbddd9 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -44,6 +44,8 @@ AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandle AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler* contextHandler, const Arguments&, std::nullptr_t): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {} +void AbstractXApplication::createContext() { createContext({}); } + void AbstractXApplication::createContext(const Configuration& configuration) { if(!tryCreateContext(configuration)) std::exit(1); } diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 6a3464d2f..a07e6ccb2 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -88,7 +88,13 @@ class AbstractXApplication { ~AbstractXApplication(); /** @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); diff --git a/src/Platform/GlutApplication.cpp b/src/Platform/GlutApplication.cpp index 394546f98..cce9242c0 100644 --- a/src/Platform/GlutApplication.cpp +++ b/src/Platform/GlutApplication.cpp @@ -42,7 +42,7 @@ GlutApplication::GlutApplication(const Arguments& arguments, const Configuration #ifndef DOXYGEN_GENERATING_OUTPUT GlutApplication::GlutApplication(const Arguments& arguments): c(nullptr) { initialize(arguments.argc, arguments.argv); - createContext({}); + createContext(); } #endif @@ -59,6 +59,8 @@ void GlutApplication::initialize(int& argc, char** argv) { glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); } +void GlutApplication::createContext() { createContext({}); } + void GlutApplication::createContext(const Configuration& configuration) { if(!tryCreateContext(configuration)) std::exit(1); } diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 6ad4c246a..037ebb1b2 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -114,7 +114,13 @@ class GlutApplication { ~GlutApplication(); /** @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); diff --git a/src/Platform/NaClApplication.cpp b/src/Platform/NaClApplication.cpp index 3b6648ba2..bdb34e5e6 100644 --- a/src/Platform/NaClApplication.cpp +++ b/src/Platform/NaClApplication.cpp @@ -60,7 +60,7 @@ NaClApplication::NaClApplication(const Arguments& arguments, const Configuration #ifndef DOXYGEN_GENERATING_OUTPUT NaClApplication::NaClApplication(const Arguments& arguments): Instance(arguments), Graphics3DClient(this), MouseLock(this), c(nullptr) { debugOutput = new ConsoleDebugOutput(this); - createContext({}); + createContext(); } #endif @@ -68,6 +68,8 @@ NaClApplication::NaClApplication(const Arguments& arguments, std::nullptr_t): In debugOutput = new ConsoleDebugOutput(this); } +void NaClApplication::createContext() { createContext({}); } + void NaClApplication::createContext(const Configuration& configuration) { if(!tryCreateContext(configuration)) std::exit(1); } diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 34d8d88b3..6674ab7e8 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -179,7 +179,13 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public ~NaClApplication(); /** @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); diff --git a/src/Platform/Sdl2Application.cpp b/src/Platform/Sdl2Application.cpp index 4377aaca5..2f5b7785a 100644 --- a/src/Platform/Sdl2Application.cpp +++ b/src/Platform/Sdl2Application.cpp @@ -68,7 +68,7 @@ Sdl2Application::Sdl2Application(const Arguments&, const Configuration& configur #ifndef DOXYGEN_GENERATING_OUTPUT Sdl2Application::Sdl2Application(const Arguments&): context(nullptr), flags(Flag::Redraw) { initialize(); - createContext({}); + createContext(); } #endif @@ -88,6 +88,8 @@ void Sdl2Application::initialize() { } } +void Sdl2Application::createContext() { createContext({}); } + void Sdl2Application::createContext(const Configuration& configuration) { if(!tryCreateContext(configuration)) std::exit(1); } diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 925f3443b..a9d2a8afc 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -182,7 +182,13 @@ class Sdl2Application { * constructor itself. The program exits if the context cannot be * created, see @ref tryCreateContext() for an alternative. */ + #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 /** * @brief Try to create context with given configuration diff --git a/src/Platform/WindowlessGlxApplication.cpp b/src/Platform/WindowlessGlxApplication.cpp index 1940e704f..e71181530 100644 --- a/src/Platform/WindowlessGlxApplication.cpp +++ b/src/Platform/WindowlessGlxApplication.cpp @@ -41,12 +41,14 @@ WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, const Confi #ifndef DOXYGEN_GENERATING_OUTPUT WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&): c(nullptr) { - createContext({}); + createContext(); } #endif WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, std::nullptr_t): c(nullptr) {} +void WindowlessGlxApplication::createContext() { createContext({}); } + void WindowlessGlxApplication::createContext(const Configuration& configuration) { if(!tryCreateContext(configuration)) std::exit(1); } diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index 937d7b3fb..bf0855d9c 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -107,7 +107,13 @@ class WindowlessGlxApplication { ~WindowlessGlxApplication(); /** @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); diff --git a/src/Platform/WindowlessNaClApplication.cpp b/src/Platform/WindowlessNaClApplication.cpp index f28e27e67..22e9eb1d6 100644 --- a/src/Platform/WindowlessNaClApplication.cpp +++ b/src/Platform/WindowlessNaClApplication.cpp @@ -59,7 +59,7 @@ WindowlessNaClApplication::WindowlessNaClApplication(const Arguments& arguments, #ifndef DOXYGEN_GENERATING_OUTPUT WindowlessNaClApplication::WindowlessNaClApplication(const Arguments& arguments): Instance(arguments), Graphics3DClient(this), c(nullptr) { debugOutput = new ConsoleDebugOutput(this); - createContext({}); + createContext(); } #endif @@ -67,6 +67,8 @@ WindowlessNaClApplication::WindowlessNaClApplication(const Arguments& arguments, debugOutput = new ConsoleDebugOutput(this); } +void WindowlessNaClApplication::createContext() { createContext({}); } + void WindowlessNaClApplication::createContext(const Configuration& configuration) { if(!tryCreateContext(configuration)) std::exit(1); } diff --git a/src/Platform/WindowlessNaClApplication.h b/src/Platform/WindowlessNaClApplication.h index 010a6ba41..309f32a16 100644 --- a/src/Platform/WindowlessNaClApplication.h +++ b/src/Platform/WindowlessNaClApplication.h @@ -123,7 +123,13 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien ~WindowlessNaClApplication(); /** @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); diff --git a/src/Platform/magnum-info.cpp b/src/Platform/magnum-info.cpp index c2e66e982..182a4e28c 100644 --- a/src/Platform/magnum-info.cpp +++ b/src/Platform/magnum-info.cpp @@ -70,7 +70,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat /* Create context after parsing arguments, so the help can be displayed without creating context */ - createContext({}); + createContext(); Context* c = Context::current(); /* Pass debug output as messages to JavaScript */ diff --git a/src/Text/fontconverter.cpp b/src/Text/fontconverter.cpp index 1db6bc542..a944fce6f 100644 --- a/src/Text/fontconverter.cpp +++ b/src/Text/fontconverter.cpp @@ -62,7 +62,7 @@ FontConverter::FontConverter(const Arguments& arguments): Platform::WindowlessAp .setHelp("Converts font to raster one of given atlas size.") .parse(arguments.argc, arguments.argv); - createContext({}); + createContext(); } int FontConverter::exec() { diff --git a/src/TextureTools/distancefieldconverter.cpp b/src/TextureTools/distancefieldconverter.cpp index e61b17e45..8fd096224 100644 --- a/src/TextureTools/distancefieldconverter.cpp +++ b/src/TextureTools/distancefieldconverter.cpp @@ -61,7 +61,7 @@ DistanceFieldConverter::DistanceFieldConverter(const Arguments& arguments): Wind .setHelp("Converts black&white image to distance-field representation.") .parse(arguments.argc, arguments.argv); - createContext({}); + createContext(); } int DistanceFieldConverter::exec() { From b406404969e38067a1e24f6eda720d418623a4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 20:30:21 +0100 Subject: [PATCH 13/32] Platform: there is no point in disabling copy/move of Configuration. The class isn't heavy at all and we don't need to maintain only one instance. --- src/Platform/AbstractXApplication.h | 5 ----- src/Platform/GlutApplication.h | 5 ----- src/Platform/NaClApplication.h | 5 ----- src/Platform/Sdl2Application.h | 5 ----- src/Platform/WindowlessGlxApplication.h | 5 ----- src/Platform/WindowlessNaClApplication.h | 5 ----- 6 files changed, 30 deletions(-) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index a07e6ccb2..34f5194d9 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -181,11 +181,6 @@ Double-buffered OpenGL context. @todo GLX_ARB_create_context_robustness/EGL_EXT_create_context_robustness */ class AbstractXApplication::Configuration { - Configuration(const Configuration&) = delete; - Configuration(Configuration&&) = delete; - Configuration& operator=(const Configuration&) = delete; - Configuration& operator=(Configuration&&) = delete; - public: /*implicit*/ Configuration(); ~Configuration(); diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 037ebb1b2..1a45612c7 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -236,11 +236,6 @@ Double-buffered RGBA window with depth and stencil buffers. @see @ref GlutApplication(), @ref createContext(), @ref tryCreateContext() */ class GlutApplication::Configuration { - Configuration(const Configuration&) = delete; - Configuration(Configuration&&) = delete; - Configuration& operator=(const Configuration&) = delete; - Configuration& operator=(Configuration&&) = delete; - public: /*implicit*/ Configuration(); ~Configuration(); diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 6674ab7e8..0c0da3f16 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -318,11 +318,6 @@ Double-buffered RGBA canvas with depth and stencil buffers. @see @ref NaClApplication(), @ref createContext() */ class NaClApplication::Configuration { - Configuration(const Configuration&) = delete; - Configuration(Configuration&&) = delete; - Configuration& operator=(const Configuration&) = delete; - Configuration& operator=(Configuration&&) = delete; - public: constexpr /*implicit*/ Configuration(): _size(640, 480), _sampleCount(0) {} diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index a9d2a8afc..1412d4ab1 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -341,11 +341,6 @@ depth buffer. @see @ref Sdl2Application(), @ref createContext(), @ref tryCreateContext() */ class Sdl2Application::Configuration { - Configuration(const Configuration&) = delete; - Configuration(Configuration&&) = delete; - Configuration& operator=(const Configuration&) = delete; - Configuration& operator=(Configuration&&) = delete; - public: /** * @brief Window flag diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index bf0855d9c..627c844c8 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -133,11 +133,6 @@ class WindowlessGlxApplication { @ref tryCreateContext() */ class WindowlessGlxApplication::Configuration { - Configuration(const Configuration&) = delete; - Configuration(Configuration&&) = delete; - Configuration& operator=(const Configuration&) = delete; - Configuration& operator=(Configuration&&) = delete; - public: /*implicit*/ Configuration(); ~Configuration(); diff --git a/src/Platform/WindowlessNaClApplication.h b/src/Platform/WindowlessNaClApplication.h index 309f32a16..f2b99f145 100644 --- a/src/Platform/WindowlessNaClApplication.h +++ b/src/Platform/WindowlessNaClApplication.h @@ -153,11 +153,6 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien @ref tryCreateContext() */ class WindowlessNaClApplication::Configuration { - Configuration(const Configuration&) = delete; - Configuration(Configuration&&) = delete; - Configuration& operator=(const Configuration&) = delete; - Configuration& operator=(Configuration&&) = delete; - public: constexpr /*implicit*/ Configuration() {} }; From da049642cf415becd733769fc838de9b71f6e04d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 20:31:32 +0100 Subject: [PATCH 14/32] Platform: WindolessGlxApplication::Configuration can be a POD. No need to create symbols for empty constructor/destructor. --- src/Platform/WindowlessGlxApplication.cpp | 3 --- src/Platform/WindowlessGlxApplication.h | 3 +-- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Platform/WindowlessGlxApplication.cpp b/src/Platform/WindowlessGlxApplication.cpp index e71181530..357d9eae3 100644 --- a/src/Platform/WindowlessGlxApplication.cpp +++ b/src/Platform/WindowlessGlxApplication.cpp @@ -119,7 +119,4 @@ WindowlessGlxApplication::~WindowlessGlxApplication() { glXDestroyContext(display, context); } -WindowlessGlxApplication::Configuration::Configuration() = default; -WindowlessGlxApplication::Configuration::~Configuration() = default; - }} diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index 627c844c8..720c5320a 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -134,8 +134,7 @@ class WindowlessGlxApplication { */ class WindowlessGlxApplication::Configuration { public: - /*implicit*/ Configuration(); - ~Configuration(); + constexpr /*implicit*/ Configuration() {} }; /** @hideinitializer From 698b150c9031a3e4ee2fdc60c05e25e47dcd9ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 20:32:48 +0100 Subject: [PATCH 15/32] Platform: disable copy/move of Application classes. They are something like singletons (or they expect that behavior internally), moreover some code might hold pointer to them, thus movement is not desired. --- src/Platform/AbstractXApplication.h | 12 ++++++++++++ src/Platform/GlutApplication.h | 12 ++++++++++++ src/Platform/NaClApplication.h | 12 ++++++++++++ src/Platform/Sdl2Application.h | 12 ++++++++++++ src/Platform/WindowlessGlxApplication.h | 12 ++++++++++++ src/Platform/WindowlessNaClApplication.h | 12 ++++++++++++ 6 files changed, 72 insertions(+) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 34f5194d9..549a01738 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -73,6 +73,18 @@ class AbstractXApplication { class MouseEvent; class MouseMoveEvent; + /** @brief Copying is not allowed */ + AbstractXApplication(const AbstractXApplication&) = delete; + + /** @brief Moving is not allowed */ + AbstractXApplication(AbstractXApplication&&) = delete; + + /** @brief Copying is not allowed */ + AbstractXApplication& operator=(const AbstractXApplication&) = delete; + + /** @brief Moving is not allowed */ + AbstractXApplication& operator=(AbstractXApplication&&) = delete; + /** * @brief Execute main loop * @return Value for returning from `main()`. diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 1a45612c7..f292cceee 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -102,6 +102,18 @@ class GlutApplication { /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit GlutApplication(const Arguments& arguments, std::nullptr_t); + /** @brief Copying is not allowed */ + GlutApplication(const GlutApplication&) = delete; + + /** @brief Moving is not allowed */ + GlutApplication(GlutApplication&&) = delete; + + /** @brief Copying is not allowed */ + GlutApplication& operator=(const GlutApplication&) = delete; + + /** @brief Moving is not allowed */ + GlutApplication& operator=(GlutApplication&&) = delete; + /** @copydoc Sdl2Application::exec() */ int exec() { glutMainLoop(); diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 0c0da3f16..28dbd438c 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -160,6 +160,18 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit NaClApplication(const Arguments& arguments, std::nullptr_t); + /** @brief Copying is not allowed */ + NaClApplication(const NaClApplication&) = delete; + + /** @brief Moving is not allowed */ + NaClApplication(NaClApplication&&) = delete; + + /** @brief Copying is not allowed */ + NaClApplication& operator=(const NaClApplication&) = delete; + + /** @brief Moving is not allowed */ + NaClApplication& operator=(NaClApplication&&) = delete; + /** @brief Whether the application runs fullscreen */ bool isFullscreen(); diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 1412d4ab1..8458fec55 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -161,6 +161,18 @@ class Sdl2Application { */ explicit Sdl2Application(const Arguments& arguments, std::nullptr_t); + /** @brief Copying is not allowed */ + Sdl2Application(const Sdl2Application&) = delete; + + /** @brief Moving is not allowed */ + Sdl2Application(Sdl2Application&&) = delete; + + /** @brief Copying is not allowed */ + Sdl2Application& operator=(const Sdl2Application&) = delete; + + /** @brief Moving is not allowed */ + Sdl2Application& operator=(Sdl2Application&&) = delete; + /** * @brief Execute main loop * @return Value for returning from `main()`. diff --git a/src/Platform/WindowlessGlxApplication.h b/src/Platform/WindowlessGlxApplication.h index 720c5320a..3b531f85e 100644 --- a/src/Platform/WindowlessGlxApplication.h +++ b/src/Platform/WindowlessGlxApplication.h @@ -95,6 +95,18 @@ class WindowlessGlxApplication { /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit WindowlessGlxApplication(const Arguments& arguments, std::nullptr_t); + /** @brief Copying is not allowed */ + WindowlessGlxApplication(const WindowlessGlxApplication&) = delete; + + /** @brief Moving is not allowed */ + WindowlessGlxApplication(WindowlessGlxApplication&&) = delete; + + /** @brief Copying is not allowed */ + WindowlessGlxApplication& operator=(const WindowlessGlxApplication&) = delete; + + /** @brief Moving is not allowed */ + WindowlessGlxApplication& operator=(WindowlessGlxApplication&&) = delete; + /** * @brief Execute application * @return Value for returning from `main()`. diff --git a/src/Platform/WindowlessNaClApplication.h b/src/Platform/WindowlessNaClApplication.h index f2b99f145..277b82111 100644 --- a/src/Platform/WindowlessNaClApplication.h +++ b/src/Platform/WindowlessNaClApplication.h @@ -111,6 +111,18 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien /** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */ explicit WindowlessNaClApplication(const Arguments& arguments, std::nullptr_t); + /** @brief Copying is not allowed */ + WindowlessNaClApplication(const WindowlessNaClApplication&) = delete; + + /** @brief Moving is not allowed */ + WindowlessNaClApplication(WindowlessNaClApplication&&) = delete; + + /** @brief Copying is not allowed */ + WindowlessNaClApplication& operator=(const WindowlessNaClApplication&) = delete; + + /** @brief Moving is not allowed */ + WindowlessNaClApplication& operator=(WindowlessNaClApplication&&) = delete; + /** * @brief Execute application * @return Value for returning from `main()`. From fbc9277b12dd4e0eb32d4198ccfd437b92eba6ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 20:34:03 +0100 Subject: [PATCH 16/32] Platform: publicly document copy/move inability of Event classes. We need to create one instance, send it to subclasses and then check its state, thus we expect that the user always operatres with the original instance. --- src/Platform/AbstractXApplication.h | 18 ++++++++++++------ src/Platform/GlutApplication.h | 17 ++++++++++++----- src/Platform/NaClApplication.h | 17 ++++++++++++----- src/Platform/Sdl2Application.h | 17 ++++++++++++----- 4 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 549a01738..9d0bb7f29 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -238,12 +238,6 @@ class AbstractXApplication::Configuration { @ref mouseMoveEvent() */ class AbstractXApplication::InputEvent { - InputEvent(const InputEvent&) = delete; - InputEvent(InputEvent&&) = delete; - InputEvent& operator=(const InputEvent&) = delete; - InputEvent& operator=(InputEvent&&) = delete; - - public: public: /** * @brief %Modifier @@ -311,6 +305,18 @@ class AbstractXApplication::InputEvent { */ typedef Containers::EnumSet Buttons; + /** @brief Copying is not allowed */ + InputEvent(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent(InputEvent&&) = delete; + + /** @brief Copying is not allowed */ + InputEvent& operator=(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent& operator=(InputEvent&&) = delete; + /** @copydoc Sdl2Application::InputEvent::setAccepted() */ void setAccepted(bool accepted = true) { _accepted = accepted; } diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index f292cceee..97452a23b 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -309,12 +309,19 @@ class GlutApplication::Configuration { @ref mousePressEvent(), @ref mouseReleaseEvent(), @ref mouseMoveEvent() */ class GlutApplication::InputEvent { - InputEvent(const InputEvent&) = delete; - InputEvent(InputEvent&&) = delete; - InputEvent& operator=(const InputEvent&) = delete; - InputEvent& operator=(InputEvent&&) = delete; - public: + /** @brief Copying is not allowed */ + InputEvent(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent(InputEvent&&) = delete; + + /** @brief Copying is not allowed */ + InputEvent& operator=(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent& operator=(InputEvent&&) = delete; + /** @copydoc Sdl2Application::InputEvent::setAccepted() */ void setAccepted(bool accepted = true) { _accepted = accepted; } diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 28dbd438c..2e48bfc2e 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -377,11 +377,6 @@ propagated to the browser. @ref mouseMoveEvent() */ class NaClApplication::InputEvent { - InputEvent(const InputEvent&) = delete; - InputEvent(InputEvent&&) = delete; - InputEvent& operator=(const InputEvent&) = delete; - InputEvent& operator=(InputEvent&&) = delete; - public: /** * @brief %Modifier @@ -450,6 +445,18 @@ class NaClApplication::InputEvent { */ typedef Containers::EnumSet Buttons; + /** @brief Copying is not allowed */ + InputEvent(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent(InputEvent&&) = delete; + + /** @brief Copying is not allowed */ + InputEvent& operator=(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent& operator=(InputEvent&&) = delete; + /** @brief Modifiers */ constexpr Modifiers modifiers() const { return _modifiers; } diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 8458fec55..d13a98dc4 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -454,11 +454,6 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::Flags) @ref mouseMoveEvent() */ class Sdl2Application::InputEvent { - InputEvent(const InputEvent&) = delete; - InputEvent(InputEvent&&) = delete; - InputEvent& operator=(const InputEvent&) = delete; - InputEvent& operator=(InputEvent&&) = delete; - public: /** * @brief %Modifier @@ -484,6 +479,18 @@ class Sdl2Application::InputEvent { */ typedef Containers::EnumSet Modifiers; + /** @brief Copying is not allowed */ + InputEvent(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent(InputEvent&&) = delete; + + /** @brief Copying is not allowed */ + InputEvent& operator=(const InputEvent&) = delete; + + /** @brief Moving is not allowed */ + InputEvent& operator=(InputEvent&&) = delete; + /** * @brief Set event as accepted * From f0eaf04e3674eb056a3870782c5dbe14e5d2f924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 20:58:05 +0100 Subject: [PATCH 17/32] Platform: make virtual functions private, rendering protected, other public. * The default (empty) implementation of virtuals shouldn't be called, thus this effectively protects the user from doing it. * Only the application itself knows best when and how to call rendering-related functions such as swapBuffers() and redraw(), thus they are protected. * Functions for setting up fullscreen or hiding the mouse may be called from user code outside the application, thus they are kept public. --- src/Platform/AbstractXApplication.h | 19 +++++++----- src/Platform/GlutApplication.h | 23 +++++++++----- src/Platform/NaClApplication.h | 47 ++++++++++++++++++----------- src/Platform/ScreenedApplication.h | 5 +++ src/Platform/Sdl2Application.h | 45 ++++++++++++++++----------- 5 files changed, 89 insertions(+), 50 deletions(-) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 9d0bb7f29..8e8a1ec40 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -111,13 +111,7 @@ class AbstractXApplication { /** @copydoc Sdl2Application::tryCreateContext() */ bool tryCreateContext(const Configuration& configuration); - /** @{ @name Drawing functions */ - - /** @copydoc Sdl2Application::viewportEvent() */ - virtual void viewportEvent(const Vector2i& size) = 0; - - /** @copydoc Sdl2Application::drawEvent() */ - virtual void drawEvent() = 0; + /** @{ @name Screen handling */ /** @copydoc Sdl2Application::swapBuffers() */ void swapBuffers(); @@ -125,6 +119,17 @@ class AbstractXApplication { /** @copydoc Sdl2Application::redraw() */ void redraw() { flags |= Flag::Redraw; } + #ifdef DOXYGEN_GENERATING_OUTPUT + protected: + #else + private: + #endif + /** @copydoc Sdl2Application::viewportEvent() */ + virtual void viewportEvent(const Vector2i& size) = 0; + + /** @copydoc Sdl2Application::drawEvent() */ + virtual void drawEvent() = 0; + /*@}*/ /** @{ @name Keyboard handling */ diff --git a/src/Platform/GlutApplication.h b/src/Platform/GlutApplication.h index 97452a23b..e7267abe7 100644 --- a/src/Platform/GlutApplication.h +++ b/src/Platform/GlutApplication.h @@ -137,13 +137,7 @@ class GlutApplication { /** @copydoc Sdl2Application::tryCreateContext() */ bool tryCreateContext(const Configuration& configuration); - /** @{ @name Drawing functions */ - - /** @copydoc Sdl2Application::viewportEvent() */ - virtual void viewportEvent(const Vector2i& size) = 0; - - /** @copydoc Sdl2Application::drawEvent() */ - virtual void drawEvent() = 0; + /** @{ @name Screen handling */ /** @copydoc Sdl2Application::swapBuffers() */ void swapBuffers() { glutSwapBuffers(); } @@ -151,6 +145,17 @@ class GlutApplication { /** @copydoc Sdl2Application::redraw() */ void redraw() { glutPostRedisplay(); } + #ifdef DOXYGEN_GENERATING_OUTPUT + protected: + #else + private: + #endif + /** @copydoc Sdl2Application::viewportEvent() */ + virtual void viewportEvent(const Vector2i& size) = 0; + + /** @copydoc Sdl2Application::drawEvent() */ + virtual void drawEvent() = 0; + /*@}*/ /** @{ @name Keyboard handling */ @@ -201,7 +206,11 @@ class GlutApplication { glutWarpPointer(position.x(), position.y()); } + #ifdef DOXYGEN_GENERATING_OUTPUT protected: + #else + private: + #endif /** @copydoc Sdl2Application::mousePressEvent() */ virtual void mousePressEvent(MouseEvent& event); diff --git a/src/Platform/NaClApplication.h b/src/Platform/NaClApplication.h index 2e48bfc2e..0c9203f03 100644 --- a/src/Platform/NaClApplication.h +++ b/src/Platform/NaClApplication.h @@ -172,19 +172,6 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public /** @brief Moving is not allowed */ NaClApplication& operator=(NaClApplication&&) = delete; - /** @brief Whether the application runs fullscreen */ - bool isFullscreen(); - - /** - * @brief Set fullscreen - * @return `False` if switch to opposite mode is in progress or if the - * switch is not possible, `true` otherwise. - * - * The switch is done asynchronously, during the switch no event - * processing is done. - */ - bool setFullscreen(bool enabled); - protected: /* Nobody will need to have (and delete) NaClApplication*, thus this is faster than public pure virtual destructor */ @@ -202,20 +189,40 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public /** @copydoc Sdl2Application::tryCreateContext() */ bool tryCreateContext(const Configuration& configuration); - /** @{ @name Drawing functions */ + /** @{ @name Screen handling */ - /** @copydoc Sdl2Application::viewportEvent() */ - virtual void viewportEvent(const Vector2i& size) = 0; + public: + /** @brief Whether the application runs fullscreen */ + bool isFullscreen(); - /** @copydoc Sdl2Application::drawEvent() */ - virtual void drawEvent() = 0; + /** + * @brief Set fullscreen + * @return `False` if switch to opposite mode is in progress or if the + * switch is not possible, `true` otherwise. + * + * The switch is done asynchronously, during the switch no event + * processing is done. + */ + bool setFullscreen(bool enabled); + protected: /** @copydoc Sdl2Application::swapBuffers() */ void swapBuffers(); /** @copydoc Sdl2Application::redraw() */ void redraw() { flags |= Flag::Redraw; } + #ifdef DOXYGEN_GENERATING_OUTPUT + protected: + #else + private: + #endif + /** @copydoc Sdl2Application::viewportEvent() */ + virtual void viewportEvent(const Vector2i& size) = 0; + + /** @copydoc Sdl2Application::drawEvent() */ + virtual void drawEvent() = 0; + /*@}*/ /** @{ @name Keyboard handling */ @@ -255,7 +262,11 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public */ void setMouseLocked(bool enabled); + #ifdef DOXYGEN_GENERATING_OUTPUT protected: + #else + private: + #endif /** * @brief Mouse press event * diff --git a/src/Platform/ScreenedApplication.h b/src/Platform/ScreenedApplication.h index dc962bdf9..2836a63b1 100644 --- a/src/Platform/ScreenedApplication.h +++ b/src/Platform/ScreenedApplication.h @@ -161,6 +161,11 @@ template class BasicScreenedApplication: public Application, this is faster than public pure virtual destructor */ ~BasicScreenedApplication(); + #ifdef DOXYGEN_GENERATING_OUTPUT + protected: + #else + private: + #endif /** * @brief Global viewport event * diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index d13a98dc4..7df1cbf30 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -210,8 +210,28 @@ class Sdl2Application { */ bool tryCreateContext(const Configuration& configuration); - /** @{ @name Drawing functions */ + /** @{ @name Screen handling */ + /** + * @brief Swap buffers + * + * Paints currently rendered framebuffer on screen. + */ + void swapBuffers(); + + /** + * @brief Redraw immediately + * + * Marks the window for redrawing, resulting in call to @ref drawEvent() + * in the next iteration. + */ + void redraw() { flags |= Flag::Redraw; } + + #ifdef DOXYGEN_GENERATING_OUTPUT + protected: + #else + private: + #endif /** * @brief Viewport event * @@ -236,21 +256,6 @@ class Sdl2Application { */ virtual void drawEvent() = 0; - /** - * @brief Swap buffers - * - * Paints currently rendered framebuffer on screen. - */ - void swapBuffers(); - - /** - * @brief Redraw immediately - * - * Marks the window for redrawing, resulting in call to @ref drawEvent() - * in the next iteration. - */ - void redraw() { flags |= Flag::Redraw; } - /*@}*/ /** @{ @name Keyboard handling */ @@ -281,12 +286,16 @@ class Sdl2Application { * @brief Enable or disable mouse locking * * When mouse is locked, the cursor is hidden and only - * MouseMoveEvent::relativePosition() is changing, absolute position - * stays the same. + * @ref MouseMoveEvent::relativePosition() is changing, absolute + * position stays the same. */ void setMouseLocked(bool enabled); + #ifdef DOXYGEN_GENERATING_OUTPUT protected: + #else + private: + #endif /** * @brief Mouse press event * From 02afa105dbaa161bd4a1c4e3f1bf15073c49ac61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 21:40:00 +0100 Subject: [PATCH 18/32] Doc++ --- doc/building.dox | 10 ++++------ doc/platform.dox | 9 ++++++--- src/Platform/AbstractXApplication.h | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/doc/building.dox b/doc/building.dox index c9be98045..08d302075 100644 --- a/doc/building.dox +++ b/doc/building.dox @@ -104,12 +104,10 @@ within QtCreator by adding new `make install` build rule. @subsubsection building-windows-troubleshooting Windows troubleshooting -If CMake isn't able to find dependencies (e.g. %Corrade is not found) and you -have installed them to MinGW directory, point to `CMAKE_FIND_ROOT_PATH` to -MinGW installation prefix, e.g. specify `-DCMAKE_FIND_ROOT_PATH=C:/MinGW/` -CMake parameter. - -See also Corrade's @ref building-corrade-windows-troubleshooting "troubleshooting section". +If CMake isn't able to find dependencies (e.g. %Corrade is not found), point +`CMAKE_FIND_ROOT_PATH` and `CMAKE_INSTALL_PREFIX` to installation prefix of +dependency libraries, e.g. specify `-DCMAKE_FIND_ROOT_PATH=C:/MinGW/` CMake +parameter. @subsection building-features Enabling or disabling features diff --git a/doc/platform.dox b/doc/platform.dox index 463066526..92574996b 100644 --- a/doc/platform.dox +++ b/doc/platform.dox @@ -55,7 +55,8 @@ directly in `main()`, but for convenience and portability it's better to use To simplify the porting, the library provides `Platform::Application` typedef and `MAGNUM_APPLICATION_MAIN()` macro (but only if only one application header is included, to avoid ambiguity). Changing the code to use different toolkit is -then matter of replacing only the #`include` statement. +then matter of replacing only the #`include` statement (and changing +one line in CMake build script, as you see later). Barebone application implementation which will just clear the window to dark blue color is shown in the following code listing. @@ -76,6 +77,7 @@ class MyApplication: public Platform::Application { public: MyApplication(const Arguments& arguments); + private: void viewportEvent(const Vector2i& viewport) override; void drawEvent() override; }; @@ -166,8 +168,9 @@ to it. Again, to simplify porting, you can also use generic `${MAGNUM_APPLICATION_INCLUDE_DIRS}` and `${MAGNUM_WAPPLICATION_LIBRARIES}` aliases (or `${MAGNUM_WINDOWLESSAPPLICATION_INCLUDE_DIRS}`, `${MAGNUM_WINDOWLESSAPPLICATION_LIBRARIES}` for windowless applications), but only if only one application (windowless application) component is requested to -avoid ambiguity. Changing the code to use different toolkit is then matter of -replacing only the requested `*Application` component. +avoid ambiguity. Changing the build script to use different toolkit is then +matter of replacing only the requested `*Application` component (and one +#`include` line in the actual code, as said above). @code find_package(Magnum REQUIRED GlutApplication) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 8e8a1ec40..b1cd8c867 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -193,8 +193,8 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::Flags) @brief %Configuration Double-buffered OpenGL context. -@see @ref GlxApplication(), @ref XEglApplication(), @ref createContext(), - @ref tryCreateContext() +@see @ref GlxApplication::GlxApplication(), @ref XeglApplication::XEglApplication(), + @ref createContext(), @ref tryCreateContext() @todo GLX_ARB_create_context_robustness/EGL_EXT_create_context_robustness */ class AbstractXApplication::Configuration { 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 19/32] 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... From 8be2293977df83b55f5a56c1de065a74e5f61ee5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 22:33:27 +0100 Subject: [PATCH 20/32] doc: updated Getting Started guide. --- doc/getting-started-blue.png | Bin 8205 -> 7677 bytes doc/getting-started.dox | 20 +++++++------------- doc/getting-started.png | Bin 8215 -> 7630 bytes 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/doc/getting-started-blue.png b/doc/getting-started-blue.png index 554613df2c27ade9ee46917eb3cf90a2e070994c..50b64d15cd99bdfa15f7e23c70f6422459b6ebcd 100644 GIT binary patch literal 7677 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 literal 8205 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 diff --git a/doc/getting-started.dox b/doc/getting-started.dox index c14c3e56f..297862778 100644 --- a/doc/getting-started.dox +++ b/doc/getting-started.dox @@ -94,8 +94,7 @@ class MyApplication: public Platform::Application { public: explicit MyApplication(const Arguments& arguments); - protected: - void viewportEvent(const Vector2i& size) override; + private: void drawEvent() override; }; @@ -103,10 +102,6 @@ MyApplication::MyApplication(const Arguments& arguments): Platform::Application( // TODO: Add your initialization code here } -void MyApplication::viewportEvent(const Vector2i& size) { - defaultFramebuffer.setViewport({{}, size}); -} - void MyApplication::drawEvent() { defaultFramebuffer.clear(FramebufferClear::Color); @@ -118,10 +113,10 @@ void MyApplication::drawEvent() { MAGNUM_APPLICATION_MAIN(MyApplication) @endcode -The application essentially does nothing, just clears properly sized screen -framebuffer to default (black) color and then does buffer swap to actually -display it on the screen. `CMakeLists.txt` finds %Magnum, sets up compiler -flags, creates the executable and links it to all needed libraries: +The application essentially does nothing, just clears screen framebuffer to +default (dark gray) color and then does buffer swap to actually display it on +the screen. `CMakeLists.txt` finds %Magnum, sets up compiler flags, creates the +executable and links it to all needed libraries: @code find_package(Magnum REQUIRED GlutApplication) @@ -181,9 +176,8 @@ Debug() << "Hello! This application is running on" << Context::current()->versio After rebuilding and starting the application, the clear color changes to blueish one and something like this would be printed to the console: -@code -Hello! This application is running on OpenGL 3.3 using Geforce GT 330M -@endcode + +> Hello! This application is running on OpenGL 3.3 using Geforce GT 330M @image html getting-started-blue.png @image latex getting-started-blue.png diff --git a/doc/getting-started.png b/doc/getting-started.png index cc0fc6112f11090702347a83ee48b7861983014b..7f4cf8c3ab82fa72f45aff6272a7df0332fa6a75 100644 GIT binary patch literal 7630 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 literal 8215 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 C{miNW From 80332478b6fe13c3437177c64cbcd2193357f161 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 23:10:26 +0100 Subject: [PATCH 21/32] MeshTools: be more explicit in what needs to be done on mesh afterwards. --- src/MeshTools/CompressIndices.h | 6 +++--- src/MeshTools/Interleave.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MeshTools/CompressIndices.h b/src/MeshTools/CompressIndices.h index 43ef9ae2e..fc4968d13 100644 --- a/src/MeshTools/CompressIndices.h +++ b/src/MeshTools/CompressIndices.h @@ -65,9 +65,9 @@ std::tuple> MAGNUM_MESHTOO @param indices Index array The same as @ref compressIndices(const std::vector&), but this -function writes the output to given buffer, updates index count and specifies -index buffer with proper index range in the mesh, so you don't have to call -@ref Mesh::setIndexCount() and @ref Mesh::setIndexBuffer() on your own. +function writes the output to given buffer and calls @ref Mesh::setIndexCount() +and @ref Mesh::setIndexBuffer(), thus you don't need to do anything else for +mesh index configuration. @see @ref MeshTools::interleave() */ diff --git a/src/MeshTools/Interleave.h b/src/MeshTools/Interleave.h index dc663456a..e9b33feed 100644 --- a/src/MeshTools/Interleave.h +++ b/src/MeshTools/Interleave.h @@ -190,8 +190,8 @@ The same as @ref interleave(const T&, const U&...), but this function writes the output to given array buffer and updates vertex count in the mesh accordingly, so you don't have to call @ref Mesh::setVertexCount() on your own. -@attention Setting primitive type and binding the attributes to shader is left - to user - see @ref Mesh-configuration "Mesh documentation". +@attention You still must call @ref Mesh::setPrimitive() and + @ref Mesh::addVertexBuffer() on the mesh afterwards. For only one attribute array this function is convenient equivalent to the following, without any performance loss: From 09c2f7ffe24cc5f88e90a18f8a335e5ff53c9b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 7 Dec 2013 23:10:51 +0100 Subject: [PATCH 22/32] Doc++ Finally I got it right. --- src/Platform/AbstractXApplication.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Platform/AbstractXApplication.h b/src/Platform/AbstractXApplication.h index 653a24092..73b020227 100644 --- a/src/Platform/AbstractXApplication.h +++ b/src/Platform/AbstractXApplication.h @@ -193,7 +193,7 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::Flags) @brief %Configuration Double-buffered OpenGL context. -@see @ref GlxApplication::GlxApplication(), @ref XeglApplication::XEglApplication(), +@see @ref GlxApplication::GlxApplication(), @ref XEglApplication::XEglApplication(), @ref createContext(), @ref tryCreateContext() @todo GLX_ARB_create_context_robustness/EGL_EXT_create_context_robustness */ From 79ff9e1ca4c23a94a264ae931da1d9fea6f65cf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 8 Dec 2013 02:24:53 +0100 Subject: [PATCH 23/32] Marking deprecated functions and types with CORRADE_DEPRECATED(). Sadly enum values can't be marked as such. --- src/AbstractShaderProgram.h | 2 +- src/AbstractTexture.h | 2 +- src/Buffer.h | 6 +++--- src/ImageFormat.h | 4 ++-- src/Magnum.h | 16 ++++++++++------ src/Math/Geometry/Rectangle.h | 6 ++++-- src/Sampler.h | 2 +- src/SceneGraph/Animable.h | 4 ++-- src/Swizzle.h | 2 +- src/Text/TextRenderer.h | 10 +++++----- 10 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index ee5418187..4ce0e6e46 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -340,7 +340,7 @@ class MAGNUM_EXPORT AbstractShaderProgram { * @deprecated Use @ref Magnum::AbstractShaderProgram::maxVertexAttributes() "maxVertexAttributes()" * instead. */ - static Int maxSupportedVertexAttributeCount() { return maxVertexAttributes(); } + static CORRADE_DEPRECATED("use maxVertexAttributes() instead") Int maxSupportedVertexAttributeCount() { return maxVertexAttributes(); } #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/AbstractTexture.h b/src/AbstractTexture.h index 406f4f674..d05ef82b5 100644 --- a/src/AbstractTexture.h +++ b/src/AbstractTexture.h @@ -115,7 +115,7 @@ class MAGNUM_EXPORT AbstractTexture { * @deprecated Use @ref Magnum::AbstractTexture::maxLayers() "maxLayers()" * instead. */ - static Int maxSupportedLayerCount() { return maxLayers(); } + static CORRADE_DEPRECATED("use maxLayers() instead") Int maxSupportedLayerCount() { return maxLayers(); } #endif #ifndef MAGNUM_TARGET_GLES diff --git a/src/Buffer.h b/src/Buffer.h index d65215739..a3fc8ca17 100644 --- a/src/Buffer.h +++ b/src/Buffer.h @@ -306,7 +306,7 @@ class MAGNUM_EXPORT Buffer { * @copybrief BufferUsage * @deprecated Use @ref Magnum::BufferUsage "BufferUsage" instead. */ - typedef BufferUsage Usage; + typedef CORRADE_DEPRECATED("use BufferUsage instead") BufferUsage Usage; #endif /** @@ -653,7 +653,7 @@ class MAGNUM_EXPORT Buffer { * @deprecated Use @ref Magnum::Buffer::setData(Containers::ArrayReference, BufferUsage) "setData(Containers::ArrayReference, BufferUsage)" * instead. */ - Buffer& setData(GLsizeiptr size, const GLvoid* data, BufferUsage usage) { + CORRADE_DEPRECATED("use setData(Containers::ArrayReference, BufferUsage) instead") Buffer& setData(GLsizeiptr size, const GLvoid* data, BufferUsage usage) { return setData({data, std::size_t(size)}, usage); } #endif @@ -693,7 +693,7 @@ class MAGNUM_EXPORT Buffer { * @deprecated Use @ref Magnum::Buffer::setSubData(GLintptr, Containers::ArrayReference) "setSubData(GLintptr, Containers::ArrayReference)" * instead. */ - Buffer& setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) { + CORRADE_DEPRECATED("use setSubData(GLintptr, Containers::ArrayReference) instead") Buffer& setSubData(GLintptr offset, GLsizeiptr size, const GLvoid* data) { return setSubData(offset, {data, std::size_t(size)}); } #endif diff --git a/src/ImageFormat.h b/src/ImageFormat.h index 5ec6e8a31..68b65db46 100644 --- a/src/ImageFormat.h +++ b/src/ImageFormat.h @@ -38,13 +38,13 @@ namespace Magnum { @copybrief ColorFormat @deprecated Use @ref Magnum::ColorFormat "ColorFormat" instead. */ -typedef ColorFormat ImageFormat; +typedef CORRADE_DEPRECATED("use ColorFormat instead") ColorFormat ImageFormat; /** @copybrief ColorType @deprecated Use @ref Magnum::ColorType "ColorType" instead. */ -typedef ColorType ImageType; +typedef CORRADE_DEPRECATED("use ColorType instead") ColorType ImageType; } #else diff --git a/src/Magnum.h b/src/Magnum.h index 3f6f49147..7485b1fcb 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -34,6 +34,10 @@ #include "Types.h" #include "magnumConfigure.h" +#ifdef MAGNUM_BUILD_DEPRECATED +#include +#endif + #ifndef DOXYGEN_GENERATING_OUTPUT typedef unsigned int GLenum; /* Needed for *Format and *Type enums */ #endif @@ -330,15 +334,15 @@ typedef Math::Range3D Range3Di; #ifdef MAGNUM_BUILD_DEPRECATED /** @copybrief Range2D -@deprecated Use @ref Magnum::Range2D instead. +@deprecated Use @ref Magnum::Range2D "Range2D" instead. */ -typedef Math::Geometry::Rectangle Rectangle; +typedef CORRADE_DEPRECATED("use Range2D instead") Math::Geometry::Rectangle Rectangle; /** @copybrief Range2Di -@deprecated Use @ref Magnum::Range2Di instead. +@deprecated Use @ref Magnum::Range2Di "Range2Di" instead. */ -typedef Math::Geometry::Rectangle Rectanglei; +typedef CORRADE_DEPRECATED("use Range2Di instead") Math::Geometry::Rectangle Rectanglei; #endif /*@}*/ @@ -388,7 +392,7 @@ typedef Math::Matrix<2, Double> Matrix2x2d; @copybrief Matrix2x2d @deprecated Use @ref Magnum::Matrix2x2d "Matrix2x2d" instead. */ -typedef Math::Matrix<2, Double> Matrix2d; +typedef CORRADE_DEPRECATED("use Matrix2x2d instead") Math::Matrix<2, Double> Matrix2d; #endif /** @@ -496,7 +500,7 @@ typedef Math::Range3D Range3Dd; @copybrief Range2Dd @deprecated Use @ref Magnum::Range2Dd instead. */ -typedef Math::Geometry::Rectangle Rectangled; +typedef CORRADE_DEPRECATED("use Range2Dd instead") Math::Geometry::Rectangle Rectangled; #endif /*@}*/ diff --git a/src/Math/Geometry/Rectangle.h b/src/Math/Geometry/Rectangle.h index bd2153a41..c3833fbf4 100644 --- a/src/Math/Geometry/Rectangle.h +++ b/src/Math/Geometry/Rectangle.h @@ -32,13 +32,15 @@ #include "Math/Range.h" #ifdef MAGNUM_BUILD_DEPRECATED +#include + namespace Magnum { namespace Math { namespace Geometry { /** @copybrief Math::Range2D -@deprecated Use @ref Magnum::Math::Range2D instead. +@deprecated Use @ref Magnum::Math::Range2D "Math::Range2D" instead. */ -template class Rectangle: public Range2D { +template class CORRADE_DEPRECATED("use Math::Range2D instead") Rectangle: public Range2D { public: /** @copydoc Range2D() */ constexpr Rectangle() = default; diff --git a/src/Sampler.h b/src/Sampler.h index 43d507720..85360d4af 100644 --- a/src/Sampler.h +++ b/src/Sampler.h @@ -149,7 +149,7 @@ class MAGNUM_EXPORT Sampler { * @deprecated Use @ref Magnum::Sampler::maxAnisotropy() "maxAnisotropy()" * instead. */ - static Float maxSupportedAnisotropy() { return maxAnisotropy(); } + static CORRADE_DEPRECATED("use maxAnisotropy() instead") Float maxSupportedAnisotropy() { return maxAnisotropy(); } #endif }; diff --git a/src/SceneGraph/Animable.h b/src/SceneGraph/Animable.h index 5779636f8..6da6a2d5a 100644 --- a/src/SceneGraph/Animable.h +++ b/src/SceneGraph/Animable.h @@ -229,14 +229,14 @@ template class Animable: public AbstractGrouped * @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()" * instead. */ - AnimableGroup* group() { return animables(); } + CORRADE_DEPRECATED("use animables() instead") AnimableGroup* group() { return animables(); } /** * @copydoc animables() * @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()" * instead. */ - const AnimableGroup* group() const { return animables(); } + CORRADE_DEPRECATED("use animables() instead") const AnimableGroup* group() const { return animables(); } #endif protected: diff --git a/src/Swizzle.h b/src/Swizzle.h index ecf717e8a..84b176aff 100644 --- a/src/Swizzle.h +++ b/src/Swizzle.h @@ -41,7 +41,7 @@ namespace Magnum { @deprecated Use @ref Magnum::Math::swizzle() "Math::swizzle()" instead. */ #ifdef DOXYGEN_GENERATING_OUTPUT -template constexpr typename Math::Implementation::TypeForSize::Type swizzle(const T& vector); +template constexpr CORRADE_DEPRECATED("use Math::swizzle() instead") typename Math::Implementation::TypeForSize::Type swizzle(const T& vector); #else using Math::swizzle; #endif diff --git a/src/Text/TextRenderer.h b/src/Text/TextRenderer.h index 53ed366d6..5f29e3270 100644 --- a/src/Text/TextRenderer.h +++ b/src/Text/TextRenderer.h @@ -3,24 +3,24 @@ #include "Text/Renderer.h" +#ifdef MAGNUM_BUILD_DEPRECATED namespace Magnum { namespace Text { -#ifdef MAGNUM_BUILD_DEPRECATED /** @copybrief Renderer2D @deprecated Use @ref Magnum::Text::Renderer2D "Renderer2D" instead. */ -typedef Renderer<2> TextRenderer2D; +typedef CORRADE_DEPRECATED("use Renderer2D instead") Renderer<2> TextRenderer2D; /** @copybrief Renderer3D @deprecated Use @ref Magnum::Text::Renderer3D "Renderer3D" instead. */ -typedef Renderer<3> TextRenderer3D; +typedef CORRADE_DEPRECATED("use Renderer2D instead") Renderer<3> TextRenderer3D; + +}} #else #error #endif -}} - #endif From 8d01723084a46cbe14083fb36ad64a963f85649e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 8 Dec 2013 14:58:13 +0100 Subject: [PATCH 24/32] Fixed static build. --- src/Shaders/magnumShadersResourceImport.hpp | 2 +- src/TextureTools/magnumTextureToolsResourceImport.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Shaders/magnumShadersResourceImport.hpp b/src/Shaders/magnumShadersResourceImport.hpp index 10b70a5b0..419601905 100644 --- a/src/Shaders/magnumShadersResourceImport.hpp +++ b/src/Shaders/magnumShadersResourceImport.hpp @@ -28,7 +28,7 @@ #ifdef MAGNUM_BUILD_STATIC #include -#include +#include static int magnumShadersResourceImport() { CORRADE_RESOURCE_INITIALIZE(MagnumShaders_RCS) diff --git a/src/TextureTools/magnumTextureToolsResourceImport.hpp b/src/TextureTools/magnumTextureToolsResourceImport.hpp index 9d2c9a3c1..9ac0777df 100644 --- a/src/TextureTools/magnumTextureToolsResourceImport.hpp +++ b/src/TextureTools/magnumTextureToolsResourceImport.hpp @@ -28,7 +28,7 @@ #ifdef MAGNUM_BUILD_STATIC #include -#include +#include static int magnumTextureToolsResourceImport() { CORRADE_RESOURCE_INITIALIZE(MagnumTextureTools_RCS) From 686e215725198d35306f3b280ec2065c42d5321f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 8 Dec 2013 14:58:38 +0100 Subject: [PATCH 25/32] GCC 4.6 compatibility: can't use both constexpr and const. --- src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp index 0a03fcd45..cc9365fa2 100644 --- a/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp +++ b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp @@ -49,7 +49,7 @@ class TgaImageConverterTest: public TestSuite::Tester { }; namespace { - constexpr const char originalData[] = { + constexpr char originalData[] = { 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7, 6, 7, 8 From ef83211c4674df9f07f5ac69476691d88652769c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 10 Dec 2013 11:48:17 +0100 Subject: [PATCH 26/32] Shaders: fix textured Flat on systems w/o ARB_explicit_attribute_location. How could I possibly overlook this. --- src/Shaders/Flat.frag | 4 ++-- src/Shaders/Flat2D.vert | 8 ++++---- src/Shaders/Flat3D.vert | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Shaders/Flat.frag b/src/Shaders/Flat.frag index 2cd2453e7..35e85bfcd 100644 --- a/src/Shaders/Flat.frag +++ b/src/Shaders/Flat.frag @@ -43,7 +43,7 @@ uniform lowp vec4 color; #endif #ifdef TEXTURED -in mediump vec2 interpolatedTextureCoords; +in mediump vec2 interpolatedTextureCoordinates; #endif #ifdef NEW_GLSL @@ -52,7 +52,7 @@ out lowp vec4 fragmentColor; void main() { #ifdef TEXTURED - fragmentColor = texture(textureData, interpolatedTextureCoords); + fragmentColor = texture(textureData, interpolatedTextureCoordinates); #else fragmentColor = color; #endif diff --git a/src/Shaders/Flat2D.vert b/src/Shaders/Flat2D.vert index 34bd475af..b06a8839d 100644 --- a/src/Shaders/Flat2D.vert +++ b/src/Shaders/Flat2D.vert @@ -41,11 +41,11 @@ in highp vec2 position; #ifdef TEXTURED #ifdef EXPLICIT_ATTRIB_LOCATION -layout(location = TEXTURECOORDINATES_ATTRIBUTE_LOCATION) in mediump vec2 textureCoords; +layout(location = TEXTURECOORDINATES_ATTRIBUTE_LOCATION) in mediump vec2 textureCoordinates; #else -in mediump vec2 textureCoords; +in mediump vec2 textureCoordinates; #endif -out mediump vec2 interpolatedTextureCoords; +out mediump vec2 interpolatedTextureCoordinates; #endif void main() { @@ -53,6 +53,6 @@ void main() { #ifdef TEXTURED /* Texture coordinates, if needed */ - interpolatedTextureCoords = textureCoords; + interpolatedTextureCoordinates = textureCoordinates; #endif } diff --git a/src/Shaders/Flat3D.vert b/src/Shaders/Flat3D.vert index 000db457f..12b8d1a2d 100644 --- a/src/Shaders/Flat3D.vert +++ b/src/Shaders/Flat3D.vert @@ -41,11 +41,11 @@ in highp vec4 position; #ifdef TEXTURED #ifdef EXPLICIT_ATTRIB_LOCATION -layout(location = TEXTURECOORDINATES_ATTRIBUTE_LOCATION) in mediump vec2 textureCoords; +layout(location = TEXTURECOORDINATES_ATTRIBUTE_LOCATION) in mediump vec2 textureCoordinates; #else -in mediump vec2 textureCoords; +in mediump vec2 textureCoordinates; #endif -out mediump vec2 interpolatedTextureCoords; +out mediump vec2 interpolatedTextureCoordinates; #endif void main() { @@ -53,6 +53,6 @@ void main() { #ifdef TEXTURED /* Texture coordinates, if needed */ - interpolatedTextureCoords = textureCoords; + interpolatedTextureCoordinates = textureCoordinates; #endif } From d945395800591c9ae7a2054a17c9e0727026910e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 11 Dec 2013 12:22:08 +0100 Subject: [PATCH 27/32] Using Corrade::Utility::Directory::{read,write}() where possible. Much shorter code now with less redundancy. --- src/Audio/AbstractImporter.cpp | 16 ++--------- src/Shader.cpp | 20 +++---------- src/Text/AbstractFont.cpp | 16 ++--------- src/Text/AbstractFontConverter.cpp | 42 ++++++---------------------- src/Trade/AbstractImageConverter.cpp | 9 ++---- src/Trade/AbstractImporter.cpp | 16 ++--------- 6 files changed, 25 insertions(+), 94 deletions(-) diff --git a/src/Audio/AbstractImporter.cpp b/src/Audio/AbstractImporter.cpp index ab3178154..5272673f6 100644 --- a/src/Audio/AbstractImporter.cpp +++ b/src/Audio/AbstractImporter.cpp @@ -24,9 +24,9 @@ #include "AbstractImporter.h" -#include #include #include +#include namespace Magnum { namespace Audio { @@ -57,22 +57,12 @@ void AbstractImporter::doOpenFile(const std::string& filename) { CORRADE_ASSERT(features() & Feature::OpenData, "Audio::AbstractImporter::openFile(): not implemented", ); /* Open file */ - std::ifstream in(filename.data(), std::ios::binary); - if(!in.good()) { + if(!Utility::Directory::fileExists(filename)) { Error() << "Trade::AbstractImporter::openFile(): cannot open file" << filename; return; } - /* Create array to hold file contents */ - in.seekg(0, std::ios::end); - Containers::Array data(in.tellg()); - - /* Read data, close */ - in.seekg(0, std::ios::beg); - in.read(reinterpret_cast(data.begin()), data.size()); - in.close(); - - doOpenData(data); + doOpenData(Utility::Directory::read(filename)); } void AbstractImporter::close() { diff --git a/src/Shader.cpp b/src/Shader.cpp index 664871931..2b928309d 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -24,9 +24,9 @@ #include "Shader.h" -#include #include #include +#include #include "Extensions.h" #include "Implementation/State.h" @@ -604,22 +604,10 @@ Shader& Shader::addSource(std::string source) { } Shader& Shader::addFile(const std::string& filename) { - /* Open file */ - std::ifstream file(filename); - CORRADE_ASSERT(file.good(), "Shader file " << '\'' + filename + '\'' << " cannot be opened.", *this); - - /* Get size of shader and initialize buffer */ - file.seekg(0, std::ios::end); - std::string source(std::size_t(file.tellg()), '\0'); - - /* Read data, close */ - file.seekg(0, std::ios::beg); - file.read(&source[0], source.size()); - file.close(); - - /* Move to sources */ - addSource(std::move(source)); + CORRADE_ASSERT(Utility::Directory::fileExists(filename), + "Shader file " << '\'' + filename + '\'' << " cannot be read.", *this); + addSource(Utility::Directory::readString(filename)); return *this; } diff --git a/src/Text/AbstractFont.cpp b/src/Text/AbstractFont.cpp index 0d92fc077..86c17749c 100644 --- a/src/Text/AbstractFont.cpp +++ b/src/Text/AbstractFont.cpp @@ -24,8 +24,8 @@ #include "AbstractFont.h" -#include #include +#include #include #include "Text/GlyphCache.h" @@ -86,22 +86,12 @@ std::pair AbstractFont::doOpenFile(const std::string& filename, co "Text::AbstractFont::openFile(): not implemented", {}); /* Open file */ - std::ifstream in(filename.data(), std::ios::binary); - if(!in.good()) { + if(!Utility::Directory::fileExists(filename)) { Error() << "Trade::AbstractFont::openFile(): cannot open file" << filename; return {}; } - /* Create array to hold file contents */ - in.seekg(0, std::ios::end); - Containers::Array data(std::size_t(in.tellg())); - - /* Read data, close */ - in.seekg(0, std::ios::beg); - in.read(reinterpret_cast(data.begin()), data.size()); - in.close(); - - return doOpenSingleData(data, size); + return doOpenSingleData(Utility::Directory::read(filename), size); } void AbstractFont::close() { diff --git a/src/Text/AbstractFontConverter.cpp b/src/Text/AbstractFontConverter.cpp index 9dd5e4320..e375e5fd7 100644 --- a/src/Text/AbstractFontConverter.cpp +++ b/src/Text/AbstractFontConverter.cpp @@ -25,9 +25,9 @@ #include "AbstractFontConverter.h" #include -#include #include #include +#include #include #include "Text/GlyphCache.h" @@ -96,16 +96,9 @@ bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& c /* Export all data */ const auto data = doExportFontToData(font, cache, filename, characters); - for(const auto& d: data) { - /* Open file */ - std::ofstream out(d.first.data(), std::ios::binary); - if(!out.good()) { - Error() << "Text::AbstractFontConverter::exportFontToFile(): cannot write to file" << d.first; - return false; - } - - /* Write data, close */ - out.write(reinterpret_cast(d.second.begin()), d.second.size()); + for(const auto& d: data) if(!Utility::Directory::write(d.first, d.second)) { + Error() << "Text::AbstractFontConverter::exportFontToFile(): cannot write to file" << d.first; + return false; } return true; @@ -154,16 +147,9 @@ bool AbstractFontConverter::doExportGlyphCacheToFile(GlyphCache& cache, const st /* Export all data */ const auto data = doExportGlyphCacheToData(cache, filename); - for(const auto& d: data) { - /* Open file */ - std::ofstream out(d.first.data(), std::ios::binary); - if(!out.good()) { - Error() << "Text::AbstractFontConverter::exportGlyphCacheToFile(): cannot write to file" << d.first; - return false; - } - - /* Write data, close */ - out.write(reinterpret_cast(d.second.begin()), d.second.size()); + for(const auto& d: data) if(!Utility::Directory::write(d.first, d.second)) { + Error() << "Text::AbstractFontConverter::exportGlyphCacheToFile(): cannot write to file" << d.first; + return false; } return true; @@ -213,22 +199,12 @@ std::unique_ptr AbstractFontConverter::doImportGlyphCacheFromFile(co "Text::AbstractFontConverter::importGlyphCacheFromFile(): not implemented", nullptr); /* Open file */ - std::ifstream in(filename.data(), std::ios::binary); - if(!in.good()) { + if(!Utility::Directory::fileExists(filename)) { Error() << "Trade::AbstractFontConverter::importGlyphCacheFromFile(): cannot open file" << filename; return nullptr; } - /* Create array to hold file contents */ - in.seekg(0, std::ios::end); - Containers::Array data(std::size_t(in.tellg())); - - /* Read data, close */ - in.seekg(0, std::ios::beg); - in.read(reinterpret_cast(data.begin()), data.size()); - in.close(); - - return doImportGlyphCacheFromSingleData(data); + return doImportGlyphCacheFromSingleData(Utility::Directory::read(filename)); } #ifndef __MINGW32__ diff --git a/src/Trade/AbstractImageConverter.cpp b/src/Trade/AbstractImageConverter.cpp index 5bdf5e8b4..705bef996 100644 --- a/src/Trade/AbstractImageConverter.cpp +++ b/src/Trade/AbstractImageConverter.cpp @@ -24,9 +24,9 @@ #include "AbstractImageConverter.h" -#include #include #include +#include namespace Magnum { namespace Trade { @@ -63,18 +63,15 @@ bool AbstractImageConverter::exportToFile(const ImageReference2D& image, const s bool AbstractImageConverter::doExportToFile(const ImageReference2D& image, const std::string& filename) const { CORRADE_ASSERT(features() & Feature::ConvertData, "Trade::AbstractImageConverter::exportToFile(): not implemented", false); - auto data = doExportToData(image); + const auto data = doExportToData(image); if(!data) return false; /* Open file */ - std::ofstream out(filename.data(), std::ios::binary); - if(!out.good()) { + if(!Utility::Directory::write(filename, data)) { Error() << "Trade::AbstractImageConverter::exportToFile(): cannot write to file" << filename; return false; } - /* Write data, close */ - out.write(reinterpret_cast(data.begin()), data.size()); return true; } diff --git a/src/Trade/AbstractImporter.cpp b/src/Trade/AbstractImporter.cpp index 76ec4021a..53dedd74b 100644 --- a/src/Trade/AbstractImporter.cpp +++ b/src/Trade/AbstractImporter.cpp @@ -24,9 +24,9 @@ #include "AbstractImporter.h" -#include #include #include +#include #include "Trade/AbstractMaterialData.h" #include "Trade/CameraData.h" @@ -68,22 +68,12 @@ void AbstractImporter::doOpenFile(const std::string& filename) { CORRADE_ASSERT(features() & Feature::OpenData, "Trade::AbstractImporter::openFile(): not implemented", ); /* Open file */ - std::ifstream in(filename.data(), std::ios::binary); - if(!in.good()) { + if(!Utility::Directory::fileExists(filename)) { Error() << "Trade::AbstractImporter::openFile(): cannot open file" << filename; return; } - /* Create array to hold file contents */ - in.seekg(0, std::ios::end); - Containers::Array data(std::size_t(in.tellg())); - - /* Read data, close */ - in.seekg(0, std::ios::beg); - in.read(reinterpret_cast(data.begin()), data.size()); - in.close(); - - doOpenData(data); + doOpenData(Utility::Directory::read(filename)); } void AbstractImporter::close() { From 2dd61a4dcdfd63a83bbae7dfac30afd43cfa2109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 11 Dec 2013 13:12:53 +0100 Subject: [PATCH 28/32] Platform: fixed assertions. --- src/Platform/AbstractXApplication.cpp | 2 +- src/Platform/WindowlessGlxApplication.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Platform/AbstractXApplication.cpp b/src/Platform/AbstractXApplication.cpp index 20c33d53b..32bb5ea98 100644 --- a/src/Platform/AbstractXApplication.cpp +++ b/src/Platform/AbstractXApplication.cpp @@ -51,7 +51,7 @@ void AbstractXApplication::createContext(const Configuration& configuration) { } bool AbstractXApplication::tryCreateContext(const Configuration& configuration) { - CORRADE_ASSERT(!c, "AbstractXApplication::tryCreateContext(): context already created", ); + CORRADE_ASSERT(!c, "AbstractXApplication::tryCreateContext(): context already created", false); viewportSize = configuration.size(); diff --git a/src/Platform/WindowlessGlxApplication.cpp b/src/Platform/WindowlessGlxApplication.cpp index 357d9eae3..30c20b3cf 100644 --- a/src/Platform/WindowlessGlxApplication.cpp +++ b/src/Platform/WindowlessGlxApplication.cpp @@ -54,7 +54,7 @@ void WindowlessGlxApplication::createContext(const Configuration& configuration) } bool WindowlessGlxApplication::tryCreateContext(const Configuration&) { - CORRADE_ASSERT(!c, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", ); + CORRADE_ASSERT(!c, "Platform::WindowlessGlxApplication::tryCreateContext(): context already created", false); display = XOpenDisplay(nullptr); From 5d9490c73bc99a5b24b9fcdd37c716d122aed1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 11 Dec 2013 12:59:22 +0100 Subject: [PATCH 29/32] Extracted Primitive enum from Mesh to MeshPrimitive. Because we can't forward-declare class members we would need to include whole Mesh (along with all OpenGL headers and other stuff) just to use Primitive enum. The old Mesh::Primitive is now alias to new one, is marked as deprecated and will be removed in future release. --- src/DebugTools/ForceRenderer.cpp | 2 +- .../Implementation/AbstractBoxRenderer.cpp | 1 + .../Implementation/CapsuleRenderer.cpp | 1 + src/DebugTools/ObjectRenderer.cpp | 2 +- src/Magnum.h | 2 + src/Mesh.cpp | 18 +- src/Mesh.h | 174 +++++++++--------- src/MeshTools/FullScreenTriangle.cpp | 2 +- src/Primitives/Capsule.cpp | 9 +- src/Primitives/Capsule.h | 10 +- src/Primitives/Circle.cpp | 9 +- src/Primitives/Circle.h | 4 +- src/Primitives/Crosshair.cpp | 5 +- src/Primitives/Crosshair.h | 4 +- src/Primitives/Cube.cpp | 5 +- src/Primitives/Cube.h | 4 +- src/Primitives/Cylinder.cpp | 5 +- src/Primitives/Cylinder.h | 4 +- src/Primitives/Icosphere.cpp | 5 +- src/Primitives/Icosphere.h | 2 +- src/Primitives/Implementation/Spheroid.cpp | 3 +- .../Implementation/WireframeSpheroid.cpp | 3 +- src/Primitives/Line.cpp | 5 +- src/Primitives/Line.h | 4 +- src/Primitives/Plane.cpp | 5 +- src/Primitives/Plane.h | 4 +- src/Primitives/Square.cpp | 5 +- src/Primitives/Square.h | 4 +- src/Primitives/UVSphere.cpp | 5 +- src/Primitives/UVSphere.h | 8 +- src/Test/MeshTest.cpp | 8 +- src/Text/Renderer.cpp | 4 +- src/TextureTools/DistanceField.cpp | 2 +- src/Trade/MeshData2D.cpp | 2 +- src/Trade/MeshData2D.h | 12 +- src/Trade/MeshData3D.cpp | 2 +- src/Trade/MeshData3D.h | 12 +- 37 files changed, 192 insertions(+), 164 deletions(-) diff --git a/src/DebugTools/ForceRenderer.cpp b/src/DebugTools/ForceRenderer.cpp index e72c03551..cf5f75421 100644 --- a/src/DebugTools/ForceRenderer.cpp +++ b/src/DebugTools/ForceRenderer.cpp @@ -86,7 +86,7 @@ template ForceRenderer::ForceRenderer(SceneG ResourceManager::instance().set(this->indexBuffer.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); Mesh* mesh = new Mesh; - mesh->setPrimitive(Mesh::Primitive::Lines) + mesh->setPrimitive(MeshPrimitive::Lines) .setIndexCount(indices.size()) .addVertexBuffer(*vertexBuffer, 0, typename Shaders::Flat::Position(Shaders::Flat::Position::Components::Two)) diff --git a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp index 5c7624d37..8e5cd07b6 100644 --- a/src/DebugTools/Implementation/AbstractBoxRenderer.cpp +++ b/src/DebugTools/Implementation/AbstractBoxRenderer.cpp @@ -24,6 +24,7 @@ #include "AbstractBoxRenderer.h" +#include "Mesh.h" #include "Primitives/Cube.h" #include "Primitives/Square.h" #include "Trade/MeshData2D.h" diff --git a/src/DebugTools/Implementation/CapsuleRenderer.cpp b/src/DebugTools/Implementation/CapsuleRenderer.cpp index ef158ba7a..a2f3d9568 100644 --- a/src/DebugTools/Implementation/CapsuleRenderer.cpp +++ b/src/DebugTools/Implementation/CapsuleRenderer.cpp @@ -24,6 +24,7 @@ #include "CapsuleRenderer.h" +#include "Mesh.h" #include "MeshView.h" #include "DebugTools/ResourceManager.h" #include "DebugTools/ShapeRenderer.h" diff --git a/src/DebugTools/ObjectRenderer.cpp b/src/DebugTools/ObjectRenderer.cpp index 84cb49177..dd20e7d8c 100644 --- a/src/DebugTools/ObjectRenderer.cpp +++ b/src/DebugTools/ObjectRenderer.cpp @@ -164,7 +164,7 @@ template ObjectRenderer::ObjectRenderer(Scen indexBuffer->setData(Renderer::indices, BufferUsage::StaticDraw); ResourceManager::instance().set(this->indexBuffer.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual); - mesh->setPrimitive(Mesh::Primitive::Lines) + mesh->setPrimitive(MeshPrimitive::Lines) .setIndexCount(Renderer::indices.size()) .addVertexBuffer(*vertexBuffer, 0, typename Shaders::VertexColor::Position(), diff --git a/src/Magnum.h b/src/Magnum.h index 7485b1fcb..95494aeb9 100644 --- a/src/Magnum.h +++ b/src/Magnum.h @@ -582,6 +582,8 @@ typedef ImageReference<1> ImageReference1D; typedef ImageReference<2> ImageReference2D; typedef ImageReference<3> ImageReference3D; +enum class MeshPrimitive: GLenum; + class Mesh; class MeshView; diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 8c8cdd234..6aa1e8475 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -82,7 +82,7 @@ std::size_t Mesh::indexSize(IndexType type) { CORRADE_ASSERT_UNREACHABLE(); } -Mesh::Mesh(Primitive primitive): _primitive(primitive), _vertexCount(0), _indexCount(0) +Mesh::Mesh(MeshPrimitive primitive): _primitive(primitive), _vertexCount(0), _indexCount(0) #ifndef MAGNUM_TARGET_GLES2 , _indexStart(0), _indexEnd(0) #endif @@ -379,9 +379,9 @@ void Mesh::unbindImplementationDefault() { void Mesh::unbindImplementationVAO() {} #ifndef DOXYGEN_GENERATING_OUTPUT -Debug operator<<(Debug debug, Mesh::Primitive value) { +Debug operator<<(Debug debug, MeshPrimitive value) { switch(value) { - #define _c(value) case Mesh::Primitive::value: return debug << "Mesh::Primitive::" #value; + #define _c(value) case MeshPrimitive::value: return debug << "MeshPrimitive::" #value; _c(Points) _c(LineStrip) _c(LineLoop) @@ -401,7 +401,7 @@ Debug operator<<(Debug debug, Mesh::Primitive value) { #undef _c } - return debug << "Mesh::Primitive::(invalid)"; + return debug << "MeshPrimitive::(invalid)"; } Debug operator<<(Debug debug, Mesh::IndexType value) { @@ -421,9 +421,9 @@ Debug operator<<(Debug debug, Mesh::IndexType value) { namespace Corrade { namespace Utility { -std::string ConfigurationValue::toString(Magnum::Mesh::Primitive value, ConfigurationValueFlags) { +std::string ConfigurationValue::toString(Magnum::MeshPrimitive value, ConfigurationValueFlags) { switch(value) { - #define _c(value) case Magnum::Mesh::Primitive::value: return #value; + #define _c(value) case Magnum::MeshPrimitive::value: return #value; _c(Points) _c(LineStrip) _c(LineLoop) @@ -446,8 +446,8 @@ std::string ConfigurationValue::toString(Magnum::Mesh:: return {}; } -Magnum::Mesh::Primitive ConfigurationValue::fromString(const std::string& stringValue, ConfigurationValueFlags) { - #define _c(value) if(stringValue == #value) return Magnum::Mesh::Primitive::value; +Magnum::MeshPrimitive ConfigurationValue::fromString(const std::string& stringValue, ConfigurationValueFlags) { + #define _c(value) if(stringValue == #value) return Magnum::MeshPrimitive::value; _c(LineStrip) _c(LineLoop) _c(Lines) @@ -465,7 +465,7 @@ Magnum::Mesh::Primitive ConfigurationValue::fromString( #endif #undef _c - return Magnum::Mesh::Primitive::Points; + return Magnum::MeshPrimitive::Points; } std::string ConfigurationValue::toString(Magnum::Mesh::IndexType value, ConfigurationValueFlags) { diff --git a/src/Mesh.h b/src/Mesh.h index 8af843eec..57af67504 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -35,6 +35,80 @@ namespace Magnum { +/** + * @brief %Mesh primitive type + * + * @see @ref Mesh::primitive(), @ref Mesh::setPrimitive() + */ +enum class MeshPrimitive: GLenum { + /** Single points. */ + Points = GL_POINTS, + + /** + * First two vertices define first line segment, each following + * vertex defines another segment. + */ + LineStrip = GL_LINE_STRIP, + + /** Line strip, last and first vertex are connected together. */ + LineLoop = GL_LINE_LOOP, + + /** + * Each pair of vertices defines a single line, lines aren't + * connected together. + */ + Lines = GL_LINES, + + #ifndef MAGNUM_TARGET_GLES + /** + * Line strip with adjacency information. + * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + */ + LineStripAdjacency = GL_LINE_STRIP_ADJACENCY, + + /** + * Lines with adjacency information. + * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + */ + LinesAdjacency = GL_LINES_ADJACENCY, + #endif + + /** + * First three vertices define first triangle, each following + * vertex defines another triangle. + */ + TriangleStrip = GL_TRIANGLE_STRIP, + + /** + * First vertex is center, each following vertex is connected to + * previous and center vertex. + */ + TriangleFan = GL_TRIANGLE_FAN, + + /** Each three vertices define one triangle. */ + Triangles = GL_TRIANGLES, + + #ifndef MAGNUM_TARGET_GLES + /** + * Triangle strip with adjacency information. + * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + */ + TriangleStripAdjacency = GL_TRIANGLE_STRIP_ADJACENCY, + + /** + * Triangles with adjacency information. + * @requires_gl32 %Extension @extension{ARB,geometry_shader4} + */ + TrianglesAdjacency = GL_TRIANGLES_ADJACENCY, + + /** + * Patches. + * @requires_gl40 %Extension @extension{ARB,tessellation_shader} + */ + Patches = GL_PATCHES + #endif +}; + /** @brief %Mesh @@ -86,7 +160,7 @@ static constexpr Vector3 positions[30] = { vertexBuffer.setData(positions, BufferUsage::StaticDraw); // Set primitive and vertex count, add the buffer and specify its layout -mesh.setPrimitive(Mesh::Primitive::Triangles) +mesh.setPrimitive(MeshPrimitive::Triangles) .setVertexCount(30) .addVertexBuffer(vertexBuffer, 0, MyShader::Position()); @endcode @@ -135,7 +209,7 @@ static constexpr GLubyte indices[75] = { indexBuffer.setData(indices, BufferUsage::StaticDraw); // Set primitive, index count, specify the buffers -mesh.setPrimitive(Mesh::Primitive::Triangles) +mesh.setPrimitive(MeshPrimitive::Triangles) .setIndexCount(75) .addVertexBuffer(vertexBuffer, 0, MyShader::Position()) .setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229); @@ -238,79 +312,13 @@ class MAGNUM_EXPORT Mesh { friend class MeshView; public: + #ifdef MAGNUM_BUILD_DEPRECATED /** - * @brief Primitive type - * - * @see @ref primitive(), @ref setPrimitive() + * @copybrief MeshPrimitive + * @deprecated Use @ref Magnum::MeshPrimitive "MeshPrimitive" instead. */ - enum class Primitive: GLenum { - /** Single points. */ - Points = GL_POINTS, - - /** - * First two vertices define first line segment, each following - * vertex defines another segment. - */ - LineStrip = GL_LINE_STRIP, - - /** Line strip, last and first vertex are connected together. */ - LineLoop = GL_LINE_LOOP, - - /** - * Each pair of vertices defines a single line, lines aren't - * connected together. - */ - Lines = GL_LINES, - - #ifndef MAGNUM_TARGET_GLES - /** - * Line strip with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} - */ - LineStripAdjacency = GL_LINE_STRIP_ADJACENCY, - - /** - * Lines with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} - */ - LinesAdjacency = GL_LINES_ADJACENCY, - #endif - - /** - * First three vertices define first triangle, each following - * vertex defines another triangle. - */ - TriangleStrip = GL_TRIANGLE_STRIP, - - /** - * First vertex is center, each following vertex is connected to - * previous and center vertex. - */ - TriangleFan = GL_TRIANGLE_FAN, - - /** Each three vertices define one triangle. */ - Triangles = GL_TRIANGLES, - - #ifndef MAGNUM_TARGET_GLES - /** - * Triangle strip with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} - */ - TriangleStripAdjacency = GL_TRIANGLE_STRIP_ADJACENCY, - - /** - * Triangles with adjacency information. - * @requires_gl32 %Extension @extension{ARB,geometry_shader4} - */ - TrianglesAdjacency = GL_TRIANGLES_ADJACENCY, - - /** - * Patches. - * @requires_gl40 %Extension @extension{ARB,tessellation_shader} - */ - Patches = GL_PATCHES - #endif - }; + typedef CORRADE_DEPRECATED("use MeshPrimitive instead") MeshPrimitive Primitive; + #endif /** * @brief Index type @@ -377,7 +385,7 @@ class MAGNUM_EXPORT Mesh { * @see @ref setPrimitive(), @ref setVertexCount(), @fn_gl{GenVertexArrays} * (if @extension{APPLE,vertex_array_object} is available) */ - explicit Mesh(Primitive primitive = Primitive::Triangles); + explicit Mesh(MeshPrimitive primitive = MeshPrimitive::Triangles); /** @brief Copying is not allowed */ Mesh(const Mesh&) = delete; @@ -407,16 +415,16 @@ class MAGNUM_EXPORT Mesh { std::size_t indexSize() const { return indexSize(_indexType); } /** @brief Primitive type */ - Primitive primitive() const { return _primitive; } + MeshPrimitive primitive() const { return _primitive; } /** * @brief Set primitive type * @return Reference to self (for method chaining) * - * Default is @ref Primitive::Triangles. + * Default is @ref MeshPrimitive::Triangles. * @see @ref setVertexCount(), @ref addVertexBuffer() */ - Mesh& setPrimitive(Primitive primitive) { + Mesh& setPrimitive(MeshPrimitive primitive) { _primitive = primitive; return *this; } @@ -743,7 +751,7 @@ class MAGNUM_EXPORT Mesh { static MAGNUM_LOCAL UnbindImplementation unbindImplementation; GLuint _id; - Primitive _primitive; + MeshPrimitive _primitive; Int _vertexCount, _indexCount; #ifndef MAGNUM_TARGET_GLES2 UnsignedInt _indexStart, _indexEnd; @@ -762,7 +770,7 @@ class MAGNUM_EXPORT Mesh { }; /** @debugoperator{Magnum::Mesh} */ -Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::Primitive value); +Debug MAGNUM_EXPORT operator<<(Debug debug, MeshPrimitive value); /** @debugoperator{Magnum::Mesh} */ Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::IndexType value); @@ -772,7 +780,7 @@ Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::IndexType value); namespace Corrade { namespace Utility { /** @configurationvalue{Magnum::Mesh} */ -template<> struct MAGNUM_EXPORT ConfigurationValue { +template<> struct MAGNUM_EXPORT ConfigurationValue { ConfigurationValue() = delete; /** @@ -780,14 +788,14 @@ template<> struct MAGNUM_EXPORT ConfigurationValue { * * If the value is invalid, returns empty string. */ - static std::string toString(Magnum::Mesh::Primitive value, ConfigurationValueFlags); + static std::string toString(Magnum::MeshPrimitive value, ConfigurationValueFlags); /** * @brief Reads enum value as string * - * If the value is invalid, returns @ref Magnum::Mesh::Primitive::Points "Mesh::Primitive::Points". + * If the value is invalid, returns @ref Magnum::MeshPrimitive::Points "MeshPrimitive::Points". */ - static Magnum::Mesh::Primitive fromString(const std::string& stringValue, ConfigurationValueFlags); + static Magnum::MeshPrimitive fromString(const std::string& stringValue, ConfigurationValueFlags); }; /** @configurationvalue{Magnum::Mesh} */ diff --git a/src/MeshTools/FullScreenTriangle.cpp b/src/MeshTools/FullScreenTriangle.cpp index da3518248..80d7ca37f 100644 --- a/src/MeshTools/FullScreenTriangle.cpp +++ b/src/MeshTools/FullScreenTriangle.cpp @@ -34,7 +34,7 @@ namespace Magnum { namespace MeshTools { std::pair fullScreenTriangle() { Mesh mesh; - mesh.setPrimitive(Mesh::Primitive::Triangles) + mesh.setPrimitive(MeshPrimitive::Triangles) .setVertexCount(3); Buffer* buffer = nullptr; diff --git a/src/Primitives/Capsule.cpp b/src/Primitives/Capsule.cpp index 88cb08983..5f4ee0220 100644 --- a/src/Primitives/Capsule.cpp +++ b/src/Primitives/Capsule.cpp @@ -26,6 +26,7 @@ #include "Math/Vector3.h" #include "Math/Functions.h" +#include "Mesh.h" #include "Primitives/Implementation/Spheroid.h" #include "Primitives/Implementation/WireframeSpheroid.h" #include "Trade/MeshData2D.h" @@ -34,7 +35,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData2D Capsule2D::wireframe(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, Float halfLength) { - CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData2D(Mesh::Primitive::Lines, std::vector{}, std::vector>{}, std::vector>{})); + CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData2D(MeshPrimitive::Lines, std::vector{}, std::vector>{}, std::vector>{})); std::vector positions; positions.reserve(hemisphereRings*4+2+(cylinderRings-1)*2); @@ -85,11 +86,11 @@ Trade::MeshData2D Capsule2D::wireframe(UnsignedInt hemisphereRings, UnsignedInt {UnsignedInt(positions.size())-3, UnsignedInt(positions.size())-1, UnsignedInt(positions.size())-2, UnsignedInt(positions.size())-1}); - return Trade::MeshData2D(Mesh::Primitive::Lines, std::move(indices), {std::move(positions)}, std::vector>{}); + return Trade::MeshData2D(MeshPrimitive::Lines, std::move(indices), {std::move(positions)}, std::vector>{}); } Trade::MeshData3D Capsule3D::solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float halfLength, TextureCoords textureCoords) { - CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); + CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 3, "Capsule must have at least one hemisphere ring, one cylinder ring and three segments", Trade::MeshData3D(MeshPrimitive::Triangles, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); Implementation::Spheroid capsule(segments, textureCoords == TextureCoords::Generate ? Implementation::Spheroid::TextureCoords::Generate : @@ -123,7 +124,7 @@ Trade::MeshData3D Capsule3D::solid(UnsignedInt hemisphereRings, UnsignedInt cyli } Trade::MeshData3D Capsule3D::wireframe(const UnsignedInt hemisphereRings, const UnsignedInt cylinderRings, const UnsignedInt segments, const Float halfLength) { - CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Capsule::wireframe(): improper parameters", Trade::MeshData3D(Mesh::Primitive::Lines, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); + CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Capsule::wireframe(): improper parameters", Trade::MeshData3D(MeshPrimitive::Lines, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); Implementation::WireframeSpheroid capsule(segments/4); diff --git a/src/Primitives/Capsule.h b/src/Primitives/Capsule.h index 64adb1dbd..35508fe9e 100644 --- a/src/Primitives/Capsule.h +++ b/src/Primitives/Capsule.h @@ -48,7 +48,7 @@ class MAGNUM_PRIMITIVES_EXPORT Capsule2D { * larger or equal to 1. * @param halfLength Half the length of cylinder part * - * Indexed @ref Mesh::Primitive "Lines". + * Indexed @ref MeshPrimitive::Lines. */ static Trade::MeshData2D wireframe(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, Float halfLength); }; @@ -77,9 +77,9 @@ class MAGNUM_PRIMITIVES_EXPORT Capsule3D { * @param halfLength Half the length of cylinder part * @param textureCoords Whether to generate texture coordinates. * - * Indexed @ref Mesh::Primitive "Triangles" with normals and optional - * 2D texture coordinates. If texture coordinates are generated, - * vertices of one segment are duplicated for texture wrapping. + * Indexed @ref MeshPrimitive::Triangles with normals and optional 2D + * texture coordinates. If texture coordinates are generated, vertices + * of one segment are duplicated for texture wrapping. */ static Trade::MeshData3D solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float halfLength, TextureCoords textureCoords = TextureCoords::DontGenerate); @@ -93,7 +93,7 @@ class MAGNUM_PRIMITIVES_EXPORT Capsule3D { * equal to 4 and multiple of 4. * @param halfLength Half the length of cylinder part * - * Indexed @ref Mesh::Primitive "Lines". + * Indexed @ref MeshPrimitive::Lines. */ static Trade::MeshData3D wireframe(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float halfLength); }; diff --git a/src/Primitives/Circle.cpp b/src/Primitives/Circle.cpp index 8a1f45c5b..0edbe633c 100644 --- a/src/Primitives/Circle.cpp +++ b/src/Primitives/Circle.cpp @@ -26,13 +26,14 @@ #include "Math/Functions.h" #include "Math/Vector2.h" +#include "Mesh.h" #include "Trade/MeshData2D.h" namespace Magnum { namespace Primitives { Trade::MeshData2D Circle::solid(UnsignedInt segments) { CORRADE_ASSERT(segments >= 3, "Primitives::Circle::solid(): segments must be >= 3", - Trade::MeshData2D(Mesh::Primitive::TriangleFan, std::vector{}, std::vector>{}, std::vector>{})); + Trade::MeshData2D(MeshPrimitive::TriangleFan, std::vector{}, std::vector>{}, std::vector>{})); std::vector positions; positions.reserve(segments+1); @@ -47,12 +48,12 @@ Trade::MeshData2D Circle::solid(UnsignedInt segments) { positions.emplace_back(Math::cos(angle), Math::sin(angle)); } - return Trade::MeshData2D(Mesh::Primitive::TriangleFan, std::vector{}, {std::move(positions)}, std::vector>{}); + return Trade::MeshData2D(MeshPrimitive::TriangleFan, std::vector{}, {std::move(positions)}, std::vector>{}); } Trade::MeshData2D Circle::wireframe(UnsignedInt segments) { CORRADE_ASSERT(segments >= 3, "Primitives::Circle::wireframe(): segments must be >= 3", - Trade::MeshData2D(Mesh::Primitive::LineLoop, std::vector{}, std::vector>{}, std::vector>{})); + Trade::MeshData2D(MeshPrimitive::LineLoop, std::vector{}, std::vector>{}, std::vector>{})); std::vector positions; positions.reserve(segments); @@ -64,7 +65,7 @@ Trade::MeshData2D Circle::wireframe(UnsignedInt segments) { positions.emplace_back(Math::cos(angle), Math::sin(angle)); } - return Trade::MeshData2D(Mesh::Primitive::LineLoop, std::vector{}, {std::move(positions)}, std::vector>{}); + return Trade::MeshData2D(MeshPrimitive::LineLoop, std::vector{}, {std::move(positions)}, std::vector>{}); } }} diff --git a/src/Primitives/Circle.h b/src/Primitives/Circle.h index b97c1e7b2..e0829c982 100644 --- a/src/Primitives/Circle.h +++ b/src/Primitives/Circle.h @@ -45,7 +45,7 @@ class MAGNUM_PRIMITIVES_EXPORT Circle { * @brief Solid circle * @param segments Number of segments. Must be greater or equal to 3. * - * Non-indexed @ref Mesh::Primitive "TriangleFan". + * Non-indexed @ref MeshPrimitive::TriangleFan. */ static Trade::MeshData2D solid(UnsignedInt segments); @@ -53,7 +53,7 @@ class MAGNUM_PRIMITIVES_EXPORT Circle { * @brief Wireframe circle * @param segments Number of segments. Must be greater or equal to 3. * - * Non-indexed @ref Mesh::Primitive "LineLoop". + * Non-indexed @ref MeshPrimitive::LineLoop. */ static Trade::MeshData2D wireframe(UnsignedInt segments); diff --git a/src/Primitives/Crosshair.cpp b/src/Primitives/Crosshair.cpp index 396cf24fa..ba3cfa26a 100644 --- a/src/Primitives/Crosshair.cpp +++ b/src/Primitives/Crosshair.cpp @@ -25,20 +25,21 @@ #include "Crosshair.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Trade/MeshData2D.h" #include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { Trade::MeshData2D Crosshair2D::wireframe() { - return Trade::MeshData2D(Mesh::Primitive::Lines, std::vector{}, {{ + return Trade::MeshData2D(MeshPrimitive::Lines, std::vector{}, {{ {-1.0f, 0.0f}, {1.0f, 0.0f}, { 0.0f, -1.0f}, {0.0f, 1.0f} }}, std::vector>{}); } Trade::MeshData3D Crosshair3D::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::Lines, std::vector{}, {{ + return Trade::MeshData3D(MeshPrimitive::Lines, std::vector{}, {{ {-1.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, { 0.0f, -1.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, { 0.0f, 0.0f, -1.0f}, {0.0f, 0.0f, 1.0f} diff --git a/src/Primitives/Crosshair.h b/src/Primitives/Crosshair.h index b8d1a2783..eae905e2e 100644 --- a/src/Primitives/Crosshair.h +++ b/src/Primitives/Crosshair.h @@ -38,7 +38,7 @@ namespace Magnum { namespace Primitives { @brief 2D crosshair primitive 2x2 wireframe crosshair (two crossed lines), non-indexed -@ref Mesh::Primitive "Lines". +@ref MeshPrimitive::Lines. */ class MAGNUM_PRIMITIVES_EXPORT Crosshair2D { public: @@ -52,7 +52,7 @@ class MAGNUM_PRIMITIVES_EXPORT Crosshair2D { @brief 3D crosshair primitive 2x2x2 wireframe crosshair (three crossed lines), non-indexed -@ref Mesh::Primitive "Lines". +@ref MeshPrimitive::Lines. */ class MAGNUM_PRIMITIVES_EXPORT Crosshair3D { public: diff --git a/src/Primitives/Cube.cpp b/src/Primitives/Cube.cpp index 6809b723b..15f5965e8 100644 --- a/src/Primitives/Cube.cpp +++ b/src/Primitives/Cube.cpp @@ -25,12 +25,13 @@ #include "Cube.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { Trade::MeshData3D Cube::solid() { - return Trade::MeshData3D(Mesh::Primitive::Triangles, { + return Trade::MeshData3D(MeshPrimitive::Triangles, { 0, 1, 2, 0, 2, 3, /* +Z */ 4, 5, 6, 4, 6, 7, /* +X */ 8, 9, 10, 8, 10, 11, /* +Y */ @@ -101,7 +102,7 @@ Trade::MeshData3D Cube::solid() { } Trade::MeshData3D Cube::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::Lines, { + return Trade::MeshData3D(MeshPrimitive::Lines, { 0, 1, 1, 2, 2, 3, 3, 0, /* +Z */ 4, 5, 5, 6, 6, 7, 7, 4, /* -Z */ 1, 5, 2, 6, /* +X */ diff --git a/src/Primitives/Cube.h b/src/Primitives/Cube.h index 52cdee061..653db9e9a 100644 --- a/src/Primitives/Cube.h +++ b/src/Primitives/Cube.h @@ -44,14 +44,14 @@ class MAGNUM_PRIMITIVES_EXPORT Cube { /** * @brief Solid cube * - * Indexed @ref Mesh::Primitive "Triangles" with flat normals. + * Indexed @ref MeshPrimitive::Triangles with flat normals. */ static Trade::MeshData3D solid(); /** * @brief Wireframe cube * - * Indexed @ref Mesh::Primitive "Lines". + * Indexed @ref MeshPrimitive::Lines. */ static Trade::MeshData3D wireframe(); diff --git a/src/Primitives/Cylinder.cpp b/src/Primitives/Cylinder.cpp index 4f02a8d6d..ae85a1777 100644 --- a/src/Primitives/Cylinder.cpp +++ b/src/Primitives/Cylinder.cpp @@ -25,6 +25,7 @@ #include "Cylinder.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Primitives/Implementation/Spheroid.h" #include "Primitives/Implementation/WireframeSpheroid.h" #include "Trade/MeshData3D.h" @@ -32,7 +33,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData3D Cylinder::solid(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength, const Flags flags) { - CORRADE_ASSERT(rings >= 1 && segments >= 3, "Primitives::Cylinder::solid(): cylinder must have at least one ring and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); + CORRADE_ASSERT(rings >= 1 && segments >= 3, "Primitives::Cylinder::solid(): cylinder must have at least one ring and three segments", Trade::MeshData3D(MeshPrimitive::Triangles, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); Implementation::Spheroid cylinder(segments, flags & Flag::GenerateTextureCoords ? Implementation::Spheroid::TextureCoords::Generate : Implementation::Spheroid::TextureCoords::DontGenerate); @@ -63,7 +64,7 @@ Trade::MeshData3D Cylinder::solid(const UnsignedInt rings, const UnsignedInt seg } Trade::MeshData3D Cylinder::wireframe(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength) { - CORRADE_ASSERT(rings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Cylinder::wireframe(): improper parameters", Trade::MeshData3D(Mesh::Primitive::Lines, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); + CORRADE_ASSERT(rings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Cylinder::wireframe(): improper parameters", Trade::MeshData3D(MeshPrimitive::Lines, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); Implementation::WireframeSpheroid cylinder(segments/4); diff --git a/src/Primitives/Cylinder.h b/src/Primitives/Cylinder.h index e00946d63..bc95ad19a 100644 --- a/src/Primitives/Cylinder.h +++ b/src/Primitives/Cylinder.h @@ -65,7 +65,7 @@ class MAGNUM_PRIMITIVES_EXPORT Cylinder { * @param halfLength Half the cylinder length * @param flags Flags * - * Indexed @ref Mesh::Primitive "Triangles" with normals, optional 2D + * Indexed @ref MeshPrimitive::Triangles with normals, optional 2D * texture coordinates and optional capped ends. If texture coordinates * are generated, vertices of one segment are duplicated for texture * wrapping. @@ -80,7 +80,7 @@ class MAGNUM_PRIMITIVES_EXPORT Cylinder { * equal to 4 and multiple of 4. * @param halfLength Half the cylinder length * - * Indexed @ref Mesh::Primitive "Lines". + * Indexed @ref MeshPrimitive::Lines. */ static Trade::MeshData3D wireframe(UnsignedInt rings, UnsignedInt segments, Float halfLength); }; diff --git a/src/Primitives/Icosphere.cpp b/src/Primitives/Icosphere.cpp index 3ec685aa3..0c82d1217 100644 --- a/src/Primitives/Icosphere.cpp +++ b/src/Primitives/Icosphere.cpp @@ -25,9 +25,10 @@ #include "Icosphere.h" #include "Math/Vector3.h" -#include "Trade/MeshData3D.h" +#include "Mesh.h" #include "MeshTools/Subdivide.h" #include "MeshTools/RemoveDuplicates.h" +#include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { @@ -78,7 +79,7 @@ Trade::MeshData3D Icosphere::solid(const UnsignedInt subdivisions) { MeshTools::removeDuplicates(indices, positions); std::vector normals(positions); - return Trade::MeshData3D(Mesh::Primitive::Triangles, std::move(indices), {std::move(positions)}, {std::move(normals)}, std::vector>{}); + return Trade::MeshData3D(MeshPrimitive::Triangles, std::move(indices), {std::move(positions)}, {std::move(normals)}, std::vector>{}); } }} diff --git a/src/Primitives/Icosphere.h b/src/Primitives/Icosphere.h index e0a39360f..7ac15e4a2 100644 --- a/src/Primitives/Icosphere.h +++ b/src/Primitives/Icosphere.h @@ -45,7 +45,7 @@ class MAGNUM_PRIMITIVES_EXPORT Icosphere { * @brief Solid icosphere * @param subdivisions Number of subdivisions * - * Indexed @ref Mesh::Primitive "Triangles" with normals. + * Indexed @ref MeshPrimitive::Triangles with normals. */ static Trade::MeshData3D solid(UnsignedInt subdivisions); }; diff --git a/src/Primitives/Implementation/Spheroid.cpp b/src/Primitives/Implementation/Spheroid.cpp index e8a1a1cb6..05d2e50a7 100644 --- a/src/Primitives/Implementation/Spheroid.cpp +++ b/src/Primitives/Implementation/Spheroid.cpp @@ -26,6 +26,7 @@ #include "Math/Functions.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { namespace Implementation { @@ -161,7 +162,7 @@ void Spheroid::capVertexRing(Float y, Float textureCoordsV, const Vector3& norma } Trade::MeshData3D Spheroid::finalize() { - return Trade::MeshData3D(Mesh::Primitive::Triangles, std::move(indices), {std::move(positions)}, {std::move(normals)}, + return Trade::MeshData3D(MeshPrimitive::Triangles, std::move(indices), {std::move(positions)}, {std::move(normals)}, textureCoords == TextureCoords::Generate ? std::vector>{std::move(textureCoords2D)} : std::vector>()); } diff --git a/src/Primitives/Implementation/WireframeSpheroid.cpp b/src/Primitives/Implementation/WireframeSpheroid.cpp index 475ba759a..434da874b 100644 --- a/src/Primitives/Implementation/WireframeSpheroid.cpp +++ b/src/Primitives/Implementation/WireframeSpheroid.cpp @@ -26,6 +26,7 @@ #include "Math/Functions.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { namespace Implementation { @@ -109,7 +110,7 @@ void WireframeSpheroid::cylinder() { } Trade::MeshData3D WireframeSpheroid::finalize() { - return Trade::MeshData3D(Mesh::Primitive::Lines, std::move(_indices), {std::move(_positions)}, std::vector>{}, std::vector>{}); + return Trade::MeshData3D(MeshPrimitive::Lines, std::move(_indices), {std::move(_positions)}, std::vector>{}, std::vector>{}); } }}} diff --git a/src/Primitives/Line.cpp b/src/Primitives/Line.cpp index 016f6d082..e7255b7cd 100644 --- a/src/Primitives/Line.cpp +++ b/src/Primitives/Line.cpp @@ -25,19 +25,20 @@ #include "Line.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Trade/MeshData2D.h" #include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { Trade::MeshData2D Line2D::wireframe() { - return Trade::MeshData2D(Mesh::Primitive::Lines, std::vector{}, {{ + return Trade::MeshData2D(MeshPrimitive::Lines, std::vector{}, {{ {0.0f, 0.0f}, {1.0f, 0.0f} }}, std::vector>{}); } Trade::MeshData3D Line3D::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::Lines, std::vector{}, {{ + return Trade::MeshData3D(MeshPrimitive::Lines, std::vector{}, {{ {0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, }}, std::vector>{}, std::vector>{}); } diff --git a/src/Primitives/Line.h b/src/Primitives/Line.h index 59a0d7a6c..868e963bd 100644 --- a/src/Primitives/Line.h +++ b/src/Primitives/Line.h @@ -38,7 +38,7 @@ namespace Magnum { namespace Primitives { @brief 2D line primitive Unit-size line in direction of positive X axis. Non-indexed -@ref Mesh::Primitive "Lines". +@ref MeshPrimitive::Lines. */ class MAGNUM_PRIMITIVES_EXPORT Line2D { public: @@ -52,7 +52,7 @@ class MAGNUM_PRIMITIVES_EXPORT Line2D { @brief 3D line primitive Unit-size line in direction of positive X axis. Non-indexed -@ref Mesh::Primitive "Lines". +@ref MeshPrimitive::Lines. */ class MAGNUM_PRIMITIVES_EXPORT Line3D { public: diff --git a/src/Primitives/Plane.cpp b/src/Primitives/Plane.cpp index a454ef645..3451168f0 100644 --- a/src/Primitives/Plane.cpp +++ b/src/Primitives/Plane.cpp @@ -25,6 +25,7 @@ #include "Plane.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Trade/MeshData3D.h" namespace Magnum { namespace Primitives { @@ -38,7 +39,7 @@ Trade::MeshData3D Plane::solid(const TextureCoords textureCoords) { {0.0f, 1.0f} }); - return Trade::MeshData3D(Mesh::Primitive::TriangleStrip, std::vector{}, {{ + return Trade::MeshData3D(MeshPrimitive::TriangleStrip, std::vector{}, {{ {1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, {-1.0f, -1.0f, 0.0f}, @@ -52,7 +53,7 @@ Trade::MeshData3D Plane::solid(const TextureCoords textureCoords) { } Trade::MeshData3D Plane::wireframe() { - return Trade::MeshData3D(Mesh::Primitive::LineLoop, std::vector{}, {{ + return Trade::MeshData3D(MeshPrimitive::LineLoop, std::vector{}, {{ {-1.0f, -1.0f, 0.0f}, {1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f}, diff --git a/src/Primitives/Plane.h b/src/Primitives/Plane.h index b25273124..efdc08d02 100644 --- a/src/Primitives/Plane.h +++ b/src/Primitives/Plane.h @@ -53,7 +53,7 @@ class MAGNUM_PRIMITIVES_EXPORT Plane { /** * @brief Solid plane * - * Non-indexed @ref Mesh::Primitive "TriangleStrip" with normals in + * Non-indexed @ref MeshPrimitive::TriangleStrip with normals in * positive Z direction. */ static Trade::MeshData3D solid(TextureCoords textureCoords = TextureCoords::DontGenerate); @@ -61,7 +61,7 @@ class MAGNUM_PRIMITIVES_EXPORT Plane { /** * @brief Wireframe plane * - * Non-indexed @ref Mesh::Primitive "LineLoop". + * Non-indexed @ref MeshPrimitive::LineLoop. */ static Trade::MeshData3D wireframe(); diff --git a/src/Primitives/Square.cpp b/src/Primitives/Square.cpp index 93e72b198..c83802563 100644 --- a/src/Primitives/Square.cpp +++ b/src/Primitives/Square.cpp @@ -25,6 +25,7 @@ #include "Square.h" #include "Math/Vector2.h" +#include "Mesh.h" #include "Trade/MeshData2D.h" namespace Magnum { namespace Primitives { @@ -38,7 +39,7 @@ Trade::MeshData2D Square::solid(const TextureCoords textureCoords) { {0.0f, 1.0f} }); - return Trade::MeshData2D(Mesh::Primitive::TriangleStrip, std::vector{}, {{ + return Trade::MeshData2D(MeshPrimitive::TriangleStrip, std::vector{}, {{ {1.0f, -1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, @@ -47,7 +48,7 @@ Trade::MeshData2D Square::solid(const TextureCoords textureCoords) { } Trade::MeshData2D Square::wireframe() { - return Trade::MeshData2D(Mesh::Primitive::LineLoop, std::vector{}, {{ + return Trade::MeshData2D(MeshPrimitive::LineLoop, std::vector{}, {{ {-1.0f, -1.0f}, {1.0f, -1.0f}, {1.0f, 1.0f}, diff --git a/src/Primitives/Square.h b/src/Primitives/Square.h index 77a7afedb..85993082a 100644 --- a/src/Primitives/Square.h +++ b/src/Primitives/Square.h @@ -53,14 +53,14 @@ class MAGNUM_PRIMITIVES_EXPORT Square { /** * @brief Solid square * - * Non-indexed @ref Mesh::Primitive "TriangleStrip". + * Non-indexed @ref MeshPrimitive::TriangleStrip. */ static Trade::MeshData2D solid(TextureCoords textureCoords = TextureCoords::DontGenerate); /** * @brief Wireframe square * - * Non-indexed @ref Mesh::Primitive "LineLoop." + * Non-indexed @ref MeshPrimitive::LineLoop. */ static Trade::MeshData2D wireframe(); diff --git a/src/Primitives/UVSphere.cpp b/src/Primitives/UVSphere.cpp index dd0c23972..b6ace4dc8 100644 --- a/src/Primitives/UVSphere.cpp +++ b/src/Primitives/UVSphere.cpp @@ -25,6 +25,7 @@ #include "UVSphere.h" #include "Math/Vector3.h" +#include "Mesh.h" #include "Primitives/Implementation/Spheroid.h" #include "Primitives/Implementation/WireframeSpheroid.h" #include "Trade/MeshData3D.h" @@ -32,7 +33,7 @@ namespace Magnum { namespace Primitives { Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords) { - CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); + CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(MeshPrimitive::Triangles, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); Implementation::Spheroid sphere(segments, textureCoords == TextureCoords::Generate ? Implementation::Spheroid::TextureCoords::Generate : @@ -59,7 +60,7 @@ Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, Textu } Trade::MeshData3D UVSphere::wireframe(const UnsignedInt rings, const UnsignedInt segments) { - CORRADE_ASSERT(rings >= 2 && rings%2 == 0 && segments >= 4 && segments%2 == 0, "Primitives::UVSphere::wireframe(): improper parameters", Trade::MeshData3D(Mesh::Primitive::Lines, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); + CORRADE_ASSERT(rings >= 2 && rings%2 == 0 && segments >= 4 && segments%2 == 0, "Primitives::UVSphere::wireframe(): improper parameters", Trade::MeshData3D(MeshPrimitive::Lines, std::vector{}, std::vector>{}, std::vector>{}, std::vector>{})); Implementation::WireframeSpheroid sphere(segments/4); diff --git a/src/Primitives/UVSphere.h b/src/Primitives/UVSphere.h index df0fcdda5..fee053691 100644 --- a/src/Primitives/UVSphere.h +++ b/src/Primitives/UVSphere.h @@ -54,9 +54,9 @@ class MAGNUM_PRIMITIVES_EXPORT UVSphere { * equal to 3. * @param textureCoords Whether to generate texture coordinates. * - * Indexed @ref Mesh::Primitive "Triangles" with normals and optional - * 2D texture coordinates. If texture coordinates are generated, - * vertices of one segment are duplicated for texture wrapping. + * Indexed @ref MeshPrimitive::Triangles with normals and optional 2D + * texture coordinates. If texture coordinates are generated, vertices + * of one segment are duplicated for texture wrapping. */ static Trade::MeshData3D solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords = TextureCoords::DontGenerate); @@ -67,7 +67,7 @@ class MAGNUM_PRIMITIVES_EXPORT UVSphere { * @param segments Number of (line) segments. Must be larger or * equal to 4 and multiple of 4. * - * Indexed @ref Mesh::Primitive "Lines". + * Indexed @ref MeshPrimitive::Lines. */ static Trade::MeshData3D wireframe(UnsignedInt rings, UnsignedInt segments); }; diff --git a/src/Test/MeshTest.cpp b/src/Test/MeshTest.cpp index 0f8ed4271..afe8d57db 100644 --- a/src/Test/MeshTest.cpp +++ b/src/Test/MeshTest.cpp @@ -49,8 +49,8 @@ MeshTest::MeshTest() { void MeshTest::debugPrimitive() { std::ostringstream o; - Debug(&o) << Mesh::Primitive::TriangleFan; - CORRADE_COMPARE(o.str(), "Mesh::Primitive::TriangleFan\n"); + Debug(&o) << MeshPrimitive::TriangleFan; + CORRADE_COMPARE(o.str(), "MeshPrimitive::TriangleFan\n"); } void MeshTest::debugIndexType() { @@ -62,9 +62,9 @@ void MeshTest::debugIndexType() { void MeshTest::configurationPrimitive() { Utility::Configuration c; - c.setValue("primitive", Mesh::Primitive::LineStrip); + c.setValue("primitive", MeshPrimitive::LineStrip); CORRADE_COMPARE(c.value("primitive"), "LineStrip"); - CORRADE_COMPARE(c.value("primitive"), Mesh::Primitive::LineStrip); + CORRADE_COMPARE(c.value("primitive"), MeshPrimitive::LineStrip); } void MeshTest::configurationIndexType() { diff --git a/src/Text/Renderer.cpp b/src/Text/Renderer.cpp index 053a67e4a..605ed274e 100644 --- a/src/Text/Renderer.cpp +++ b/src/Text/Renderer.cpp @@ -211,7 +211,7 @@ std::tuple renderInternal(AbstractFont& font, const GlyphCache& c /* Configure mesh except for vertex buffer (depends on dimension count, done in subclass) */ Mesh mesh; - mesh.setPrimitive(Mesh::Primitive::Triangles) + mesh.setPrimitive(MeshPrimitive::Triangles) .setIndexCount(indexCount) .setIndexBuffer(indexBuffer, 0, indexType, 0, vertexCount); @@ -317,7 +317,7 @@ AbstractRenderer::AbstractRenderer(AbstractFont& font, const GlyphCache& cache, #endif /* Vertex buffer configuration depends on dimension count, done in subclass */ - _mesh.setPrimitive(Mesh::Primitive::Triangles); + _mesh.setPrimitive(MeshPrimitive::Triangles); } AbstractRenderer::~AbstractRenderer() {} diff --git a/src/TextureTools/DistanceField.cpp b/src/TextureTools/DistanceField.cpp index b8d8aa2ba..52e75465f 100644 --- a/src/TextureTools/DistanceField.cpp +++ b/src/TextureTools/DistanceField.cpp @@ -175,7 +175,7 @@ void distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangl } Mesh mesh; - mesh.setPrimitive(Mesh::Primitive::Triangles) + mesh.setPrimitive(MeshPrimitive::Triangles) .setVertexCount(3); /* Older GLSL doesn't have gl_VertexID, vertices must be supplied explicitly */ diff --git a/src/Trade/MeshData2D.cpp b/src/Trade/MeshData2D.cpp index 4e06a1b00..217de6e10 100644 --- a/src/Trade/MeshData2D.cpp +++ b/src/Trade/MeshData2D.cpp @@ -28,7 +28,7 @@ namespace Magnum { namespace Trade { -MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> textureCoords2D): _primitive(primitive), _indices(std::move(indices)), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) { +MeshData2D::MeshData2D(MeshPrimitive primitive, std::vector indices, std::vector> positions, std::vector> textureCoords2D): _primitive(primitive), _indices(std::move(indices)), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) { CORRADE_ASSERT(!_positions.empty(), "Trade::MeshData2D: no position array specified", ); } diff --git a/src/Trade/MeshData2D.h b/src/Trade/MeshData2D.h index bed9b2d3e..a064977cb 100644 --- a/src/Trade/MeshData2D.h +++ b/src/Trade/MeshData2D.h @@ -28,9 +28,11 @@ * @brief Class Magnum::Trade::MeshData2D */ -#include +#include -#include "Mesh.h" +#include "Magnum.h" + +#include "magnumVisibility.h" namespace Magnum { namespace Trade { @@ -53,7 +55,7 @@ class MAGNUM_EXPORT MeshData2D { * @param textureCoords2D Two-dimensional texture coordinate arrays, * if present */ - explicit MeshData2D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> textureCoords2D); + explicit MeshData2D(MeshPrimitive primitive, std::vector indices, std::vector> positions, std::vector> textureCoords2D); /** @brief Copying is not allowed */ MeshData2D(const MeshData2D&) = delete; @@ -70,7 +72,7 @@ class MAGNUM_EXPORT MeshData2D { MeshData2D& operator=(MeshData2D&&); /** @brief Primitive */ - Mesh::Primitive primitive() const { return _primitive; } + MeshPrimitive primitive() const { return _primitive; } /** @brief Whether the mesh is indexed */ bool isIndexed() const { return !_indices.empty(); } @@ -115,7 +117,7 @@ class MAGNUM_EXPORT MeshData2D { const std::vector& textureCoords2D(UnsignedInt id) const; /**< @overload */ private: - Mesh::Primitive _primitive; + MeshPrimitive _primitive; std::vector _indices; std::vector> _positions; std::vector> _textureCoords2D; diff --git a/src/Trade/MeshData3D.cpp b/src/Trade/MeshData3D.cpp index a483521ec..fa103dc8d 100644 --- a/src/Trade/MeshData3D.cpp +++ b/src/Trade/MeshData3D.cpp @@ -28,7 +28,7 @@ namespace Magnum { namespace Trade { -MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> normals, std::vector> textureCoords2D): _primitive(primitive), _indices(std::move(indices)), _positions(std::move(positions)), _normals(std::move(normals)), _textureCoords2D(std::move(textureCoords2D)) { +MeshData3D::MeshData3D(MeshPrimitive primitive, std::vector indices, std::vector> positions, std::vector> normals, std::vector> textureCoords2D): _primitive(primitive), _indices(std::move(indices)), _positions(std::move(positions)), _normals(std::move(normals)), _textureCoords2D(std::move(textureCoords2D)) { CORRADE_ASSERT(!_positions.empty(), "Trade::MeshData3D: no position array specified", ); } diff --git a/src/Trade/MeshData3D.h b/src/Trade/MeshData3D.h index d157da1cc..d1440affb 100644 --- a/src/Trade/MeshData3D.h +++ b/src/Trade/MeshData3D.h @@ -28,9 +28,11 @@ * @brief Class Magnum::Trade::MeshData3D */ -#include +#include -#include "Mesh.h" +#include "Magnum.h" + +#include "magnumVisibility.h" namespace Magnum { namespace Trade { @@ -54,7 +56,7 @@ class MAGNUM_EXPORT MeshData3D { * @param textureCoords2D Two-dimensional texture coordinate arrays, * if present */ - explicit MeshData3D(Mesh::Primitive primitive, std::vector indices, std::vector> positions, std::vector> normals, std::vector> textureCoords2D); + explicit MeshData3D(MeshPrimitive primitive, std::vector indices, std::vector> positions, std::vector> normals, std::vector> textureCoords2D); /** @brief Copying is not allowed */ MeshData3D(const MeshData3D&) = delete; @@ -71,7 +73,7 @@ class MAGNUM_EXPORT MeshData3D { MeshData3D& operator=(MeshData3D&&); /** @brief Primitive */ - Mesh::Primitive primitive() const { return _primitive; } + MeshPrimitive primitive() const { return _primitive; } /** @brief Whether the mesh is indexed */ bool isIndexed() const { return !_indices.empty(); } @@ -131,7 +133,7 @@ class MAGNUM_EXPORT MeshData3D { const std::vector& textureCoords2D(UnsignedInt id) const; /**< @overload */ private: - Mesh::Primitive _primitive; + MeshPrimitive _primitive; std::vector _indices; std::vector> _positions; std::vector> _normals; From 1d789ef55e7e430036c5e7f219c375b7635f1537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 11 Dec 2013 13:09:52 +0100 Subject: [PATCH 30/32] MeshTools: added TODOs. --- src/MeshTools/CombineIndexedArrays.h | 2 ++ src/MeshTools/Interleave.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/MeshTools/CombineIndexedArrays.h b/src/MeshTools/CombineIndexedArrays.h index 59fa27c87..ab56624ec 100644 --- a/src/MeshTools/CombineIndexedArrays.h +++ b/src/MeshTools/CombineIndexedArrays.h @@ -128,6 +128,8 @@ std::vector indices = MeshTools::combineIndexedArrays( attributes indexed with `indices`. @attention The function expects that all arrays have the same size. +@todo Use `std::pair` (to avoid `std::make_tuple`), make this usable also at + runtime */ /* Implementation note: It's done using tuples because it is more clear which parameter is index array and which is attribute array, mainly when both are diff --git a/src/MeshTools/Interleave.h b/src/MeshTools/Interleave.h index e9b33feed..cb6644162 100644 --- a/src/MeshTools/Interleave.h +++ b/src/MeshTools/Interleave.h @@ -201,6 +201,7 @@ mesh.setVertexCount(attribute.size()); @endcode @see @ref MeshTools::compressIndices() +@todo rework so Mesh & Buffer doesn't need to be included in header */ template inline void interleave(Mesh& mesh, Buffer& buffer, BufferUsage usage, const T&... attributes) { return Implementation::Interleave()(mesh, buffer, usage, attributes...); From 4eaedf94eb8942d055cdd7b89a51070d9c2e0010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 12 Dec 2013 17:58:50 +0100 Subject: [PATCH 31/32] Platform: fixed SDL link in documentation. Thx @biosek. --- src/Platform/Sdl2Application.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Platform/Sdl2Application.h b/src/Platform/Sdl2Application.h index 073ea799b..2ae5230b6 100644 --- a/src/Platform/Sdl2Application.h +++ b/src/Platform/Sdl2Application.h @@ -51,8 +51,8 @@ namespace Platform { /** @nosubgrouping @brief SDL2 application -Application using [Simple DirectMedia Layer](www.libsdl.org/) toolkit. Supports -keyboard and mouse handling. +Application using [Simple DirectMedia Layer](http://www.libsdl.org/) toolkit. +Supports keyboard and mouse handling. This application library is available on desktop OpenGL (Linux, Windows, OS X) and in @ref CORRADE_TARGET_EMSCRIPTEN "Emscripten". It depends on **SDL2** From a9fe635867a8217de113e57c3efe85bd8c98e932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 12 Dec 2013 18:28:23 +0100 Subject: [PATCH 32/32] Updated and improved ColorFormat, ColorType and TextureFormat enum docs. Finishing promises made in #31. --- src/ColorFormat.h | 85 ++++++++++++++++++++++++++++----------------- src/TextureFormat.h | 58 ++++++++++++++++++------------- 2 files changed, 86 insertions(+), 57 deletions(-) diff --git a/src/ColorFormat.h b/src/ColorFormat.h index 54c014d7f..dadccf2cd 100644 --- a/src/ColorFormat.h +++ b/src/ColorFormat.h @@ -25,7 +25,7 @@ */ /** @file - * @brief Enum Magnum::ColorFormat, Magnum::ColorType + * @brief Enum @ref Magnum::ColorFormat, @ref Magnum::ColorType */ #include "Magnum.h" @@ -38,9 +38,18 @@ namespace Magnum { @brief Format of image data Note that some formats can be used only for framebuffer reading (using -AbstractFramebuffer::read()) and some only for texture data (using Texture::setImage() -and others). -@see Image, ImageReference, BufferImage, Trade::ImageData +@ref AbstractFramebuffer::read()) and some only for texture data (using +@ref Texture::setImage() and others), the limitations are mentioned in +documentation of each particular value. + +In most cases you may want to use @ref ColorFormat::Red (for grayscale images), +@ref ColorFormat::RGB or @ref ColorFormat::RGBA along with +@ref ColorType::UnsignedByte, the matching texture format is then +@ref TextureFormat::R8, @ref TextureFormat::RGB8 or @ref TextureFormat::RGBA8. +See documentation of these values for possible limitations when using OpenGL ES +2.0 or WebGL. + +@see @ref Image, @ref ImageReference, @ref BufferImage, @ref Trade::ImageData */ enum class ColorFormat: GLenum { /** @@ -57,14 +66,14 @@ enum class ColorFormat: GLenum { #ifndef MAGNUM_TARGET_GLES /** * Floating-point green channel. - * @requires_gl Only @ref Magnum::ColorFormat "ColorFormat::Red" is + * @requires_gl Only @ref Magnum::ColorFormat::Red "ColorFormat::Red" is * available in OpenGL ES. */ Green = GL_GREEN, /** * Floating-point blue channel. - * @requires_gl Only @ref Magnum::ColorFormat "ColorFormat::Red" is + * @requires_gl Only @ref Magnum::ColorFormat::Red "ColorFormat::Red" is * available in OpenGL ES. */ Blue = GL_BLUE, @@ -75,9 +84,9 @@ enum class ColorFormat: GLenum { * Floating-point luminance channel. The value is used for all RGB * channels. * @deprecated_gl Included for compatibility reasons only, use - * @ref Magnum::ColorFormat "ColorFormat::Red" instead. + * @ref Magnum::ColorFormat::Red "ColorFormat::Red" instead. * @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use - * @ref Magnum::ColorFormat "ColorFormat::Red" instead. + * @ref Magnum::ColorFormat::Red "ColorFormat::Red" instead. */ Luminance = GL_LUMINANCE, #endif @@ -99,9 +108,9 @@ enum class ColorFormat: GLenum { * Floating-point luminance and alpha channel. First value is used for all * RGB channels, second value is used for alpha channel. * @deprecated_gl Included for compatibility reasons only, use - * @ref Magnum::ColorFormat "ColorFormat::RG" instead. + * @ref Magnum::ColorFormat::RG "ColorFormat::RG" instead. * @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use - * @ref Magnum::ColorFormat "ColorFormat::RG" instead. + * @ref Magnum::ColorFormat::RG "ColorFormat::RG" instead. */ LuminanceAlpha = GL_LUMINANCE_ALPHA, #endif @@ -148,7 +157,7 @@ enum class ColorFormat: GLenum { /** * Integer green channel. * @requires_gl30 %Extension @extension{EXT,texture_integer} - * @requires_gl Only @ref Magnum::ColorFormat "ColorFormat::RedInteger" + * @requires_gl Only @ref Magnum::ColorFormat::RedInteger "ColorFormat::RedInteger" * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. */ @@ -157,8 +166,8 @@ enum class ColorFormat: GLenum { /** * Integer blue channel. * @requires_gl30 %Extension @extension{EXT,texture_integer} - * @requires_gl Only @ref Magnum::ColorFormat "ColorFormat::RedInteger" is - * available in OpenGL ES 3.0, only floating-point image data are + * @requires_gl Only @ref Magnum::ColorFormat::RedInteger "ColorFormat::RedInteger" + * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. */ BlueInteger = GL_BLUE_INTEGER, @@ -194,8 +203,8 @@ enum class ColorFormat: GLenum { /** * Integer BGR. * @requires_gl30 %Extension @extension{EXT,texture_integer} - * @requires_gl Only @ref Magnum::ColorFormat "ColorFormat::RGBInteger" is - * available in OpenGL ES 3.0, only floating-point image data are + * @requires_gl Only @ref Magnum::ColorFormat::RGBInteger "ColorFormat::RGBInteger" + * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. */ BGRInteger = GL_BGR_INTEGER, @@ -203,8 +212,8 @@ enum class ColorFormat: GLenum { /** * Integer BGRA. * @requires_gl30 %Extension @extension{EXT,texture_integer} - * @requires_gl Only @ref Magnum::ColorFormat "ColorFormat::RGBAInteger" is - * available in OpenGL ES 3.0, only floating-point image data are + * @requires_gl Only @ref Magnum::ColorFormat::RGBAInteger "ColorFormat::RGBAInteger" + * is available in OpenGL ES 3.0, only floating-point image data are * available in OpenGL ES 2.0. */ BGRAInteger = GL_BGRA_INTEGER, @@ -251,9 +260,18 @@ enum class ColorFormat: GLenum { @brief Type of image data Note that some formats can be used only for framebuffer reading (using -AbstractFramebuffer::read()) and some only for texture data (using Texture::setImage() -and others). -@see Image, ImageReference, BufferImage, Trade::ImageData +@ref AbstractFramebuffer::read()) and some only for texture data (using +@ref Texture::setImage() and others), the limitations are mentioned in +documentation of each particular value. + +In most cases you may want to use @ref ColorType::UnsignedByte along with +@ref ColorFormat::Red (for grayscale images), @ref ColorFormat::RGB or +@ref ColorFormat::RGBA, the matching texture format is then +@ref TextureFormat::R8, @ref TextureFormat::RGB8 or @ref TextureFormat::RGBA8. +See documentation of these values for possible limitations when using OpenGL ES +2.0 or WebGL. + +@see @ref Image, @ref ImageReference, @ref BufferImage, @ref Trade::ImageData */ enum class ColorType: GLenum { /** Each component unsigned byte. */ @@ -263,8 +281,9 @@ enum class ColorType: GLenum { /** * Each component signed byte. * @requires_gl Can't be used for framebuffer reading in OpenGL ES. - * @requires_gles30 For texture data only, only @ref Magnum::ColorType "ColorType::UnsignedByte" - * is available in OpenGL ES 2.0. + * @requires_gles30 For texture data only, only + * @ref Magnum::ColorType::UnsignedByte "ColorType::UnsignedByte" is + * available in OpenGL ES 2.0. */ Byte = GL_BYTE, #endif @@ -281,8 +300,9 @@ enum class ColorType: GLenum { /** * Each component signed short. * @requires_gl Can't be used for framebuffer reading in OpenGL ES. - * @requires_gles30 For texture data only, only @ref Magnum::ColorType "ColorType::UnsignedShort" - * is available in OpenGL ES 2.0. + * @requires_gles30 For texture data only, only + * @ref Magnum::ColorType::UnsignedShort "ColorType::UnsignedShort" is + * available in OpenGL ES 2.0. */ Short = GL_SHORT, #endif @@ -298,7 +318,7 @@ enum class ColorType: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * Each component signed int. - * @requires_gles30 Only @ref Magnum::ColorType "ColorType::UnsignedInt" + * @requires_gles30 Only @ref Magnum::ColorType::UnsignedInt "ColorType::UnsignedInt" * is available in OpenGL ES 2.0. */ Int = GL_INT, @@ -345,7 +365,7 @@ enum class ColorType: GLenum { #ifndef MAGNUM_TARGET_GLES /** * BGR, unsigned short, red and blue 5bit, green 6bit. - * @requires_gl Only @ref Magnum::ColorType "ColorType::RGB565" is + * @requires_gl Only @ref Magnum::ColorType::RGB565 "ColorType::RGB565" is * available in OpenGL ES. */ UnsignedShort565Rev = GL_UNSIGNED_SHORT_5_6_5_REV, @@ -388,22 +408,22 @@ enum class ColorType: GLenum { #ifndef MAGNUM_TARGET_GLES /** * RGBA, unsigned int, each component 8bit. - * @requires_gl Use @ref Magnum::ColorType "ColorType::UnsignedByte" in - * OpenGL ES instead. + * @requires_gl Use @ref Magnum::ColorType::UnsignedByte "ColorType::UnsignedByte" + * in OpenGL ES instead. */ UnsignedInt8888 = GL_UNSIGNED_INT_8_8_8_8, /** * ABGR, unsigned int, each component 8bit. * @requires_gl Only RGBA component ordering is available in OpenGL ES, see - * @ref Magnum::ColorType "ColorType::UnsignedInt8888" for more - * information. + * @ref Magnum::ColorType::UnsignedInt8888 "ColorType::UnsignedInt8888" + * for more information. */ UnsignedInt8888Rev = GL_UNSIGNED_INT_8_8_8_8_REV, /** * RGBA, unsigned int, each RGB component 10bit, alpha component 2bit. - * @requires_gl Only @ref Magnum::ColorType "ColorType::UnsignedInt2101010Rev" + * @requires_gl Only @ref Magnum::ColorType::UnsignedInt2101010Rev "ColorType::UnsignedInt2101010Rev" * is available in OpenGL ES. */ UnsignedInt1010102 = GL_UNSIGNED_INT_10_10_10_2, @@ -455,7 +475,8 @@ enum class ColorType: GLenum { * Float + unsigned int, depth component 32bit float, 24bit gap, stencil * index 8bit. * @requires_gl30 %Extension @extension{ARB,depth_buffer_float} - * @requires_gles30 For texture data only, only @ref Magnum::ColorType "ColorType::UnsignedInt248" + * @requires_gles30 For texture data only, only + * @ref Magnum::ColorType::UnsignedInt248 "ColorType::UnsignedInt248" * is available in OpenGL ES 2.0. */ Float32UnsignedInt248Rev = GL_FLOAT_32_UNSIGNED_INT_24_8_REV diff --git a/src/TextureFormat.h b/src/TextureFormat.h index 57e16f9b8..e9ebe6b81 100644 --- a/src/TextureFormat.h +++ b/src/TextureFormat.h @@ -25,7 +25,7 @@ */ /** @file - * @brief Enum Magnum::TextureFormat + * @brief Enum @ref Magnum::TextureFormat */ #include "OpenGL.h" @@ -35,13 +35,20 @@ namespace Magnum { /** @brief Internal texture format -@see Texture, CubeMapTexture, CubeMapTextureArray +In most cases you may want to use @ref TextureFormat::R8 (for grayscale +textures), @ref TextureFormat::RGB8 or @ref TextureFormat::RGBA8. The matching +color format is then @ref ColorFormat::Red, @ref ColorFormat::RGB or +@ref ColorFormat::RGBA along with @ref ColorType::UnsignedByte. See +documentation of these values for possible limitations when using OpenGL ES 2.0 +or WebGL. + +@see @ref Texture, @ref CubeMapTexture, @ref CubeMapTextureArray */ enum class TextureFormat: GLenum { /** * Red component, normalized unsigned, size implementation-dependent. * @deprecated_gl Prefer to use the exactly specified version of this - * format, e.g. @ref Magnum::TextureFormat "TextureFormat::R8". + * format, e.g. @ref Magnum::TextureFormat::R8 "TextureFormat::R8". * @requires_gl30 %Extension @extension{ARB,texture_rg} * @requires_gles30 %Extension @es_extension{EXT,texture_rg} */ @@ -55,8 +62,8 @@ enum class TextureFormat: GLenum { /** * Red component, normalized unsigned byte. * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 Use @ref Magnum::TextureFormat "TextureFormat::Red" in - * OpenGL ES 2.0 instead. + * @requires_gles30 Use @ref Magnum::TextureFormat::Red "TextureFormat::Red" + * in OpenGL ES 2.0 instead. */ R8 = GL_R8, #endif @@ -65,7 +72,7 @@ enum class TextureFormat: GLenum { * Red and green component, normalized unsigned, size * implementation-dependent. * @deprecated_gl Prefer to use the exactly specified version of this - * format, e.g. @ref Magnum::TextureFormat "TextureFormat::RG8". + * format, e.g. @ref Magnum::TextureFormat::RG8 "TextureFormat::RG8". * @requires_gl30 %Extension @extension{ARB,texture_rg} * @requires_gles30 %Extension @es_extension{EXT,texture_rg} */ @@ -79,8 +86,8 @@ enum class TextureFormat: GLenum { /** * Red and green component, each normalized unsigned byte. * @requires_gl30 %Extension @extension{ARB,texture_rg} - * @requires_gles30 Use @ref Magnum::TextureFormat "TextureFormat::RG" in - * OpenGL ES 2.0 instead. + * @requires_gles30 Use @ref Magnum::TextureFormat::RG "TextureFormat::RG" + * in OpenGL ES 2.0 instead. */ RG8 = GL_RG8, #endif @@ -88,7 +95,7 @@ enum class TextureFormat: GLenum { /** * RGB, normalized unsigned, size implementation-dependent. * @deprecated_gl Prefer to use the exactly specified version of this - * format, e.g. @ref Magnum::TextureFormat "TextureFormat::RGB8". + * format, e.g. @ref Magnum::TextureFormat::RGB8 "TextureFormat::RGB8". */ RGB = GL_RGB, @@ -105,7 +112,7 @@ enum class TextureFormat: GLenum { /** * RGBA, normalized unsigned, size implementation-dependent. * @deprecated_gl Prefer to use the exactly specified version of this - * format, e.g. @ref Magnum::TextureFormat "TextureFormat::RGBA8". + * format, e.g. @ref Magnum::TextureFormat::RGBA8 "TextureFormat::RGBA8". */ RGBA = GL_RGBA, @@ -476,9 +483,9 @@ enum class TextureFormat: GLenum { * Luminance, normalized unsigned, single value used for all RGB channels. * Size implementation-dependent. * @deprecated_gl Included for compatibility reasons only, use - * @ref Magnum::TextureFormat "TextureFormat::R8" instead. + * @ref Magnum::TextureFormat::R8 "TextureFormat::R8" instead. * @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use - * @ref Magnum::TextureFormat "TextureFormat::R8" instead. + * @ref Magnum::TextureFormat::R8 "TextureFormat::R8" instead. */ Luminance = GL_LUMINANCE, @@ -487,9 +494,9 @@ enum class TextureFormat: GLenum { * RGB channels, second value is used for alpha channel. Size * implementation-dependent. * @deprecated_gl Included for compatibility reasons only, use - * @ref Magnum::TextureFormat "TextureFormat::RG8" instead. + * @ref Magnum::TextureFormat::RG8 "TextureFormat::RG8" instead. * @requires_gles20 Not available in ES 3.0 or desktop OpenGL. Use - * @ref Magnum::TextureFormat "TextureFormat::RG8" instead. + * @ref Magnum::TextureFormat::RG8 "TextureFormat::RG8" instead. */ LuminanceAlpha = GL_LUMINANCE_ALPHA, #endif @@ -509,8 +516,9 @@ enum class TextureFormat: GLenum { /** * RGB, each component normalized unsigned 5bit. - * @requires_gl Use @ref Magnum::TextureFormat "TextureFormat::RGB5A1" or - * @ref Magnum::TextureFormat "TextureFormat::RGB565" in OpenGL ES. + * @requires_gl Use @ref Magnum::TextureFormat::RGB5A1 "TextureFormat::RGB5A1" + * or @ref Magnum::TextureFormat::RGB565 "TextureFormat::RGB565" in + * OpenGL ES. */ RGB5 = GL_RGB5, #endif @@ -552,8 +560,8 @@ enum class TextureFormat: GLenum { /** * RGB, unsigned with exponent, each RGB component 9bit, exponent 5bit. * @requires_gl30 %Extension @extension{EXT,texture_shared_exponent} - * @requires_gles30 Use @ref Magnum::TextureFormat "TextureFormat::RGB" in - * OpenGL ES 2.0 instead. + * @requires_gles30 Use @ref Magnum::TextureFormat::RGB "TextureFormat::RGB" + * in OpenGL ES 2.0 instead. */ RGB9E5 = GL_RGB9_E5, #endif @@ -562,7 +570,7 @@ enum class TextureFormat: GLenum { * sRGB, normalized unsigned, size implementation-dependent. * @todo is this allowed in core? * @deprecated_gl Prefer to use the exactly specified version of this - * format, i.e. @ref Magnum::TextureFormat "TextureFormat::SRGB8". + * format, i.e. @ref Magnum::TextureFormat::SRGB8 "TextureFormat::SRGB8". * @requires_es_extension %Extension @es_extension{EXT,sRGB} */ #ifndef MAGNUM_TARGET_GLES @@ -574,8 +582,8 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * sRGB, each component normalized unsigned byte. - * @requires_gles30 Use @ref Magnum::TextureFormat "TextureFormat::SRGB" in - * OpenGL ES 2.0 instead. + * @requires_gles30 Use @ref Magnum::TextureFormat::SRGB "TextureFormat::SRGB" + * in OpenGL ES 2.0 instead. */ SRGB8 = GL_SRGB8, #endif @@ -633,7 +641,7 @@ enum class TextureFormat: GLenum { * sRGBA, normalized unsigned, size implementation-dependent. * @todo is this allowed in core? * @deprecated_gl Prefer to use the exactly specified version of this - * format, i.e. @ref Magnum::TextureFormat "TextureFormat::SRGB8Alpha8". + * format, i.e. @ref Magnum::TextureFormat::SRGB8Alpha8 "TextureFormat::SRGB8Alpha8". * @requires_es_extension %Extension @es_extension{EXT,sRGB} */ #ifndef MAGNUM_TARGET_GLES @@ -645,7 +653,7 @@ enum class TextureFormat: GLenum { #ifndef MAGNUM_TARGET_GLES2 /** * sRGBA, each component normalized unsigned byte. - * @requires_gles30 Use @ref Magnum::TextureFormat "TextureFormat::SRGBAlpha" + * @requires_gles30 Use @ref Magnum::TextureFormat::SRGBAlpha "TextureFormat::SRGBAlpha" * in OpenGL ES 2.0 instead. */ SRGB8Alpha8 = GL_SRGB8_ALPHA8, @@ -742,7 +750,7 @@ enum class TextureFormat: GLenum { /** * Depth component, size implementation-dependent. * @deprecated_gl Prefer to use the exactly specified version of this - * format, e.g. @ref Magnum::TextureFormat "TextureFormat::DepthComponent16". + * format, e.g. @ref Magnum::TextureFormat::DepthComponent16 "TextureFormat::DepthComponent16". * @requires_gles30 %Extension @es_extension{OES,depth_texture} or * @es_extension{ANGLE,depth_texture} */ @@ -801,7 +809,7 @@ enum class TextureFormat: GLenum { /** * Depth and stencil component, size implementation-dependent. * @deprecated_gl Prefer to use exactly specified version of this format, - * e.g. @ref Magnum::TextureFormat "TextureFormat::Depth24Stencil8". + * e.g. @ref Magnum::TextureFormat::Depth24Stencil8 "TextureFormat::Depth24Stencil8". * @requires_gles30 %Extension @es_extension{OES,packed_depth_stencil} */ #ifndef MAGNUM_TARGET_GLES2