Browse Source

Merge branch 'master' into compatibility

Conflicts:
	src/Math/RectangularMatrix.h
	src/Math/Vector.h
	src/Platform/AbstractXApplication.cpp
	src/Platform/GlutApplication.cpp
	src/Platform/GlutApplication.h
	src/Platform/GlxApplication.h
	src/Platform/NaClApplication.cpp
	src/Platform/NaClApplication.h
	src/Platform/Sdl2Application.cpp
	src/Platform/Sdl2Application.h
	src/Platform/WindowlessGlxApplication.cpp
	src/Platform/WindowlessGlxApplication.h
	src/Platform/WindowlessNaClApplication.cpp
	src/Platform/WindowlessNaClApplication.h
	src/Platform/XEglApplication.h
	src/Platform/magnum-info.cpp
	src/Primitives/Capsule.cpp
	src/Primitives/Circle.cpp
	src/Primitives/Crosshair.cpp
	src/Primitives/Cylinder.cpp
	src/Primitives/Implementation/WireframeSpheroid.cpp
	src/Primitives/Line.cpp
	src/Primitives/Plane.cpp
	src/Primitives/Square.cpp
	src/Primitives/UVSphere.cpp
	src/Shader.cpp
	src/Text/AbstractFontConverter.cpp
	src/Text/fontconverter.cpp
	src/TextureTools/distancefieldconverter.cpp
Vladimír Vondruš 13 years ago
parent
commit
9a4373abbb
  1. 10
      doc/building.dox
  2. BIN
      doc/getting-started-blue.png
  3. 20
      doc/getting-started.dox
  4. BIN
      doc/getting-started.png
  5. 44
      doc/platform.dox
  6. 2
      src/AbstractShaderProgram.h
  7. 2
      src/AbstractTexture.h
  8. 16
      src/Audio/AbstractImporter.cpp
  9. 6
      src/Buffer.h
  10. 15
      src/BufferImage.h
  11. 85
      src/ColorFormat.h
  12. 2
      src/DebugTools/ForceRenderer.cpp
  13. 1
      src/DebugTools/Implementation/AbstractBoxRenderer.cpp
  14. 1
      src/DebugTools/Implementation/CapsuleRenderer.cpp
  15. 2
      src/DebugTools/ObjectRenderer.cpp
  16. 62
      src/Image.h
  17. 4
      src/ImageFormat.h
  18. 24
      src/ImageReference.h
  19. 18
      src/Magnum.h
  20. 4
      src/Math/Geometry/CMakeLists.txt
  21. 6
      src/Math/Geometry/Rectangle.h
  22. 16
      src/Math/RectangularMatrix.h
  23. 24
      src/Math/Vector.h
  24. 18
      src/Mesh.cpp
  25. 174
      src/Mesh.h
  26. 2
      src/MeshTools/CombineIndexedArrays.h
  27. 6
      src/MeshTools/CompressIndices.h
  28. 2
      src/MeshTools/FullScreenTriangle.cpp
  29. 5
      src/MeshTools/Interleave.h
  30. 21
      src/Platform/AbstractXApplication.cpp
  31. 96
      src/Platform/AbstractXApplication.h
  32. 15
      src/Platform/GlutApplication.cpp
  33. 201
      src/Platform/GlutApplication.h
  34. 19
      src/Platform/GlxApplication.h
  35. 16
      src/Platform/NaClApplication.cpp
  36. 141
      src/Platform/NaClApplication.h
  37. 17
      src/Platform/ScreenedApplication.h
  38. 2
      src/Platform/ScreenedApplication.hpp
  39. 16
      src/Platform/Sdl2Application.cpp
  40. 218
      src/Platform/Sdl2Application.h
  41. 33
      src/Platform/WindowlessGlxApplication.cpp
  42. 44
      src/Platform/WindowlessGlxApplication.h
  43. 20
      src/Platform/WindowlessNaClApplication.cpp
  44. 51
      src/Platform/WindowlessNaClApplication.h
  45. 19
      src/Platform/XEglApplication.h
  46. 3
      src/Platform/magnum-info.cpp
  47. 3
      src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp
  48. 9
      src/Primitives/Capsule.cpp
  49. 10
      src/Primitives/Capsule.h
  50. 9
      src/Primitives/Circle.cpp
  51. 4
      src/Primitives/Circle.h
  52. 5
      src/Primitives/Crosshair.cpp
  53. 4
      src/Primitives/Crosshair.h
  54. 5
      src/Primitives/Cube.cpp
  55. 4
      src/Primitives/Cube.h
  56. 5
      src/Primitives/Cylinder.cpp
  57. 4
      src/Primitives/Cylinder.h
  58. 5
      src/Primitives/Icosphere.cpp
  59. 2
      src/Primitives/Icosphere.h
  60. 3
      src/Primitives/Implementation/Spheroid.cpp
  61. 3
      src/Primitives/Implementation/WireframeSpheroid.cpp
  62. 5
      src/Primitives/Line.cpp
  63. 4
      src/Primitives/Line.h
  64. 5
      src/Primitives/Plane.cpp
  65. 4
      src/Primitives/Plane.h
  66. 5
      src/Primitives/Square.cpp
  67. 4
      src/Primitives/Square.h
  68. 5
      src/Primitives/UVSphere.cpp
  69. 8
      src/Primitives/UVSphere.h
  70. 2
      src/Sampler.h
  71. 4
      src/SceneGraph/Animable.h
  72. 21
      src/Shader.cpp
  73. 4
      src/Shaders/Flat.frag
  74. 8
      src/Shaders/Flat2D.vert
  75. 8
      src/Shaders/Flat3D.vert
  76. 2
      src/Shaders/magnumShadersResourceImport.hpp
  77. 2
      src/Swizzle.h
  78. 24
      src/Test/ImageTest.cpp
  79. 8
      src/Test/MeshTest.cpp
  80. 16
      src/Text/AbstractFont.cpp
  81. 45
      src/Text/AbstractFontConverter.cpp
  82. 4
      src/Text/Renderer.cpp
  83. 10
      src/Text/TextRenderer.h
  84. 3
      src/Text/fontconverter.cpp
  85. 58
      src/TextureFormat.h
  86. 2
      src/TextureTools/DistanceField.cpp
  87. 3
      src/TextureTools/distancefieldconverter.cpp
  88. 2
      src/TextureTools/magnumTextureToolsResourceImport.hpp
  89. 9
      src/Trade/AbstractImageConverter.cpp
  90. 16
      src/Trade/AbstractImporter.cpp
  91. 57
      src/Trade/ImageData.h
  92. 2
      src/Trade/MeshData2D.cpp
  93. 12
      src/Trade/MeshData2D.h
  94. 2
      src/Trade/MeshData3D.cpp
  95. 12
      src/Trade/MeshData3D.h
  96. 24
      src/Trade/Test/ImageDataTest.cpp

10
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

BIN
doc/getting-started-blue.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

20
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

BIN
doc/getting-started.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

44
doc/platform.dox

@ -47,15 +47,15 @@ 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
is included, to avoid ambiguity). Changing the code to use different toolkit is
then matter of replacing only the <tt>#</tt>`include` statement.
then matter of replacing only the <tt>#</tt>`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,7 +76,7 @@ class MyApplication: public Platform::Application {
public:
MyApplication(const Arguments& arguments);
void viewportEvent(const Vector2i& viewport) override;
private:
void drawEvent() override;
};
@ -85,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);
@ -102,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
@ -166,8 +183,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
<tt>#</tt>`include` line in the actual code, as said above).
@code
find_package(Magnum REQUIRED GlutApplication)

2
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

2
src/AbstractTexture.h

@ -121,7 +121,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

16
src/Audio/AbstractImporter.cpp

@ -24,9 +24,9 @@
#include "AbstractImporter.h"
#include <fstream>
#include <Containers/Array.h>
#include <Utility/Assert.h>
#include <Utility/Directory.h>
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<unsigned char> data(in.tellg());
/* Read data, close */
in.seekg(0, std::ios::beg);
in.read(reinterpret_cast<char*>(data.begin()), data.size());
in.close();
doOpenData(data);
doOpenData(Utility::Directory::read(filename));
}
void AbstractImporter::close() {

6
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<const void>, BufferUsage) "setData(Containers::ArrayReference<const void>, 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<const void>) "setSubData(GLintptr, Containers::ArrayReference<const void>)"
* 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

15
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<UnsignedInt dimensions> class MAGNUM_EXPORT BufferImage: public AbstractImage {
@ -55,8 +55,8 @@ template<UnsignedInt dimensions> 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<UnsignedInt dimensions> 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<Dimensions, Int>::VectorType& size, ColorFormat format, ColorType type, const void* data, BufferUsage usage);

85
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

2
src/DebugTools/ForceRenderer.cpp

@ -86,7 +86,7 @@ template<UnsignedInt dimensions> ForceRenderer<dimensions>::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<dimensions>::Position(Shaders::Flat<dimensions>::Position::Components::Two))

1
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"

1
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"

2
src/DebugTools/ObjectRenderer.cpp

@ -164,7 +164,7 @@ template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(Scen
indexBuffer->setData(Renderer<dimensions>::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<dimensions>::indices.size())
.addVertexBuffer(*vertexBuffer, 0,
typename Shaders::VertexColor<dimensions>::Position(),

62
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<UnsignedInt dimensions> class Image: public AbstractImage {
public:
@ -60,8 +60,8 @@ template<UnsignedInt dimensions> 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) {}
@ -80,17 +80,27 @@ template<UnsignedInt dimensions> 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<dimensions>() const;
/** @brief Conversion to reference */
/*implicit*/ operator ImageReference<dimensions>()
#ifndef CORRADE_GCC47_COMPATIBILITY
const &;
#else
const;
#endif
#ifndef CORRADE_GCC47_COMPATIBILITY
/** @overload */
/*implicit*/ operator ImageReference<dimensions>() const && = delete;
#endif
/** @brief %Image size */
typename DimensionTraits<Dimensions, Int>::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 */
@ -103,9 +113,19 @@ template<UnsignedInt dimensions> 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<Dimensions, Int>::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<Dimensions, Int> _size;
unsigned char* _data;
@ -132,10 +152,24 @@ template<UnsignedInt dimensions> inline Image<dimensions>& Image<dimensions>::op
return *this;
}
template<UnsignedInt dimensions> inline Image<dimensions>::operator ImageReference<dimensions>() const {
template<UnsignedInt dimensions> inline Image<dimensions>::operator ImageReference<dimensions>()
#ifndef CORRADE_GCC47_COMPATIBILITY
const &
#else
const
#endif
{
return ImageReference<dimensions>(AbstractImage::format(), AbstractImage::type(), _size, _data);
}
template<UnsignedInt dimensions> inline unsigned char* Image<dimensions>::release() {
/** @todo I need `std::exchange` NOW. */
unsigned char* const data = _data;
_size = {};
_data = nullptr;
return data;
}
}
#endif

4
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

24
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,15 +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
@todo Provide const version somewhat
Interchangeable with @ref Image, @ref BufferImage or @ref Trade::ImageData.
@see @ref ImageReference1D, @ref ImageReference2D, @ref ImageReference3D
*/
template<UnsignedInt dimensions> class ImageReference: public AbstractImage {
public:
@ -61,7 +60,7 @@ template<UnsignedInt dimensions> class ImageReference: public AbstractImage {
* @param size %Image size
* @param data %Image data
*/
constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits<Dimensions, Int>::VectorType& size, void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<unsigned char*>(data)) {}
constexpr explicit ImageReference(ColorFormat format, ColorType type, const typename DimensionTraits<Dimensions, Int>::VectorType& size, const void* data): AbstractImage(format, type), _size(size), _data(reinterpret_cast<const unsigned char*>(data)) {}
/**
* @brief Constructor
@ -69,8 +68,8 @@ template<UnsignedInt dimensions> 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<Dimensions, Int>::VectorType& size): AbstractImage(format, type), _size(size), _data(nullptr) {}
@ -78,8 +77,7 @@ template<UnsignedInt dimensions> class ImageReference: public AbstractImage {
constexpr typename DimensionTraits<Dimensions, Int>::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<UnsignedInt dimensions> class ImageReference: public AbstractImage {
* passed in constructor. The data are not copied nor deleted on
* destruction.
*/
void setData(void* data) {
_data = reinterpret_cast<unsigned char*>(data);
void setData(const void* data) {
_data = reinterpret_cast<const unsigned char*>(data);
}
private:
Math::Vector<Dimensions, Int> _size;
unsigned char* _data;
const unsigned char* _data;
};
/** @brief One-dimensional image wrapper */

18
src/Magnum.h

@ -34,6 +34,10 @@
#include "Types.h"
#include "magnumConfigure.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <Utility/Macros.h>
#endif
#ifndef DOXYGEN_GENERATING_OUTPUT
typedef unsigned int GLenum; /* Needed for *Format and *Type enums */
#endif
@ -330,15 +334,15 @@ typedef Math::Range3D<Int> Range3Di;
#ifdef MAGNUM_BUILD_DEPRECATED
/**
@copybrief Range2D
@deprecated Use @ref Magnum::Range2D instead.
@deprecated Use @ref Magnum::Range2D "Range2D" instead.
*/
typedef Math::Geometry::Rectangle<Float> Rectangle;
typedef CORRADE_DEPRECATED("use Range2D instead") Math::Geometry::Rectangle<Float> Rectangle;
/**
@copybrief Range2Di
@deprecated Use @ref Magnum::Range2Di instead.
@deprecated Use @ref Magnum::Range2Di "Range2Di" instead.
*/
typedef Math::Geometry::Rectangle<Int> Rectanglei;
typedef CORRADE_DEPRECATED("use Range2Di instead") Math::Geometry::Rectangle<Int> 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<Double> Range3Dd;
@copybrief Range2Dd
@deprecated Use @ref Magnum::Range2Dd instead.
*/
typedef Math::Geometry::Rectangle<Double> Rectangled;
typedef CORRADE_DEPRECATED("use Range2Dd instead") Math::Geometry::Rectangle<Double> Rectangled;
#endif
/*@}*/
@ -585,6 +589,8 @@ typedef ImageReference<1> ImageReference1D;
typedef ImageReference<2> ImageReference2D;
typedef ImageReference<3> ImageReference3D;
enum class MeshPrimitive: GLenum;
class Mesh;
class MeshView;

4
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()

6
src/Math/Geometry/Rectangle.h

@ -32,13 +32,15 @@
#include "Math/Range.h"
#ifdef MAGNUM_BUILD_DEPRECATED
#include <Utility/Macros.h>
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 T> class Rectangle: public Range2D<T> {
template<class T> class CORRADE_DEPRECATED("use Math::Range2D instead") Rectangle: public Range2D<T> {
public:
/** @copydoc Range2D() */
constexpr Rectangle() = default;

16
src/Math/RectangularMatrix.h

@ -185,20 +185,8 @@ template<std::size_t cols, std::size_t rows, class T> class RectangularMatrix {
*
* @see operator[]
*/
T* data()
#if !defined(CORRADE_GCC47_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY)
&
#endif
{ return _data[0].data(); }
/** @overload */
constexpr const T* data()
#if !defined(CORRADE_GCC47_COMPATIBILITY) && !defined(CORRADE_MSVC2013_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

24
src/Math/Vector.h

@ -199,28 +199,8 @@ template<std::size_t size, class T> class Vector {
*
* @see operator[]()
*/
T* data()
#if !defined(CORRADE_GCC47_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY)
&
#endif
#ifndef CORRADE_MSVC2013_COMPATIBILITY
{ return _data; }
#else
{ return _data.data(); }
#endif
/** @overload */
constexpr const T* data()
#if !defined(CORRADE_GCC47_COMPATIBILITY) && !defined(CORRADE_MSVC2013_COMPATIBILITY)
const &
#else
const
#endif
#ifndef CORRADE_MSVC2013_COMPATIBILITY
{ return _data; }
#else
{ return _data.data(); }
#endif
T* data() { return _data; }
constexpr const T* data() const { return _data; } /**< @overload */
/**
* @brief Value at given position

18
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<Magnum::Mesh::Primitive>::toString(Magnum::Mesh::Primitive value, ConfigurationValueFlags) {
std::string ConfigurationValue<Magnum::MeshPrimitive>::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<Magnum::Mesh::Primitive>::toString(Magnum::Mesh::
return {};
}
Magnum::Mesh::Primitive ConfigurationValue<Magnum::Mesh::Primitive>::fromString(const std::string& stringValue, ConfigurationValueFlags) {
#define _c(value) if(stringValue == #value) return Magnum::Mesh::Primitive::value;
Magnum::MeshPrimitive ConfigurationValue<Magnum::MeshPrimitive>::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<Magnum::Mesh::Primitive>::fromString(
#endif
#undef _c
return Magnum::Mesh::Primitive::Points;
return Magnum::MeshPrimitive::Points;
}
std::string ConfigurationValue<Magnum::Mesh::IndexType>::toString(Magnum::Mesh::IndexType value, ConfigurationValueFlags) {

174
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<Magnum::Mesh::Primitive> {
template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::MeshPrimitive> {
ConfigurationValue() = delete;
/**
@ -780,14 +788,14 @@ template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::Mesh::Primitive> {
*
* 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} */

2
src/MeshTools/CombineIndexedArrays.h

@ -128,6 +128,8 @@ std::vector<UnsignedInt> 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

6
src/MeshTools/CompressIndices.h

@ -69,9 +69,9 @@ std::tuple<std::size_t, Mesh::IndexType, Containers::Array<char>> MAGNUM_MESHTOO
@param indices Index array
The same as @ref compressIndices(const std::vector<UnsignedInt>&), 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()
*/

2
src/MeshTools/FullScreenTriangle.cpp

@ -34,7 +34,7 @@ namespace Magnum { namespace MeshTools {
std::pair<Buffer*, Mesh> fullScreenTriangle() {
Mesh mesh;
mesh.setPrimitive(Mesh::Primitive::Triangles)
mesh.setPrimitive(MeshPrimitive::Triangles)
.setVertexCount(3);
Buffer* buffer = nullptr;

5
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:
@ -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<class ...T> inline void interleave(Mesh& mesh, Buffer& buffer, BufferUsage usage, const T&... attributes) {
return Implementation::Interleave()(mesh, buffer, usage, attributes...);

21
src/Platform/AbstractXApplication.cpp

@ -42,13 +42,6 @@ AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandle
createContext(configuration);
}
#ifndef DOXYGEN_GENERATING_OUTPUT
AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments&): contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
}
#endif
#ifndef CORRADE_GCC45_COMPATIBILITY
AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments&, std::nullptr_t)
#else
@ -56,8 +49,14 @@ AbstractXApplication::AbstractXApplication(Implementation::AbstractContextHandle
#endif
: contextHandler(contextHandler), c(nullptr), flags(Flag::Redraw) {}
void AbstractXApplication::createContext() { createContext({}); }
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", false);
viewportSize = configuration.size();
@ -73,8 +72,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 */
@ -103,6 +102,7 @@ void AbstractXApplication::createContext(const Configuration& configuration) {
contextHandler->makeCurrent();
c = new Context;
return true;
}
AbstractXApplication::~AbstractXApplication() {
@ -174,6 +174,7 @@ int AbstractXApplication::exec() {
return 0;
}
void AbstractXApplication::viewportEvent(const Vector2i&) {}
void AbstractXApplication::keyPressEvent(KeyEvent&) {}
void AbstractXApplication::keyReleaseEvent(KeyEvent&) {}
void AbstractXApplication::mousePressEvent(MouseEvent&) {}

96
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()`.
@ -87,23 +99,37 @@ class AbstractXApplication {
this is faster than public pure virtual destructor */
~AbstractXApplication();
/** @copydoc GlutApplication::createContext() */
/** @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
/** @{ @name Drawing functions */
/** @copydoc GlutApplication::viewportEvent() */
virtual void viewportEvent(const Vector2i& size) = 0;
/** @copydoc Sdl2Application::tryCreateContext() */
bool tryCreateContext(const Configuration& configuration);
/** @copydoc GlutApplication::drawEvent() */
virtual void drawEvent() = 0;
/** @{ @name Screen handling */
/** @copydoc GlutApplication::swapBuffers() */
/** @copydoc Sdl2Application::swapBuffers() */
void swapBuffers();
/** @copydoc GlutApplication::redraw() */
/** @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);
/** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0;
/*@}*/
/** @{ @name Keyboard handling */
@ -134,10 +160,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<Display*, VisualID, Window>* contextHandler, const Arguments& arguments, const Configuration& configuration);
explicit AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments& arguments);
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit AbstractXApplication(Implementation::AbstractContextHandler<Display*, VisualID, Window>* contextHandler, const Arguments& arguments, std::nullptr_t);
@ -174,15 +197,11 @@ CORRADE_ENUMSET_OPERATORS(AbstractXApplication::Flags)
@brief %Configuration
Double-buffered OpenGL context.
@see AbstractXApplication(), createContext()
@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 {
Configuration(const Configuration&) = delete;
Configuration(Configuration&&) = delete;
Configuration& operator=(const Configuration&) = delete;
Configuration& operator=(Configuration&&) = delete;
public:
/*implicit*/ Configuration();
~Configuration();
@ -223,21 +242,16 @@ 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;
InputEvent(InputEvent&&) = delete;
InputEvent& operator=(const InputEvent&) = delete;
InputEvent& operator=(InputEvent&&) = delete;
public:
public:
/**
* @brief %Modifier
*
* @see Modifiers, modifiers()
* @see @ref Modifiers, @ref modifiers()
*/
enum class Modifier: unsigned int {
Shift = ShiftMask, /**< Shift */
@ -278,7 +292,7 @@ class AbstractXApplication::InputEvent {
/**
* @brief Set of modifiers
*
* @see modifiers()
* @see @ref modifiers()
*/
typedef Containers::EnumSet<Modifier, unsigned int> Modifiers;
@ -300,10 +314,22 @@ class AbstractXApplication::InputEvent {
*/
typedef Containers::EnumSet<Button, unsigned int> Buttons;
/** @copydoc GlutApplication::InputEvent::setAccepted() */
/** @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; }
/** @copydoc GlutApplication::InputEvent::isAccepted() */
/** @copydoc Sdl2Application::InputEvent::isAccepted() */
constexpr bool isAccepted() const { return _accepted; }
/** @brief Modifiers */
@ -338,7 +364,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;
@ -347,7 +373,7 @@ class AbstractXApplication::KeyEvent: public AbstractXApplication::InputEvent {
/**
* @brief Key
*
* @see key()
* @see @ref key()
*/
enum class Key: KeySym {
Enter = XK_Return, /**< Enter */
@ -438,7 +464,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;
@ -447,7 +473,7 @@ class AbstractXApplication::MouseEvent: public AbstractXApplication::InputEvent
/**
* @brief Mouse button
*
* @see button()
* @see @ref button()
*/
enum class Button: unsigned int {
Left = Button1, /**< Left button */
@ -473,7 +499,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;

15
src/Platform/GlutApplication.cpp

@ -42,8 +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);
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
}
#endif
@ -66,11 +65,10 @@ 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)) {
Error() << "Platform::GlutApplication::createContext(): cannot create context";
std::exit(1);
}
if(!tryCreateContext(configuration)) std::exit(1);
}
bool GlutApplication::tryCreateContext(const Configuration& configuration) {
@ -83,8 +81,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);
@ -117,6 +117,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&) {}

201
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...
@ -90,15 +91,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,23 +100,26 @@ 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) */
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit GlutApplication(const Arguments& arguments, std::nullptr_t);
#else
explicit GlutApplication(const Arguments& arguments, void*);
#endif
/**
* @brief Execute main loop
* @return Value for returning from `main()`.
*/
/** @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();
return 0;
@ -134,74 +130,42 @@ 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() */
#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
*
* Unlike createContext() returns `false` if the context cannot be
* created, `true` otherwise.
*/
/** @copydoc Sdl2Application::tryCreateContext() */
bool tryCreateContext(const Configuration& configuration);
/** @{ @name Drawing functions */
/** @{ @name Screen handling */
/**
* @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().
*/
virtual void viewportEvent(const Vector2i& size) = 0;
/** @copydoc Sdl2Application::swapBuffers() */
void swapBuffers() { glutSwapBuffers(); }
/**
* @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().
*/
virtual void drawEvent() = 0;
/** @copydoc Sdl2Application::redraw() */
void redraw() { glutPostRedisplay(); }
/**
* @brief Swap buffers
*
* Paints currently rendered framebuffer on screen.
*/
void swapBuffers() { glutSwapBuffers(); }
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @copydoc Sdl2Application::viewportEvent() */
virtual void viewportEvent(const Vector2i& size);
/**
* @brief Redraw immediately
*
* Marks the window for redrawing, resulting in call to drawEvent()
* in the next iteration.
*/
virtual void redraw() { glutPostRedisplay(); }
/** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0;
/*@}*/
/** @{ @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);
/**
@ -230,7 +194,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) {
@ -247,21 +211,15 @@ class GlutApplication {
glutWarpPointer(position.x(), position.y());
}
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
/**
* @brief Mouse press event
*
* Called when mouse button is pressed. Default implementation does
* nothing.
*/
#else
private:
#endif
/** @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);
/**
@ -269,7 +227,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);
@ -301,14 +259,9 @@ 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;
Configuration(Configuration&&) = delete;
Configuration& operator=(const Configuration&) = delete;
Configuration& operator=(Configuration&&) = delete;
public:
/*implicit*/ Configuration();
~Configuration();
@ -366,25 +319,27 @@ 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;
InputEvent(InputEvent&&) = delete;
InputEvent& operator=(const InputEvent&) = delete;
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.
*/
/** @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; }
/** @brief Whether the event is accepted */
/** @copydoc Sdl2Application::InputEvent::isAccepted() */
constexpr bool isAccepted() const { return _accepted; }
protected:
@ -407,7 +362,7 @@ GlutApplication::InputEvent::~InputEvent() = default;
/**
@brief Key event
@see keyPressEvent()
@see @ref keyPressEvent()
*/
class GlutApplication::KeyEvent: public GlutApplication::InputEvent {
friend class GlutApplication;
@ -416,7 +371,7 @@ class GlutApplication::KeyEvent: public GlutApplication::InputEvent {
/**
* @brief Key
*
* @see key()
* @see @ref key()
*/
enum class Key: int {
Up = GLUT_KEY_UP, /**< Up arrow */
@ -457,7 +412,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;
@ -466,7 +421,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 */
@ -492,7 +447,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;
@ -501,7 +456,7 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent {
/**
* @brief Mouse button
*
* @see Buttons, buttons()
* @see @ref Buttons, @ref buttons()
*/
enum class Button: UnsignedByte {
/**
@ -514,7 +469,7 @@ class GlutApplication::MouseMoveEvent: public GlutApplication::InputEvent {
/**
* @brief Set of mouse buttons
*
* @see buttons()
* @see @ref buttons()
*/
typedef Containers::EnumSet<Button, UnsignedByte> Buttons;
@ -535,9 +490,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});

19
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...
@ -66,10 +67,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) */
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit GlxApplication(const Arguments& arguments, std::nullptr_t);
#else
@ -86,9 +87,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});

16
src/Platform/NaClApplication.cpp

@ -60,8 +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);
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
}
#endif
@ -75,11 +74,10 @@ NaClApplication::NaClApplication(const Arguments& arguments, void*)
debugOutput = new ConsoleDebugOutput(this);
}
void NaClApplication::createContext() { createContext({}); }
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) {
@ -100,13 +98,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);
@ -256,6 +257,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&) {}

141
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...
@ -148,7 +149,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,13 +158,45 @@ 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) */
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit NaClApplication(const Arguments& arguments, std::nullptr_t);
#else
explicit NaClApplication(const Arguments& arguments, void*);
#endif
/** @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;
protected:
/* Nobody will need to have (and delete) NaClApplication*, thus this is
faster than public pure virtual destructor */
~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);
/** @{ @name Screen handling */
public:
/** @brief Whether the application runs fullscreen */
bool isFullscreen();
@ -178,30 +211,23 @@ class NaClApplication: public pp::Instance, public pp::Graphics3DClient, public
bool setFullscreen(bool enabled);
protected:
/* Nobody will need to have (and delete) NaClApplication*, thus this is
faster than public pure virtual destructor */
~NaClApplication();
/** @copydoc GlutApplication::createContext() */
void createContext(const Configuration& configuration);
/** @copydoc GlutApplication::tryCreateContext() */
bool tryCreateContext(const Configuration& configuration);
/** @copydoc Sdl2Application::swapBuffers() */
void swapBuffers();
/** @{ @name Drawing functions */
/** @copydoc Sdl2Application::redraw() */
void redraw() { flags |= Flag::Redraw; }
/** @copydoc GlutApplication::viewportEvent() */
virtual void viewportEvent(const Vector2i& size) = 0;
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/** @copydoc Sdl2Application::viewportEvent() */
virtual void viewportEvent(const Vector2i& size);
/** @copydoc GlutApplication::drawEvent() */
/** @copydoc Sdl2Application::drawEvent() */
virtual void drawEvent() = 0;
/** @copydoc GlutApplication::swapBuffers() */
void swapBuffers();
/** @copydoc GlutApplication::redraw() */
void redraw() { flags |= Flag::Redraw; }
/*@}*/
/** @{ @name Keyboard handling */
@ -236,12 +262,16 @@ 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);
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/**
* @brief Mouse press event
*
@ -313,14 +343,9 @@ 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;
Configuration(Configuration&&) = delete;
Configuration& operator=(const Configuration&) = delete;
Configuration& operator=(Configuration&&) = delete;
public:
constexpr /*implicit*/ Configuration(): _size(640, 480), _sampleCount(0) {}
@ -361,23 +386,19 @@ 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;
InputEvent(InputEvent&&) = delete;
InputEvent& operator=(const InputEvent&) = delete;
InputEvent& operator=(InputEvent&&) = delete;
public:
/**
* @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 */
@ -418,7 +439,7 @@ class NaClApplication::InputEvent {
/**
* @brief Set of modifiers
*
* @see modifiers()
* @see @ref modifiers()
*/
typedef Containers::EnumSet<Modifier, std::uint32_t> Modifiers;
@ -440,6 +461,18 @@ class NaClApplication::InputEvent {
*/
typedef Containers::EnumSet<Button, std::uint32_t> 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; }
@ -481,8 +514,8 @@ inline NaClApplication::InputEvent::~InputEvent() = default;
/**
@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;
@ -492,7 +525,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 */
@ -576,8 +609,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;
@ -586,7 +619,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 */
@ -610,8 +643,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;
@ -654,9 +687,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) \

17
src/Platform/ScreenedApplication.h

@ -165,19 +165,20 @@ template<class Application> 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
*
* 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

2
src/Platform/ScreenedApplication.hpp

@ -77,6 +77,8 @@ template<class Application> BasicScreenedApplication<Application>& BasicScreened
return *this;
}
template<class Application> void BasicScreenedApplication<Application>::globalViewportEvent(const Vector2i&) {}
template<class Application> void BasicScreenedApplication<Application>::viewportEvent(const Vector2i& size) {
/* Call viewport event after all other (because of framebuffer resizing) */
globalViewportEvent(size);

16
src/Platform/Sdl2Application.cpp

@ -68,8 +68,7 @@ Sdl2Application::Sdl2Application(const Arguments&, const Configuration& configur
#ifndef DOXYGEN_GENERATING_OUTPUT
Sdl2Application::Sdl2Application(const Arguments&): context(nullptr), flags(Flag::Redraw) {
initialize();
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
}
#endif
@ -95,11 +94,10 @@ void Sdl2Application::initialize() {
}
}
void Sdl2Application::createContext() { createContext({}); }
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) {
@ -122,10 +120,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;
@ -249,6 +250,7 @@ void Sdl2Application::setMouseLocked(bool enabled) {
#endif
}
void Sdl2Application::viewportEvent(const Vector2i&) {}
void Sdl2Application::keyPressEvent(KeyEvent&) {}
void Sdl2Application::keyReleaseEvent(KeyEvent&) {}
void Sdl2Application::mousePressEvent(MouseEvent&) {}

218
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**
@ -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...
@ -135,7 +136,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,14 +153,35 @@ 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().
*/
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit Sdl2Application(const Arguments& arguments, std::nullptr_t);
#else
explicit Sdl2Application(const Arguments& arguments, void*);
#endif
/** @copydoc GlutApplication::exec() */
/** @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()`.
*/
int exec();
/** @brief Exit application main loop */
@ -162,31 +192,87 @@ 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.
*/
#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 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() */
virtual void viewportEvent(const Vector2i& size) = 0;
/** @copydoc GlutApplication::drawEvent() */
virtual void drawEvent() = 0;
/** @{ @name Screen handling */
/** @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; }
#ifdef DOXYGEN_GENERATING_OUTPUT
protected:
#else
private:
#endif
/**
* @brief Viewport event
*
* 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 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);
/**
* @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;
/*@}*/
/** @{ @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);
/**
@ -208,16 +294,30 @@ 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:
/** @copydoc GlutApplication::mousePressEvent() */
#else
private:
#endif
/**
* @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);
/**
@ -267,19 +367,14 @@ 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;
Configuration(Configuration&&) = delete;
Configuration& operator=(const Configuration&) = delete;
Configuration& operator=(Configuration&&) = delete;
public:
/**
* @brief Window flag
*
* @see Flags, setFlags()
* @see @ref Flags, @ref setFlags()
*/
enum class Flag: Uint32 {
Resizable = SDL_WINDOW_RESIZABLE, /**< Resizable window */
@ -293,7 +388,7 @@ class Sdl2Application::Configuration {
/**
* @brief Window flags
*
* @see setFlags()
* @see @ref setFlags()
*/
typedef Containers::EnumSet<Flag, Uint32, SDL_WINDOW_RESIZABLE|
SDL_WINDOW_FULLSCREEN|SDL_WINDOW_HIDDEN|SDL_WINDOW_MAXIMIZED|
@ -371,21 +466,17 @@ CORRADE_ENUMSET_OPERATORS(Sdl2Application::Configuration::Flags)
/**
@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 Sdl2Application::InputEvent {
InputEvent(const InputEvent&) = delete;
InputEvent(InputEvent&&) = delete;
InputEvent& operator=(const InputEvent&) = delete;
InputEvent& operator=(InputEvent&&) = delete;
public:
/**
* @brief %Modifier
*
* @see Modifiers, KeyEvent::modifiers(), MouseEvent::modifiers(),
* MouseMoveEvent::modifiers()
* @see @ref Modifiers, @ref KeyEvent::modifiers(),
* @ref MouseEvent::modifiers(), @ref MouseMoveEvent::modifiers()
*/
enum class Modifier: Uint16 {
Shift = KMOD_SHIFT, /**< Shift */
@ -400,15 +491,34 @@ class Sdl2Application::InputEvent {
/**
* @brief Set of modifiers
*
* @see KeyEvent::modifiers(), MouseEvent::modifiers(),
* MouseMoveEvent::modifiers()
* @see @ref KeyEvent::modifiers(), @ref MouseEvent::modifiers(),
* @ref MouseMoveEvent::modifiers()
*/
typedef Containers::EnumSet<Modifier, Uint16> Modifiers;
/** @copydoc GlutApplication::InputEvent::setAccepted() */
/** @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
*
* 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
@ -433,7 +543,7 @@ Sdl2Application::InputEvent::~InputEvent() = default;
/**
@brief Key event
@see keyPressEvent(), keyReleaseEvent()
@see @ref keyPressEvent(), @ref keyReleaseEvent()
*/
class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent {
friend class Sdl2Application;
@ -442,7 +552,7 @@ class Sdl2Application::KeyEvent: public Sdl2Application::InputEvent {
/**
* @brief Key
*
* @see key()
* @see @ref key()
*/
enum class Key: SDL_Keycode {
Enter = SDLK_RETURN, /**< Enter */
@ -533,7 +643,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;
@ -542,7 +652,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 */
@ -577,7 +687,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;
@ -636,9 +746,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});

33
src/Platform/WindowlessGlxApplication.cpp

@ -41,8 +41,7 @@ WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, const Confi
#ifndef DOXYGEN_GENERATING_OUTPUT
WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&): c(nullptr) {
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
}
#endif
@ -53,8 +52,14 @@ WindowlessGlxApplication::WindowlessGlxApplication(const Arguments&, void*)
#endif
: c(nullptr) {}
void WindowlessGlxApplication::createContext(const Configuration&) {
CORRADE_ASSERT(!c, "WindowlessGlxApplication::createContext(): context already created", );
void WindowlessGlxApplication::createContext() { createContext({}); }
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", false);
display = XOpenDisplay(nullptr);
@ -62,8 +67,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 */
@ -71,8 +76,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[] = {
@ -88,8 +93,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 */
@ -104,11 +109,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() {
@ -118,7 +124,4 @@ WindowlessGlxApplication::~WindowlessGlxApplication() {
glXDestroyContext(display, context);
}
WindowlessGlxApplication::Configuration::Configuration() = default;
WindowlessGlxApplication::Configuration::~Configuration() = default;
}}

44
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...
@ -83,7 +84,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,13 +93,25 @@ class WindowlessGlxApplication {
explicit WindowlessGlxApplication(const Arguments& arguments);
#endif
/** @copydoc GlutApplication::GlutApplication(const Arguments&, std::nullptr_t) */
/** @copydoc Sdl2Application::Sdl2Application(const Arguments&, std::nullptr_t) */
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit WindowlessGlxApplication(const Arguments& arguments, std::nullptr_t);
#else
explicit WindowlessGlxApplication(const Arguments& arguments, void*);
#endif
/** @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()`.
@ -110,8 +123,17 @@ class WindowlessGlxApplication {
thus this is faster than public pure virtual destructor */
~WindowlessGlxApplication();
/** @copydoc GlutApplication::createContext() */
/** @copydoc Sdl2Application::createContext() */
#ifdef DOXYGEN_GENERATING_OUTPUT
void createContext(const Configuration& configuration = Configuration());
#else
/* To avoid "invalid use of incomplete type" */
void createContext(const Configuration& configuration);
void createContext();
#endif
/** @copydoc Sdl2Application::tryCreateContext() */
bool tryCreateContext(const Configuration& configuration);
private:
Display* display;
@ -124,24 +146,20 @@ class WindowlessGlxApplication {
/**
@brief %Configuration
@see WindowlessGlxApplication(), createContext()
@see @ref WindowlessGlxApplication(), @ref createContext(),
@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();
constexpr /*implicit*/ Configuration() {}
};
/** @hideinitializer
@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) {

20
src/Platform/WindowlessNaClApplication.cpp

@ -26,6 +26,7 @@
#include <ppapi/cpp/graphics_3d.h>
#include <ppapi/cpp/completion_callback.h>
#include <Utility/Assert.h>
#include <Utility/NaClStreamBuffer.h>
#include "Context.h"
@ -58,8 +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);
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
}
#endif
@ -73,11 +73,10 @@ WindowlessNaClApplication::WindowlessNaClApplication(const Arguments& arguments,
debugOutput = new ConsoleDebugOutput(this);
}
void WindowlessNaClApplication::createContext() { createContext({}); }
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&) {
@ -94,13 +93,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());
@ -119,4 +121,8 @@ bool WindowlessNaClApplication::Init(uint32_t , const char* , const char*) {
return exec() == 0;
}
void WindowlessNaClApplication::Graphics3DContextLost() {
CORRADE_ASSERT(false, "NaClApplication: context unexpectedly lost", );
}
}}

51
src/Platform/WindowlessNaClApplication.h

@ -35,7 +35,6 @@
#include <ppapi/cpp/graphics_3d_client.h>
#include <ppapi/gles2/gl2ext_ppapi.h>
#include "Math/Vector2.h"
#include "Magnum.h"
#include "corradeCompatibility.h"
@ -61,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...
@ -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,13 +109,25 @@ 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) */
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit WindowlessNaClApplication(const Arguments& arguments, std::nullptr_t);
#else
explicit WindowlessNaClApplication(const Arguments& arguments, void*);
#endif
/** @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()`.
@ -127,18 +139,22 @@ class WindowlessNaClApplication: public pp::Instance, public pp::Graphics3DClien
thus this is faster than public pure virtual destructor */
~WindowlessNaClApplication();
/** @copydoc GlutApplication::createContext() */
/** @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 GlutApplication::tryCreateContext() */
/** @copydoc Sdl2Application::tryCreateContext() */
bool tryCreateContext(const Configuration& configuration);
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;
@ -150,14 +166,10 @@ 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;
Configuration(Configuration&&) = delete;
Configuration& operator=(const Configuration&) = delete;
Configuration& operator=(Configuration&&) = delete;
public:
constexpr /*implicit*/ Configuration() {}
};
@ -181,9 +193,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) \

19
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...
@ -67,10 +68,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) */
#ifndef CORRADE_GCC45_COMPATIBILITY
explicit XEglApplication(const Arguments& arguments, std::nullptr_t);
#else
@ -87,9 +88,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});

3
src/Platform/magnum-info.cpp

@ -70,8 +70,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat
/* Create context after parsing arguments, so the help can be displayed
without creating context */
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
Context* c = Context::current();
/* Pass debug output as messages to JavaScript */

3
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 char originalData[] = {
1, 2, 3, 2, 3, 4,
3, 4, 5, 4, 5, 6,
5, 6, 7, 6, 7, 8

9
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"
@ -35,7 +36,7 @@ namespace Magnum { namespace Primitives {
Trade::MeshData2D Capsule2D::wireframe(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, Float halfLength) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
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<UnsignedInt>(), std::vector<std::vector<Vector2>>(), std::vector<std::vector<Vector2>>()));
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<UnsignedInt>(), std::vector<std::vector<Vector2>>(), std::vector<std::vector<Vector2>>()));
std::vector<Vector2> positions;
positions.reserve(hemisphereRings*4+2+(cylinderRings-1)*2);
@ -86,12 +87,12 @@ 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<std::vector<Vector2>>{});
return Trade::MeshData2D(MeshPrimitive::Lines, std::move(indices), {std::move(positions)}, std::vector<std::vector<Vector2>>{});
}
Trade::MeshData3D Capsule3D::solid(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float halfLength, TextureCoords textureCoords) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
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<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
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<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
Implementation::Spheroid capsule(segments, textureCoords == TextureCoords::Generate ?
Implementation::Spheroid::TextureCoords::Generate :
@ -126,7 +127,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) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Capsule::wireframe(): improper parameters", Trade::MeshData3D(Mesh::Primitive::Lines, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
CORRADE_ASSERT(hemisphereRings >= 1 && cylinderRings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Capsule::wireframe(): improper parameters", Trade::MeshData3D(MeshPrimitive::Lines, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
Implementation::WireframeSpheroid capsule(segments/4);

10
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);
};

9
src/Primitives/Circle.cpp

@ -26,6 +26,7 @@
#include "Math/Functions.h"
#include "Math/Vector2.h"
#include "Mesh.h"
#include "Trade/MeshData2D.h"
namespace Magnum { namespace Primitives {
@ -33,7 +34,7 @@ namespace Magnum { namespace Primitives {
Trade::MeshData2D Circle::solid(UnsignedInt segments) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
CORRADE_ASSERT(segments >= 3, "Primitives::Circle::solid(): segments must be >= 3",
Trade::MeshData2D(Mesh::Primitive::TriangleFan, std::vector<UnsignedInt>(), std::vector<std::vector<Vector2>>(), std::vector<std::vector<Vector2>>()));
Trade::MeshData2D(MeshPrimitive::TriangleFan, std::vector<UnsignedInt>(), std::vector<std::vector<Vector2>>(), std::vector<std::vector<Vector2>>()));
std::vector<Vector2> positions;
positions.reserve(segments+1);
@ -48,13 +49,13 @@ Trade::MeshData2D Circle::solid(UnsignedInt segments) {
positions.emplace_back(Math::cos(angle), Math::sin(angle));
}
return Trade::MeshData2D(Mesh::Primitive::TriangleFan, std::vector<UnsignedInt>{}, {std::move(positions)}, std::vector<std::vector<Vector2>>{});
return Trade::MeshData2D(MeshPrimitive::TriangleFan, std::vector<UnsignedInt>{}, {std::move(positions)}, std::vector<std::vector<Vector2>>{});
}
Trade::MeshData2D Circle::wireframe(UnsignedInt segments) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
CORRADE_ASSERT(segments >= 3, "Primitives::Circle::wireframe(): segments must be >= 3",
Trade::MeshData2D(Mesh::Primitive::LineLoop, std::vector<UnsignedInt>(), std::vector<std::vector<Vector2>>(), std::vector<std::vector<Vector2>>()));
Trade::MeshData2D(MeshPrimitive::LineLoop, std::vector<UnsignedInt>(), std::vector<std::vector<Vector2>>(), std::vector<std::vector<Vector2>>()));
std::vector<Vector2> positions;
positions.reserve(segments);
@ -66,7 +67,7 @@ Trade::MeshData2D Circle::wireframe(UnsignedInt segments) {
positions.emplace_back(Math::cos(angle), Math::sin(angle));
}
return Trade::MeshData2D(Mesh::Primitive::LineLoop, std::vector<UnsignedInt>{}, {std::move(positions)}, std::vector<std::vector<Vector2>>{});
return Trade::MeshData2D(MeshPrimitive::LineLoop, std::vector<UnsignedInt>{}, {std::move(positions)}, std::vector<std::vector<Vector2>>{});
}
}}

4
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);

5
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<UnsignedInt>{}, {std::vector<Vector2>{
return Trade::MeshData2D(MeshPrimitive::Lines, std::vector<UnsignedInt>{}, {std::vector<Vector2>{
{-1.0f, 0.0f}, {1.0f, 0.0f},
{ 0.0f, -1.0f}, {0.0f, 1.0f}
}}, std::vector<std::vector<Vector2>>{});
}
Trade::MeshData3D Crosshair3D::wireframe() {
return Trade::MeshData3D(Mesh::Primitive::Lines, std::vector<UnsignedInt>{}, {std::vector<Vector3>{
return Trade::MeshData3D(MeshPrimitive::Lines, std::vector<UnsignedInt>{}, {std::vector<Vector3>{
{-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}

4
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:

5
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 */

4
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();

5
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"
@ -33,7 +34,7 @@ namespace Magnum { namespace Primitives {
Trade::MeshData3D Cylinder::solid(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength, const Flags flags) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
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<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
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<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
Implementation::Spheroid cylinder(segments, flags & Flag::GenerateTextureCoords ? Implementation::Spheroid::TextureCoords::Generate : Implementation::Spheroid::TextureCoords::DontGenerate);
@ -65,7 +66,7 @@ Trade::MeshData3D Cylinder::solid(const UnsignedInt rings, const UnsignedInt seg
Trade::MeshData3D Cylinder::wireframe(const UnsignedInt rings, const UnsignedInt segments, const Float halfLength) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
CORRADE_ASSERT(rings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Cylinder::wireframe(): improper parameters", Trade::MeshData3D(Mesh::Primitive::Lines, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
CORRADE_ASSERT(rings >= 1 && segments >= 4 && segments%4 == 0, "Primitives::Cylinder::wireframe(): improper parameters", Trade::MeshData3D(MeshPrimitive::Lines, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
Implementation::WireframeSpheroid cylinder(segments/4);

4
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);
};

5
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 {
@ -82,7 +83,7 @@ Trade::MeshData3D Icosphere::solid(const UnsignedInt subdivisions) {
MeshTools::removeDuplicates(indices, positions);
std::vector<Vector3> normals(positions);
return Trade::MeshData3D(Mesh::Primitive::Triangles, std::move(indices), {std::move(positions)}, {std::move(normals)}, std::vector<std::vector<Vector2>>{});
return Trade::MeshData3D(MeshPrimitive::Triangles, std::move(indices), {std::move(positions)}, {std::move(normals)}, std::vector<std::vector<Vector2>>{});
}
}}

2
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);
};

3
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::vector<Vector2>>{std::move(textureCoords2D)} : std::vector<std::vector<Vector2>>());
}

3
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 {
@ -110,7 +111,7 @@ void WireframeSpheroid::cylinder() {
Trade::MeshData3D WireframeSpheroid::finalize() {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
return Trade::MeshData3D(Mesh::Primitive::Lines, std::move(_indices), {std::move(_positions)}, std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>());
return Trade::MeshData3D(MeshPrimitive::Lines, std::move(_indices), {std::move(_positions)}, std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>());
}
}}}

5
src/Primitives/Line.cpp

@ -25,20 +25,21 @@
#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<UnsignedInt>{}, {std::vector<Vector2>{
return Trade::MeshData2D(MeshPrimitive::Lines, std::vector<UnsignedInt>{}, {std::vector<Vector2>{
{0.0f, 0.0f}, {1.0f, 0.0f}
}}, std::vector<std::vector<Vector2>>{});
}
Trade::MeshData3D Line3D::wireframe() {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
return Trade::MeshData3D(Mesh::Primitive::Lines, std::vector<UnsignedInt>(), {std::vector<Vector3>{
return Trade::MeshData3D(MeshPrimitive::Lines, std::vector<UnsignedInt>(), {std::vector<Vector3>{
{0.0f, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f},
}}, std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>());
}

4
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:

5
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<UnsignedInt>{}, {std::vector<Vector3>{
return Trade::MeshData3D(MeshPrimitive::TriangleStrip, std::vector<UnsignedInt>{}, {std::vector<Vector3>{
{1.0f, -1.0f, 0.0f},
{1.0f, 1.0f, 0.0f},
{-1.0f, -1.0f, 0.0f},
@ -53,7 +54,7 @@ Trade::MeshData3D Plane::solid(const TextureCoords textureCoords) {
Trade::MeshData3D Plane::wireframe() {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
return Trade::MeshData3D(Mesh::Primitive::LineLoop, std::vector<UnsignedInt>(), {std::vector<Vector3>{
return Trade::MeshData3D(MeshPrimitive::LineLoop, std::vector<UnsignedInt>(), {std::vector<Vector3>{
{-1.0f, -1.0f, 0.0f},
{1.0f, -1.0f, 0.0f},
{1.0f, 1.0f, 0.0f},

4
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();

5
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<UnsignedInt>{}, {std::vector<Vector2>{
return Trade::MeshData2D(MeshPrimitive::TriangleStrip, std::vector<UnsignedInt>{}, {std::vector<Vector2>{
{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<UnsignedInt>{}, {std::vector<Vector2>{
return Trade::MeshData2D(MeshPrimitive::LineLoop, std::vector<UnsignedInt>{}, {std::vector<Vector2>{
{-1.0f, -1.0f},
{1.0f, -1.0f},
{1.0f, 1.0f},

4
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();

5
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"
@ -33,7 +34,7 @@ namespace Magnum { namespace Primitives {
Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, TextureCoords textureCoords) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(Mesh::Primitive::Triangles, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
CORRADE_ASSERT(rings >= 2 && segments >= 3, "UVSphere must have at least two rings and three segments", Trade::MeshData3D(MeshPrimitive::Triangles, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
Implementation::Spheroid sphere(segments, textureCoords == TextureCoords::Generate ?
Implementation::Spheroid::TextureCoords::Generate :
@ -61,7 +62,7 @@ Trade::MeshData3D UVSphere::solid(UnsignedInt rings, UnsignedInt segments, Textu
Trade::MeshData3D UVSphere::wireframe(const UnsignedInt rings, const UnsignedInt segments) {
/* {} initializers are causing ICE in MSVC 2013. Bhaha. */
CORRADE_ASSERT(rings >= 2 && rings%2 == 0 && segments >= 4 && segments%2 == 0, "Primitives::UVSphere::wireframe(): improper parameters", Trade::MeshData3D(Mesh::Primitive::Lines, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
CORRADE_ASSERT(rings >= 2 && rings%2 == 0 && segments >= 4 && segments%2 == 0, "Primitives::UVSphere::wireframe(): improper parameters", Trade::MeshData3D(MeshPrimitive::Lines, std::vector<UnsignedInt>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector3>>(), std::vector<std::vector<Vector2>>()));
Implementation::WireframeSpheroid sphere(segments/4);

8
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);
};

2
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
};

4
src/SceneGraph/Animable.h

@ -229,14 +229,14 @@ template<UnsignedInt dimensions, class T> class Animable: public AbstractGrouped
* @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()"
* instead.
*/
AnimableGroup<dimensions, T>* group() { return animables(); }
CORRADE_DEPRECATED("use animables() instead") AnimableGroup<dimensions, T>* group() { return animables(); }
/**
* @copydoc animables()
* @deprecated Use @ref Magnum::SceneGraph::Animable::animables() "animables()"
* instead.
*/
const AnimableGroup<dimensions, T>* group() const { return animables(); }
CORRADE_DEPRECATED("use animables() instead") const AnimableGroup<dimensions, T>* group() const { return animables(); }
#endif
protected:

21
src/Shader.cpp

@ -25,9 +25,10 @@
#include "Shader.h"
#include <algorithm> /* std::max(), needed by MSVC */
#include <fstream>
#include <Containers/Array.h>
#include <Utility/Assert.h>
#include <Utility/Directory.h>
#include "Extensions.h"
#include "Implementation/State.h"
@ -610,22 +611,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;
}

4
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

8
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
}

8
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
}

2
src/Shaders/magnumShadersResourceImport.hpp

@ -28,7 +28,7 @@
#ifdef MAGNUM_BUILD_STATIC
#include <Utility/Resource.h>
#include <Utility/utilities.h>
#include <Utility/Macros.h>
static int magnumShadersResourceImport() {
CORRADE_RESOURCE_INITIALIZE(MagnumShaders_RCS)

2
src/Swizzle.h

@ -41,7 +41,7 @@ namespace Magnum {
@deprecated Use @ref Magnum::Math::swizzle() "Math::swizzle()" instead.
*/
#ifdef DOXYGEN_GENERATING_OUTPUT
template<char ...components, class T> constexpr typename Math::Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector);
template<char ...components, class T> constexpr CORRADE_DEPRECATED("use Math::swizzle() instead") typename Math::Implementation::TypeForSize<sizeof...(components), T>::Type swizzle(const T& vector);
#else
using Math::swizzle;
#endif

24
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>({&ImageTest::moveConstructor,
&ImageTest::moveAssignment,
&ImageTest::toReference});
&ImageTest::toReference,
&ImageTest::release});
}
void ImageTest::moveConstructor() {
@ -71,13 +73,31 @@ 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<const Image2D&, ImageReference2D>::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<const Image2D, ImageReference2D>::value));
CORRADE_VERIFY(!(std::is_convertible<const Image2D&&, ImageReference2D>::value));
}
}
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());
}
}}

8
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<Mesh::Primitive>("primitive"), Mesh::Primitive::LineStrip);
CORRADE_COMPARE(c.value<MeshPrimitive>("primitive"), MeshPrimitive::LineStrip);
}
void MeshTest::configurationIndexType() {

16
src/Text/AbstractFont.cpp

@ -24,8 +24,8 @@
#include "AbstractFont.h"
#include <fstream>
#include <Containers/Array.h>
#include <Utility/Directory.h>
#include <Utility/Unicode.h>
#include "Text/GlyphCache.h"
@ -86,22 +86,12 @@ std::pair<Float, Float> 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<unsigned char> data(std::size_t(in.tellg()));
/* Read data, close */
in.seekg(0, std::ios::beg);
in.read(reinterpret_cast<char*>(data.begin()), data.size());
in.close();
return doOpenSingleData(data, size);
return doOpenSingleData(Utility::Directory::read(filename), size);
}
void AbstractFont::close() {

45
src/Text/AbstractFontConverter.cpp

@ -25,9 +25,9 @@
#include "AbstractFontConverter.h"
#include <algorithm>
#include <fstream>
#include <Containers/Array.h>
#include <Utility/Assert.h>
#include <Utility/Directory.h>
#include <Utility/Unicode.h>
#include "Text/GlyphCache.h"
@ -108,18 +108,10 @@ bool AbstractFontConverter::doExportFontToFile(AbstractFont& font, GlyphCache& c
/* Export all data */
const auto data = doExportFontToData(font, cache, filename, characters);
for(auto it = data.begin(); it != data.end(); ++it) {
for(auto it = data.begin(); it != data.end(); ++it) if(!Utility::Directory::write(it->first, it->second)) {
const auto& d = *it;
/* 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<const char*>(d.second.begin()), d.second.size());
Error() << "Text::AbstractFontConverter::exportFontToFile(): cannot write to file" << d.first;
return false;
}
return true;
@ -180,18 +172,9 @@ bool AbstractFontConverter::doExportGlyphCacheToFile(GlyphCache& cache, const st
/* Export all data */
const auto data = doExportGlyphCacheToData(cache, filename);
for(auto it = data.begin(); it != data.end(); ++it) {
const auto& d = *it;
/* 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<const char*>(d.second.begin()), d.second.size());
for(auto it = data.begin(); it != data.end(); ++it) if(!Utility::Directory::write(it->first, it->second)) {
Error() << "Text::AbstractFontConverter::exportGlyphCacheToFile(): cannot write to file" << it->first;
return false;
}
return true;
@ -241,22 +224,12 @@ std::unique_ptr<GlyphCache> AbstractFontConverter::doImportGlyphCacheFromFile(co
"Text::AbstractFontConverter::importGlyphCacheFromFile(): not implemented", {});
/* 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 {};
}
/* Create array to hold file contents */
in.seekg(0, std::ios::end);
Containers::Array<unsigned char> data(std::size_t(in.tellg()));
/* Read data, close */
in.seekg(0, std::ios::beg);
in.read(reinterpret_cast<char*>(data.begin()), data.size());
in.close();
return doImportGlyphCacheFromSingleData(data);
return doImportGlyphCacheFromSingleData(Utility::Directory::read(filename));
}
#ifndef __MINGW32__

4
src/Text/Renderer.cpp

@ -215,7 +215,7 @@ std::tuple<Mesh, Range2D> 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);
@ -322,7 +322,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() {}

10
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

3
src/Text/fontconverter.cpp

@ -62,8 +62,7 @@ FontConverter::FontConverter(const Arguments& arguments): Platform::WindowlessAp
.setHelp("Converts font to raster one of given atlas size.")
.parse(arguments.argc, arguments.argv);
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
}
int FontConverter::exec() {

58
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

2
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 */

3
src/TextureTools/distancefieldconverter.cpp

@ -61,8 +61,7 @@ DistanceFieldConverter::DistanceFieldConverter(const Arguments& arguments): Wind
.setHelp("Converts black&white image to distance-field representation.")
.parse(arguments.argc, arguments.argv);
/* GCC 4.5 can't handle {} here (wtf) */
createContext(Configuration());
createContext();
}
int DistanceFieldConverter::exec() {

2
src/TextureTools/magnumTextureToolsResourceImport.hpp

@ -28,7 +28,7 @@
#ifdef MAGNUM_BUILD_STATIC
#include <Utility/Resource.h>
#include <Utility/utilities.h>
#include <Utility/Macros.h>
static int magnumTextureToolsResourceImport() {
CORRADE_RESOURCE_INITIALIZE(MagnumTextureTools_RCS)

9
src/Trade/AbstractImageConverter.cpp

@ -24,9 +24,9 @@
#include "AbstractImageConverter.h"
#include <fstream>
#include <Containers/Array.h>
#include <Utility/Assert.h>
#include <Utility/Directory.h>
namespace Magnum { namespace Trade {
@ -72,18 +72,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<const char*>(data.begin()), data.size());
return true;
}

16
src/Trade/AbstractImporter.cpp

@ -24,9 +24,9 @@
#include "AbstractImporter.h"
#include <fstream>
#include <Containers/Array.h>
#include <Utility/Assert.h>
#include <Utility/Directory.h>
#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<unsigned char> data(std::size_t(in.tellg()));
/* Read data, close */
in.seekg(0, std::ios::beg);
in.read(reinterpret_cast<char*>(data.begin()), data.size());
in.close();
doOpenData(data);
doOpenData(Utility::Directory::read(filename));
}
void AbstractImporter::close() {

57
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<UnsignedInt dimensions> class ImageData: public AbstractImage {
public:
@ -70,20 +70,39 @@ template<UnsignedInt dimensions> 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<dimensions>() const;
/** @brief Conversion to reference */
/*implicit*/ operator ImageReference<dimensions>()
#ifndef CORRADE_GCC47_COMPATIBILITY
const &;
#else
const;
#endif
#ifndef CORRADE_GCC47_COMPATIBILITY
/** @overload */
/*implicit*/ operator ImageReference<dimensions>() const && = delete;
#endif
/** @brief %Image size */
typename DimensionTraits<Dimensions, Int>::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<Dimensions, Int> _size;
unsigned char* _data;
@ -110,10 +129,24 @@ template<UnsignedInt dimensions> inline ImageData<dimensions>& ImageData<dimensi
return *this;
}
template<UnsignedInt dimensions> inline ImageData<dimensions>::operator ImageReference<dimensions>() const {
template<UnsignedInt dimensions> inline ImageData<dimensions>::operator ImageReference<dimensions>()
#ifndef CORRADE_GCC47_COMPATIBILITY
const &
#else
const
#endif
{
return ImageReference<dimensions>(AbstractImage::format(), AbstractImage::type(), _size, _data);
}
template<UnsignedInt dimensions> inline unsigned char* ImageData<dimensions>::release() {
/** @todo I need `std::exchange` NOW. */
unsigned char* const data = _data;
_size = {};
_data = nullptr;
return data;
}
}}
#endif

2
src/Trade/MeshData2D.cpp

@ -28,7 +28,7 @@
namespace Magnum { namespace Trade {
MeshData2D::MeshData2D(Mesh::Primitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector2>> positions, std::vector<std::vector<Vector2>> textureCoords2D): _primitive(primitive), _indices(std::move(indices)), _positions(std::move(positions)), _textureCoords2D(std::move(textureCoords2D)) {
MeshData2D::MeshData2D(MeshPrimitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector2>> positions, std::vector<std::vector<Vector2>> 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", );
}

12
src/Trade/MeshData2D.h

@ -28,9 +28,11 @@
* @brief Class Magnum::Trade::MeshData2D
*/
#include <string>
#include <vector>
#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<UnsignedInt> indices, std::vector<std::vector<Vector2>> positions, std::vector<std::vector<Vector2>> textureCoords2D);
explicit MeshData2D(MeshPrimitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector2>> positions, std::vector<std::vector<Vector2>> 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<Vector2>& textureCoords2D(UnsignedInt id) const; /**< @overload */
private:
Mesh::Primitive _primitive;
MeshPrimitive _primitive;
std::vector<UnsignedInt> _indices;
std::vector<std::vector<Vector2>> _positions;
std::vector<std::vector<Vector2>> _textureCoords2D;

2
src/Trade/MeshData3D.cpp

@ -28,7 +28,7 @@
namespace Magnum { namespace Trade {
MeshData3D::MeshData3D(Mesh::Primitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector3>> positions, std::vector<std::vector<Vector3>> normals, std::vector<std::vector<Vector2>> 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<UnsignedInt> indices, std::vector<std::vector<Vector3>> positions, std::vector<std::vector<Vector3>> normals, std::vector<std::vector<Vector2>> 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", );
}

12
src/Trade/MeshData3D.h

@ -28,9 +28,11 @@
* @brief Class Magnum::Trade::MeshData3D
*/
#include <string>
#include <vector>
#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<UnsignedInt> indices, std::vector<std::vector<Vector3>> positions, std::vector<std::vector<Vector3>> normals, std::vector<std::vector<Vector2>> textureCoords2D);
explicit MeshData3D(MeshPrimitive primitive, std::vector<UnsignedInt> indices, std::vector<std::vector<Vector3>> positions, std::vector<std::vector<Vector3>> normals, std::vector<std::vector<Vector2>> 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<Vector2>& textureCoords2D(UnsignedInt id) const; /**< @overload */
private:
Mesh::Primitive _primitive;
MeshPrimitive _primitive;
std::vector<UnsignedInt> _indices;
std::vector<std::vector<Vector3>> _positions;
std::vector<std::vector<Vector3>> _normals;

24
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>({&ImageDataTest::moveConstructor,
&ImageDataTest::moveAssignment,
&ImageDataTest::toReference});
&ImageDataTest::toReference,
&ImageDataTest::release});
}
void ImageDataTest::moveConstructor() {
@ -71,13 +73,31 @@ 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<const Trade::ImageData2D&, ImageReference2D>::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<const Trade::ImageData2D, ImageReference2D>::value));
CORRADE_VERIFY(!(std::is_convertible<const Trade::ImageData2D&&, ImageReference2D>::value));
}
}
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());
}
}}}

Loading…
Cancel
Save