diff --git a/doc/changelog.dox b/doc/changelog.dox index 5a06da54b..98d0fb02c 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -202,6 +202,8 @@ See also: - A new @ref developers page containing step-by-step checklists for maintainers and core developers +- The @ref Primitives namespace now has contains images visualizing how + each primitive looks - Compiling majority of code snippets to ensure they don't get out of sync with the code diff --git a/doc/generated/CMakeLists.txt b/doc/generated/CMakeLists.txt index 175afcaa5..21cb405c5 100644 --- a/doc/generated/CMakeLists.txt +++ b/doc/generated/CMakeLists.txt @@ -57,3 +57,12 @@ target_link_libraries(shaders Magnum::Primitives Magnum::Shaders Magnum::WindowlessApplication) + +add_executable(primitives primitives.cpp) +target_include_directories(primitives PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_link_libraries(primitives + Magnum::Magnum + Magnum::MeshTools + Magnum::Primitives + Magnum::Shaders + Magnum::WindowlessApplication) diff --git a/doc/generated/README.md b/doc/generated/README.md index 6b2fe1856..f8e235b64 100644 --- a/doc/generated/README.md +++ b/doc/generated/README.md @@ -12,6 +12,13 @@ Create build dir, point CMake to this directory and compile the executables: cmake ../doc/generated cmake --build . +### Primitive images + +Generated by the `primitives` executable. Run it in this directory, the output +is put into `doc/` directory. Apply `pngcrush` to them for smaller file sizes: + + for f in $(ls primitives-*.png); do pngcrush -ow $f; done + ### Shader images Generated by the `shaders` executable. Must be run in this directory, the diff --git a/doc/generated/primitives.cpp b/doc/generated/primitives.cpp new file mode 100644 index 000000000..0d16ac2b7 --- /dev/null +++ b/doc/generated/primitives.cpp @@ -0,0 +1,467 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include + +#ifdef CORRADE_TARGET_APPLE +#include +#elif defined(CORRADE_TARGET_UNIX) +#include +#elif defined(CORRADE_TARGET_WINDOWS) +#include +#else +#error no windowless application available on this platform +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "configure.h" + +using namespace Magnum; +using namespace Magnum::Math::Literals; + +struct PrimitiveVisualizer: Platform::WindowlessApplication { + explicit PrimitiveVisualizer(const Arguments& arguments): Platform::WindowlessApplication{arguments} {} + + int exec() override; + + std::pair axis2D(); + std::pair axis3D(); + + std::pair capsule2DWireframe(); + std::pair circle2DWireframe(); + std::pair crosshair2D(); + std::pair line2D(); + std::pair squareWireframe(); + + std::pair capsule3DWireframe(); + std::pair circle3DWireframe(); + std::pair crosshair3D(); + std::pair cubeWireframe(); + std::pair cylinderWireframe(); + std::pair line3D(); + std::pair planeWireframe(); + std::pair uvSphereWireframe(); + + std::pair circle2DSolid(); + std::pair squareSolid(); + + std::pair capsule3DSolid(); + std::pair circle3DSolid(); + std::pair cubeSolid(); + std::pair cylinderSolid(); + std::pair icosphereSolid(); + std::pair planeSolid(); + std::pair uvSphereSolid(); +}; + +namespace { + constexpr const Vector2i ImageSize{256}; + const auto BaseColor = 0x2f83cc_rgbf; + const auto OutlineColor = 0xdcdcdc_rgbf; + const auto Projection2D = Matrix3::projection({3.0f, 3.0f}); + const auto Projection3D = Matrix4::perspectiveProjection(35.0_degf, 1.0f, 0.001f, 100.0f); + const auto Transformation2D = Matrix3::rotation(13.2_degf); + const auto Transformation3D = Matrix4::translation(Vector3::zAxis(-6.0f))* + Matrix4::rotationY(-10.82_degf)* + Matrix4::rotationX(24.37_degf)* + Matrix4::rotationZ(18.3_degf); +} + +int PrimitiveVisualizer::exec() { + PluginManager::Manager converterManager{MAGNUM_PLUGINS_IMAGECONVERTER_DIR}; + std::unique_ptr converter = converterManager.loadAndInstantiate("PngImageConverter"); + if(!converter) { + Error() << "Cannot load image converter plugin"; + std::exit(1); + } + + Renderbuffer multisampleColor, multisampleDepth; + multisampleColor.setStorageMultisample(16, RenderbufferFormat::RGBA8, ImageSize); + multisampleDepth.setStorageMultisample(16, RenderbufferFormat::DepthComponent24, ImageSize); + + Framebuffer multisampleFramebuffer{{{}, ImageSize}}; + multisampleFramebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, multisampleColor) + .attachRenderbuffer(Framebuffer::BufferAttachment::Depth, multisampleDepth) + .bind(); + CORRADE_INTERNAL_ASSERT(multisampleFramebuffer.checkStatus(FramebufferTarget::Draw) == Framebuffer::Status::Complete); + + Renderbuffer color; + color.setStorage(RenderbufferFormat::RGBA8, ImageSize); + Framebuffer framebuffer{{{}, ImageSize}}; + framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color); + + /* Cheating a bit and enabling only face culling instead of depth test in + order to draw the wireframe over. I couldn't get polygon offset to work + on the first try so I gave up. This will of course break with things + like torus later. */ + Renderer::enable(Renderer::Feature::FaceCulling); + Renderer::enable(Renderer::Feature::Blending); + Renderer::setBlendFunction(Renderer::BlendFunction::One, Renderer::BlendFunction::One); + Renderer::setClearColor(0x000000_rgbaf); + Renderer::setLineWidth(1.5f); + + { + Shaders::VertexColor2D shader; + shader.setTransformationProjectionMatrix(Projection2D*Transformation2D); + + for(auto fun: {&PrimitiveVisualizer::axis2D}) { + multisampleFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + std::string filename; + Containers::Optional data; + std::tie(data, filename) = (this->*fun)(); + + /* TODO: use MeshTools::compile() once it can handle colors */ + Buffer vertices, indices; + vertices.setData(MeshTools::interleave(data->positions(0), data->colors(0)), BufferUsage::StaticDraw); + indices.setData(data->indices(), BufferUsage::StaticDraw); + Mesh mesh; + mesh.addVertexBuffer(vertices, 0, Shaders::VertexColor2D::Position{}, Shaders::VertexColor2D::Color{Shaders::VertexColor2D::Color::Components::Four}) + .setIndexBuffer(indices, 0, Mesh::IndexType::UnsignedInt) + .setCount(data->indices().size()) + .setPrimitive(data->primitive()); + + mesh.draw(shader); + + AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), FramebufferBlit::Color); + Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}); + converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + } + } + + { + Shaders::VertexColor3D shader; + shader.setTransformationProjectionMatrix(Projection3D*Transformation3D); + + for(auto fun: {&PrimitiveVisualizer::axis3D}) { + multisampleFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + std::string filename; + Containers::Optional data; + std::tie(data, filename) = (this->*fun)(); + + /* TODO: use MeshTools::compile() once it can handle colors */ + Buffer vertices, indices; + vertices.setData(MeshTools::interleave(data->positions(0), data->colors(0)), BufferUsage::StaticDraw); + indices.setData(data->indices(), BufferUsage::StaticDraw); + Mesh mesh; + mesh.addVertexBuffer(vertices, 0, Shaders::VertexColor3D::Position{}, Shaders::VertexColor3D::Color{Shaders::VertexColor3D::Color::Components::Four}) + .setIndexBuffer(indices, 0, Mesh::IndexType::UnsignedInt) + .setCount(data->indices().size()) + .setPrimitive(data->primitive()); + + mesh.draw(shader); + + AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), FramebufferBlit::Color); + Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}); + converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + } + } + + { + Shaders::Flat2D shader; + shader.setColor(OutlineColor) + .setTransformationProjectionMatrix(Projection2D*Transformation2D); + + for(auto fun: {&PrimitiveVisualizer::capsule2DWireframe, + &PrimitiveVisualizer::circle2DWireframe, + &PrimitiveVisualizer::crosshair2D, + &PrimitiveVisualizer::line2D, + &PrimitiveVisualizer::squareWireframe}) + { + multisampleFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + std::string filename; + Containers::Optional data; + std::tie(data, filename) = (this->*fun)(); + + std::unique_ptr vertices, indices; + Mesh mesh{NoCreate}; + std::tie(mesh, vertices, indices) = MeshTools::compile(*data, BufferUsage::StaticDraw); + + mesh.draw(shader); + + AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), FramebufferBlit::Color); + Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}); + converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + } + } + + { + Shaders::Flat3D shader; + shader.setColor(OutlineColor) + .setTransformationProjectionMatrix(Projection3D*Transformation3D); + + for(auto fun: {&PrimitiveVisualizer::capsule3DWireframe, + &PrimitiveVisualizer::circle3DWireframe, + &PrimitiveVisualizer::crosshair3D, + &PrimitiveVisualizer::cubeWireframe, + &PrimitiveVisualizer::cylinderWireframe, + &PrimitiveVisualizer::line3D, + &PrimitiveVisualizer::planeWireframe, + &PrimitiveVisualizer::uvSphereWireframe}) + { + multisampleFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + std::string filename; + Containers::Optional data; + std::tie(data, filename) = (this->*fun)(); + + std::unique_ptr vertices, indices; + Mesh mesh{NoCreate}; + std::tie(mesh, vertices, indices) = MeshTools::compile(*data, BufferUsage::StaticDraw); + + mesh.draw(shader); + + AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), FramebufferBlit::Color); + Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}); + converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + } + } + + { + const Matrix3 projection = Projection2D*Transformation2D; + Shaders::MeshVisualizer shader{Shaders::MeshVisualizer::Flag::Wireframe}; + shader.setColor(BaseColor) + .setWireframeColor(OutlineColor) + .setViewportSize(Vector2{ImageSize}) + .setTransformationProjectionMatrix(Matrix4{ + {projection[0], 0.0f}, + {projection[1], 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {{projection[2].xy(), 0.0f}, 1.0f}}); + + for(auto fun: {&PrimitiveVisualizer::circle2DSolid, + &PrimitiveVisualizer::squareSolid}) + { + multisampleFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + std::string filename; + Containers::Optional data; + std::tie(data, filename) = (this->*fun)(); + + /* TODO: use MeshTools::compile() and MeshVisualizer2D once it exists */ + Buffer vertices; + vertices.setData(data->positions(0), BufferUsage::StaticDraw); + Mesh mesh; + mesh.addVertexBuffer(vertices, 0, Shaders::MeshVisualizer::Position{Shaders::MeshVisualizer::Position::Components::Two}) + .setCount(data->positions(0).size()) + .setPrimitive(data->primitive()); + + mesh.draw(shader); + + AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), FramebufferBlit::Color); + Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}); + converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + } + } + + { + Shaders::Phong phong; + phong.setAmbientColor(0x22272e_rgbf) + .setDiffuseColor(BaseColor) + .setSpecularColor(0x000000_rgbf) + .setLightPosition({5.0f, 5.0f, 7.0f}) + .setProjectionMatrix(Projection3D) + .setTransformationMatrix(Transformation3D) + .setNormalMatrix(Transformation3D.rotationScaling()); + + Shaders::MeshVisualizer wireframe{Shaders::MeshVisualizer::Flag::Wireframe}; + wireframe.setColor(0x000000_rgbaf) + .setWireframeColor(OutlineColor) + .setViewportSize(Vector2{ImageSize}) + .setTransformationProjectionMatrix(Projection3D*Transformation3D); + + for(auto fun: {&PrimitiveVisualizer::capsule3DSolid, + &PrimitiveVisualizer::circle3DSolid, + &PrimitiveVisualizer::cubeSolid, + &PrimitiveVisualizer::cylinderSolid, + &PrimitiveVisualizer::icosphereSolid, + &PrimitiveVisualizer::planeSolid, + &PrimitiveVisualizer::uvSphereSolid}) + { + multisampleFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + std::string filename; + Containers::Optional data; + std::tie(data, filename) = (this->*fun)(); + + std::unique_ptr vertices, indices; + Mesh mesh{NoCreate}; + std::tie(mesh, vertices, indices) = MeshTools::compile(*data, BufferUsage::StaticDraw); + + mesh.draw(phong); + mesh.draw(wireframe); + + AbstractFramebuffer::blit(multisampleFramebuffer, framebuffer, framebuffer.viewport(), FramebufferBlit::Color); + Image2D result = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}); + converter->exportToFile(result, Utility::Directory::join("../", "primitives-" + filename)); + } + } + + return 0; +} + +std::pair PrimitiveVisualizer::axis2D() { + return {Primitives::axis2D(), "axis2d.png"}; +} + +std::pair PrimitiveVisualizer::axis3D() { + return {Primitives::axis3D(), "axis3d.png"}; +} + +std::pair PrimitiveVisualizer::capsule2DWireframe() { + auto capsule = Primitives::capsule2DWireframe(8, 1, 0.75f); + MeshTools::transformPointsInPlace(Matrix3::scaling(Vector2{0.75f}), capsule.positions(0)); + return {std::move(capsule), "capsule2dwireframe.png"}; +} + +std::pair PrimitiveVisualizer::circle2DWireframe() { + return {Primitives::circle2DWireframe(32), "circle2dwireframe.png"}; +} + +std::pair PrimitiveVisualizer::crosshair2D() { + return {Primitives::crosshair2D(), "crosshair2d.png"}; +} + +std::pair PrimitiveVisualizer::line2D() { + auto line = Primitives::line2D(); + MeshTools::transformPointsInPlace(Matrix3::translation(Vector2::xAxis(-1.0f))*Matrix3::scaling(Vector2::xScale(2.0f)), line.positions(0)); + return {std::move(line), "line2d.png"}; +} + +std::pair PrimitiveVisualizer::squareWireframe() { + return {Primitives::squareWireframe(), "squarewireframe.png"}; +} + +std::pair PrimitiveVisualizer::capsule3DWireframe() { + auto capsule = Primitives::capsule3DWireframe(8, 1, 16, 1.0f); + MeshTools::transformPointsInPlace(Matrix4::scaling(Vector3{0.75f}), capsule.positions(0)); + return {std::move(capsule), "capsule3dwireframe.png"}; +} + +std::pair PrimitiveVisualizer::circle3DWireframe() { + return {Primitives::circle3DWireframe(32), "circle3dwireframe.png"}; +} + +std::pair PrimitiveVisualizer::crosshair3D() { + return {Primitives::crosshair3D(), "crosshair3d.png"}; +} + +std::pair PrimitiveVisualizer::cubeWireframe() { + return {Primitives::cubeWireframe(), "cubewireframe.png"}; +} + +std::pair PrimitiveVisualizer::cylinderWireframe() { + return {Primitives::cylinderWireframe(1, 32, 1.0f), "cylinderwireframe.png"}; +} + +std::pair PrimitiveVisualizer::line3D() { + auto line = Primitives::line3D(); + MeshTools::transformPointsInPlace(Matrix4::translation(Vector3::xAxis(-1.0f))*Matrix4::scaling(Vector3::xScale(2.0f)), line.positions(0)); + return {std::move(line), "line3d.png"}; +} + +std::pair PrimitiveVisualizer::planeWireframe() { + return {Primitives::planeWireframe(), "planewireframe.png"}; +} + +std::pair PrimitiveVisualizer::uvSphereWireframe() { + return {Primitives::uvSphereWireframe(16, 32), "uvspherewireframe.png"}; +} + +std::pair PrimitiveVisualizer::circle2DSolid() { + return {Primitives::circle2DSolid(16), "circle2dsolid.png"}; +} + +std::pair PrimitiveVisualizer::squareSolid() { + return {Primitives::squareSolid(), "squaresolid.png"}; +} + +std::pair PrimitiveVisualizer::capsule3DSolid() { + auto capsule = Primitives::capsule3DSolid(4, 1, 12, 0.75f); + MeshTools::transformPointsInPlace(Matrix4::scaling(Vector3{0.75f}), capsule.positions(0)); + return {std::move(capsule), "capsule3dsolid.png"}; +} + +std::pair PrimitiveVisualizer::circle3DSolid() { + return {Primitives::circle3DSolid(16), "circle3dsolid.png"}; +} + +std::pair PrimitiveVisualizer::cubeSolid() { + return {Primitives::cubeSolid(), "cubesolid.png"}; +} + +std::pair PrimitiveVisualizer::cylinderSolid() { + return {Primitives::cylinderSolid(1, 12, 1.0f, Primitives::CylinderFlag::CapEnds), "cylindersolid.png"}; +} + +std::pair PrimitiveVisualizer::icosphereSolid() { + return {Primitives::icosphereSolid(1), "icospheresolid.png"}; +} + +std::pair PrimitiveVisualizer::planeSolid() { + return {Primitives::planeSolid(), "planesolid.png"}; +} + +std::pair PrimitiveVisualizer::uvSphereSolid() { + return {Primitives::uvSphereSolid(8, 16), "uvspheresolid.png"}; +} + +MAGNUM_WINDOWLESSAPPLICATION_MAIN(PrimitiveVisualizer) diff --git a/doc/primitives-axis2d.png b/doc/primitives-axis2d.png new file mode 100644 index 000000000..dc1c80088 Binary files /dev/null and b/doc/primitives-axis2d.png differ diff --git a/doc/primitives-axis3d.png b/doc/primitives-axis3d.png new file mode 100644 index 000000000..398a21ce5 Binary files /dev/null and b/doc/primitives-axis3d.png differ diff --git a/doc/primitives-capsule2dwireframe.png b/doc/primitives-capsule2dwireframe.png new file mode 100644 index 000000000..ae2ea351c Binary files /dev/null and b/doc/primitives-capsule2dwireframe.png differ diff --git a/doc/primitives-capsule3dsolid.png b/doc/primitives-capsule3dsolid.png new file mode 100644 index 000000000..c8ef87289 Binary files /dev/null and b/doc/primitives-capsule3dsolid.png differ diff --git a/doc/primitives-capsule3dwireframe.png b/doc/primitives-capsule3dwireframe.png new file mode 100644 index 000000000..1e7eaa401 Binary files /dev/null and b/doc/primitives-capsule3dwireframe.png differ diff --git a/doc/primitives-circle2dsolid.png b/doc/primitives-circle2dsolid.png new file mode 100644 index 000000000..1a76f6ab0 Binary files /dev/null and b/doc/primitives-circle2dsolid.png differ diff --git a/doc/primitives-circle2dwireframe.png b/doc/primitives-circle2dwireframe.png new file mode 100644 index 000000000..b049fabc6 Binary files /dev/null and b/doc/primitives-circle2dwireframe.png differ diff --git a/doc/primitives-circle3dsolid.png b/doc/primitives-circle3dsolid.png new file mode 100644 index 000000000..a8772ce0a Binary files /dev/null and b/doc/primitives-circle3dsolid.png differ diff --git a/doc/primitives-circle3dwireframe.png b/doc/primitives-circle3dwireframe.png new file mode 100644 index 000000000..46283737e Binary files /dev/null and b/doc/primitives-circle3dwireframe.png differ diff --git a/doc/primitives-crosshair2d.png b/doc/primitives-crosshair2d.png new file mode 100644 index 000000000..1dd240a24 Binary files /dev/null and b/doc/primitives-crosshair2d.png differ diff --git a/doc/primitives-crosshair3d.png b/doc/primitives-crosshair3d.png new file mode 100644 index 000000000..a44400a75 Binary files /dev/null and b/doc/primitives-crosshair3d.png differ diff --git a/doc/primitives-cubesolid.png b/doc/primitives-cubesolid.png new file mode 100644 index 000000000..ad86392e5 Binary files /dev/null and b/doc/primitives-cubesolid.png differ diff --git a/doc/primitives-cubewireframe.png b/doc/primitives-cubewireframe.png new file mode 100644 index 000000000..9bf6262e8 Binary files /dev/null and b/doc/primitives-cubewireframe.png differ diff --git a/doc/primitives-cylindersolid.png b/doc/primitives-cylindersolid.png new file mode 100644 index 000000000..0190e5e31 Binary files /dev/null and b/doc/primitives-cylindersolid.png differ diff --git a/doc/primitives-cylinderwireframe.png b/doc/primitives-cylinderwireframe.png new file mode 100644 index 000000000..9afe77f60 Binary files /dev/null and b/doc/primitives-cylinderwireframe.png differ diff --git a/doc/primitives-icospheresolid.png b/doc/primitives-icospheresolid.png new file mode 100644 index 000000000..f0865a6d1 Binary files /dev/null and b/doc/primitives-icospheresolid.png differ diff --git a/doc/primitives-line2d.png b/doc/primitives-line2d.png new file mode 100644 index 000000000..57b080f2b Binary files /dev/null and b/doc/primitives-line2d.png differ diff --git a/doc/primitives-line3d.png b/doc/primitives-line3d.png new file mode 100644 index 000000000..c8c8c5d2b Binary files /dev/null and b/doc/primitives-line3d.png differ diff --git a/doc/primitives-planesolid.png b/doc/primitives-planesolid.png new file mode 100644 index 000000000..4e6833939 Binary files /dev/null and b/doc/primitives-planesolid.png differ diff --git a/doc/primitives-planewireframe.png b/doc/primitives-planewireframe.png new file mode 100644 index 000000000..89cf7c455 Binary files /dev/null and b/doc/primitives-planewireframe.png differ diff --git a/doc/primitives-squaresolid.png b/doc/primitives-squaresolid.png new file mode 100644 index 000000000..a73bad260 Binary files /dev/null and b/doc/primitives-squaresolid.png differ diff --git a/doc/primitives-squarewireframe.png b/doc/primitives-squarewireframe.png new file mode 100644 index 000000000..4da8a18d4 Binary files /dev/null and b/doc/primitives-squarewireframe.png differ diff --git a/doc/primitives-uvspheresolid.png b/doc/primitives-uvspheresolid.png new file mode 100644 index 000000000..2b6e73c24 Binary files /dev/null and b/doc/primitives-uvspheresolid.png differ diff --git a/doc/primitives-uvspherewireframe.png b/doc/primitives-uvspherewireframe.png new file mode 100644 index 000000000..672253b89 Binary files /dev/null and b/doc/primitives-uvspherewireframe.png differ diff --git a/src/Magnum/Primitives/Axis.h b/src/Magnum/Primitives/Axis.h index d54b32c31..8a4ee24ac 100644 --- a/src/Magnum/Primitives/Axis.h +++ b/src/Magnum/Primitives/Axis.h @@ -39,6 +39,9 @@ namespace Magnum { namespace Primitives { Two color-coded arrows for visualizing orientation (XY is RG). Indexed @ref MeshPrimitive::Lines with vertex colors. + +@image html primitives-axis2d.png + @see @ref axis3D(), @ref crosshair2D(), @ref line2D() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D axis2D(); @@ -48,6 +51,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D axis2D(); Three color-coded arrows for visualizing orientation (XYZ is RGB). Indexed @ref MeshPrimitive::Lines with vertex colors. + +@image html primitives-axis3d.png + @see @ref axis2D(), @ref crosshair3D(), @ref line3D() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D axis3D(); diff --git a/src/Magnum/Primitives/Capsule.h b/src/Magnum/Primitives/Capsule.h index 1dc569d13..0b650d934 100644 --- a/src/Magnum/Primitives/Capsule.h +++ b/src/Magnum/Primitives/Capsule.h @@ -48,6 +48,9 @@ namespace Magnum { namespace Primitives { Cylinder of radius @cpp 1.0f @ce along Y axis with hemispheres instead of caps. Indexed @ref MeshPrimitive::Lines. + +@image html primitives-capsule2dwireframe.png + @see @ref capsule3DSolid(), @ref capsule3DWireframe(), @ref circle2DWireframe(), @ref squareWireframe() */ @@ -92,6 +95,8 @@ 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. +@image html primitives-capsule3dsolid.png + The capsule is by default created with radius set to @f$ 1.0 @f$. In order to get radius @f$ r @f$, length @f$ l @f$ and preserve correct normals, set @p halfLength to @f$ 0.5 \frac{l}{r} @f$ and then scale all @@ -113,6 +118,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D capsule3DSolid(UnsignedInt hemisphere Cylinder of radius @cpp 1.0f @ce along Y axis with hemispheres instead of caps. Indexed @ref MeshPrimitive::Lines. + +@image html primitives-capsule3dwireframe.png + @see @ref capsule2DWireframe(), @ref capsule3DSolid(), @ref cylinderSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D capsule3DWireframe(UnsignedInt hemisphereRings, UnsignedInt cylinderRings, UnsignedInt segments, Float halfLength); diff --git a/src/Magnum/Primitives/Circle.h b/src/Magnum/Primitives/Circle.h index b94b75c6a..7b124e40c 100644 --- a/src/Magnum/Primitives/Circle.h +++ b/src/Magnum/Primitives/Circle.h @@ -43,6 +43,9 @@ namespace Magnum { namespace Primitives { @param segments Number of segments. Must be greater or equal to @cpp 3 @ce. Circle with radius @cpp 1.0f @ce. Non-indexed @ref MeshPrimitive::TriangleFan. + +@image html primitives-circle2dsolid.png + @see @ref circle2DWireframe(), @ref circle3DSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D circle2DSolid(UnsignedInt segments); @@ -52,6 +55,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D circle2DSolid(UnsignedInt segments); @param segments Number of segments. Must be greater or equal to @cpp 3 @ce. Circle with radius @cpp 1.0f @ce. Non-indexed @ref MeshPrimitive::LineLoop. + +@image html primitives-circle2dwireframe.png + @see @ref circle2DSolid(), @ref circle3DWireframe() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D circle2DWireframe(UnsignedInt segments); @@ -80,6 +86,9 @@ struct MAGNUM_PRIMITIVES_EXPORT Circle { Circle on the XY plane with radius @cpp 1.0f @ce. Non-indexed @ref MeshPrimitive::TriangleFan with normals in positive Z direction. + +@image html primitives-circle3dsolid.png + @see @ref circle3DWireframe(), @ref circle2DSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D circle3DSolid(UnsignedInt segments); @@ -90,6 +99,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D circle3DSolid(UnsignedInt segments); Circle on the XY plane with radius @cpp 1.0f @ce. Non-indexed @ref MeshPrimitive::LineLoop. + +@image html primitives-circle3dwireframe.png + @see @ref circle2DSolid(), @ref circle3DWireframe() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D circle3DWireframe(UnsignedInt segments); diff --git a/src/Magnum/Primitives/Crosshair.h b/src/Magnum/Primitives/Crosshair.h index c7d505ff2..5640a0f3e 100644 --- a/src/Magnum/Primitives/Crosshair.h +++ b/src/Magnum/Primitives/Crosshair.h @@ -42,6 +42,9 @@ namespace Magnum { namespace Primitives { @brief 2D crosshair 2x2 crosshair (two crossed lines), non-indexed @ref MeshPrimitive::Lines. + +@image html primitives-crosshair2d.png + @see @ref crosshair3D(), @ref axis2D(), @ref line2D() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D crosshair2D(); @@ -63,6 +66,9 @@ struct MAGNUM_PRIMITIVES_EXPORT Crosshair2D { @brief 3D crosshair 2x2x2 crosshair (three crossed lines), non-indexed @ref MeshPrimitive::Lines. + +@image html primitives-crosshair3d.png + @see @ref crosshair2D(), @ref axis2D(), @ref line3D() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D crosshair3D(); diff --git a/src/Magnum/Primitives/Cube.h b/src/Magnum/Primitives/Cube.h index 676b55f9e..618d160a2 100644 --- a/src/Magnum/Primitives/Cube.h +++ b/src/Magnum/Primitives/Cube.h @@ -42,6 +42,9 @@ namespace Magnum { namespace Primitives { @brief Solid 3D cube Indexed @ref MeshPrimitive::Triangles with flat normals. + +@image html primitives-cubesolid.png + @see @ref cubeSolidStrip(), @ref cubeWireframe() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D cubeSolid(); @@ -51,6 +54,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D cubeSolid(); Non-indexed @ref MeshPrimitive::TriangleStrip. Just positions, no normals or anything else. + +@image html primitives-cubesolid.png + @see @ref cubeSolid(), @ref cubeWireframe() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D cubeSolidStrip(); @@ -59,6 +65,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D cubeSolidStrip(); @brief Wireframe 3D cube Indexed @ref MeshPrimitive::Lines. + +@image html primitives-cubewireframe.png + @see @ref cubeSolid(), @ref cubeSolidStrip() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D cubeWireframe(); diff --git a/src/Magnum/Primitives/Cylinder.h b/src/Magnum/Primitives/Cylinder.h index 8e6578faf..b466125e7 100644 --- a/src/Magnum/Primitives/Cylinder.h +++ b/src/Magnum/Primitives/Cylinder.h @@ -70,6 +70,7 @@ Cylinder along Y axis of radius @cpp 1.0f @ce. Indexed optional capped ends. If texture coordinates are generated, vertices of one segment are duplicated for texture wrapping. +@image html primitives-cylindersolid.png The cylinder is by default created with radius set to @f$ 1.0 @f$. In order to get radius @f$ r @f$, length @f$ l @f$ and preserve correct normals, set @@ -90,6 +91,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D cylinderSolid(UnsignedInt rings, Unsi Cylinder along Y axis of radius @cpp 1.0f @ce. Indexed @ref MeshPrimitive::Lines. + +@image html primitives-cylinderwireframe.png + @see @ref cylinderSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D cylinderWireframe(UnsignedInt rings, UnsignedInt segments, Float halfLength); diff --git a/src/Magnum/Primitives/Icosphere.h b/src/Magnum/Primitives/Icosphere.h index df96855cd..8559446e2 100644 --- a/src/Magnum/Primitives/Icosphere.h +++ b/src/Magnum/Primitives/Icosphere.h @@ -44,6 +44,9 @@ namespace Magnum { namespace Primitives { Sphere with radius @cpp 1.0f @ce. Indexed @ref MeshPrimitive::Triangles with normals. + +@image html primitives-icospheresolid.png + @see @ref uvSphereSolid(), @ref uvSphereWireframe() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D icosphereSolid(UnsignedInt subdivisions); diff --git a/src/Magnum/Primitives/Line.h b/src/Magnum/Primitives/Line.h index 4f573ba91..5e86a373e 100644 --- a/src/Magnum/Primitives/Line.h +++ b/src/Magnum/Primitives/Line.h @@ -43,6 +43,9 @@ namespace Magnum { namespace Primitives { Unit-size line in direction of positive X axis. Non-indexed @ref MeshPrimitive::Lines. + +@image html primitives-line2d.png + @see @ref line3D(), @ref axis2D(), @ref crosshair2D() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D line2D(); @@ -52,6 +55,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D line2D(); Unit-size line in direction of positive X axis. Non-indexed @ref MeshPrimitive::Lines. + +@image html primitives-line3d.png + @see @ref line2D(), @ref axis3D(), @ref crosshair3D() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D line3D(); diff --git a/src/Magnum/Primitives/Plane.h b/src/Magnum/Primitives/Plane.h index 558235c7d..9a433588d 100644 --- a/src/Magnum/Primitives/Plane.h +++ b/src/Magnum/Primitives/Plane.h @@ -55,6 +55,9 @@ enum class PlaneTextureCoords: UnsignedByte { 2x2 plane. Non-indexed @ref MeshPrimitive::TriangleStrip on the XY plane with normals in positive Z direction. + +@image html primitives-planesolid.png + @see @ref planeWireframe(), @ref squareSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D planeSolid(PlaneTextureCoords textureCoords = PlaneTextureCoords::DontGenerate); @@ -63,6 +66,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D planeSolid(PlaneTextureCoords texture @brief Wireframe 3D plane 2x2 plane. Non-indexed @ref MeshPrimitive::LineLoop on the XY plane. + +@image html primitives-planewireframe.png + @see @ref planeSolid(), @ref squareWireframe() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D planeWireframe(); diff --git a/src/Magnum/Primitives/Square.h b/src/Magnum/Primitives/Square.h index 6ec853b37..043d2f72e 100644 --- a/src/Magnum/Primitives/Square.h +++ b/src/Magnum/Primitives/Square.h @@ -54,6 +54,9 @@ enum class SquareTextureCoords: UnsignedByte { @brief Solid 2D square 2x2 square. Non-indexed @ref MeshPrimitive::TriangleStrip. + +@image html primitives-squaresolid.png + @see @ref squareWireframe(), @ref planeSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D squareSolid(SquareTextureCoords textureCoords = SquareTextureCoords::DontGenerate); @@ -62,6 +65,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D squareSolid(SquareTextureCoords textu @brief Wireframe 2D square 2x2 square. Non-indexed @ref MeshPrimitive::LineLoop. + +@image html primitives-squarewireframe.png + @see @ref squareSolid(), @ref planeWireframe() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData2D squareWireframe(); diff --git a/src/Magnum/Primitives/UVSphere.h b/src/Magnum/Primitives/UVSphere.h index 8e88ef15b..4f65d09c9 100644 --- a/src/Magnum/Primitives/UVSphere.h +++ b/src/Magnum/Primitives/UVSphere.h @@ -59,6 +59,9 @@ enum class UVSphereTextureCoords: UnsignedByte { Sphere with radius @cpp 1.0f @ce. 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. + +@image html primitives-uvspheresolid.png + @see @ref icosphereSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D uvSphereSolid(UnsignedInt rings, UnsignedInt segments, UVSphereTextureCoords textureCoords = UVSphereTextureCoords::DontGenerate); @@ -71,6 +74,9 @@ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D uvSphereSolid(UnsignedInt rings, Unsi @cpp 4 @ce and multiple of @cpp 4 @ce. Sphere with radius @cpp 1.0f @ce. Indexed @ref MeshPrimitive::Lines. + +@image html primitives-uvspherewireframe.png + @see @ref icosphereSolid() */ MAGNUM_PRIMITIVES_EXPORT Trade::MeshData3D uvSphereWireframe(UnsignedInt rings, UnsignedInt segments);