diff --git a/doc/opengl-wrapping.dox b/doc/opengl-wrapping.dox index 05313b413..14960e0b2 100644 --- a/doc/opengl-wrapping.dox +++ b/doc/opengl-wrapping.dox @@ -58,7 +58,7 @@ equivalent to the moved-from state. It is useful in case you need to construct the object before creating context (such as class members) or if you know you would overwrite it later with another object: -@snippet opengl-wrapping.cpp nocreate +@snippet Magnum.cpp opengl-wrapping-nocreate If you need to preserve the underlying OpenGL object after destruction, you can call @cpp release() @ce. It returns ID of the underlying object, the instance @@ -68,7 +68,7 @@ ID of the underlying without releasing it using `id()`). It is also possible to do the opposite --- wrapping existing OpenGL object ID into Magnum object instance using @cpp wrap() @ce. -@snippet opengl-wrapping.cpp transfer +@snippet Magnum.cpp opengl-wrapping-transfer The @cpp NoCreate @ce constructor, @cpp wrap() @ce and @cpp release() @ce functions are available for all OpenGL classes except @ref Shader, where @@ -87,7 +87,7 @@ tracks OpenGL state such as currently bound objects, activated renderer features etc. When combining Magnum with third-party code, the internal state tracker may get confused and you need to reset it using @ref Context::resetState(): -@snippet opengl-wrapping.cpp state +@snippet Magnum.cpp opengl-wrapping-state Note that by design it's not possible to reset all state touched by Magnum to previous values --- it would involve impractically large amount of queries and @@ -113,7 +113,7 @@ GL version/extension is required. The information is also aggregated on @ref opengl-required-extensions documentation page. Use @ref Context::isVersionSupported() or @ref Context::isExtensionSupported(): -@snippet opengl-wrapping.cpp extensions +@snippet Magnum.cpp opengl-wrapping-extensions @attention Using API that requires OpenGL version or extension that is not provided by the driver results in undefined behavior --- the best you can @@ -135,7 +135,7 @@ required extensions are not available, @ref Texture::setStorage() emulation on platforms that don't support it etc. The goal is to abstract away the (mostly unimportant) differences for easier porting. -@snippet opengl-wrapping.cpp dsa +@snippet Magnum.cpp opengl-wrapping-dsa */ } diff --git a/doc/snippets/CMakeLists.txt b/doc/snippets/CMakeLists.txt index 56651bb94..22eaa9216 100644 --- a/doc/snippets/CMakeLists.txt +++ b/doc/snippets/CMakeLists.txt @@ -27,8 +27,14 @@ set_directory_properties(PROPERTIES CORRADE_CXX_STANDARD 11 CORRADE_USE_PEDANTIC_FLAGS ON) +# Emscripten needs special flag to use WebGL 2 +if(CORRADE_TARGET_EMSCRIPTEN AND NOT TARGET_GLES2) + # TODO: give me INTERFACE_LINK_OPTIONS or something, please + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_WEBGL2=1") +endif() + add_library(snippets STATIC - opengl-wrapping.cpp) + Magnum.cpp) target_link_libraries(snippets PRIVATE Magnum) set_target_properties(snippets PROPERTIES FOLDER "Magnum/doc/snippets") @@ -41,7 +47,7 @@ if(WITH_DEBUGTOOLS AND Corrade_TestSuite_FOUND AND NOT CORRADE_TARGET_IOS) ${CMAKE_CURRENT_BINARY_DIR}/configure.h) # CompareImage documentation snippet. I need it executable so I can - # copy&paste the output to the documentation. Also mot using + # copy&paste the output to the documentation. Also not using # corrade_add_test() because it shouldn't be run as part of CTest as it # purposedly fails. add_executable(debugtools-compareimage debugtools-compareimage.cpp) @@ -56,7 +62,9 @@ if(WITH_SDL2APPLICATION) target_link_libraries(getting-started PRIVATE MagnumSdl2Application) target_link_libraries(getting-started-blue PRIVATE MagnumSdl2Application) - add_library(snippets-MagnumPlatform STATIC MagnumPlatform.cpp) + add_library(snippets-MagnumPlatform STATIC + MagnumPlatform.cpp + Magnum-framebuffer.cpp) target_link_libraries(snippets-MagnumPlatform PRIVATE MagnumSdl2Application) set_target_properties( diff --git a/doc/snippets/Magnum-framebuffer.cpp b/doc/snippets/Magnum-framebuffer.cpp new file mode 100644 index 000000000..89ef0e452 --- /dev/null +++ b/doc/snippets/Magnum-framebuffer.cpp @@ -0,0 +1,68 @@ +/* + 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 "Magnum/DefaultFramebuffer.h" +#include "Magnum/Framebuffer.h" +#include "Magnum/Platform/Sdl2Application.h" + +using namespace Magnum; + +struct A: Platform::Sdl2Application { +/* [DefaultFramebuffer-usage-viewport] */ +void viewportEvent(const Vector2i& size) override { + defaultFramebuffer.setViewport({{}, size}); + + // ... +} +/* [DefaultFramebuffer-usage-viewport] */ + +/* [DefaultFramebuffer-usage-clear] */ +void drawEvent() override { + defaultFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); + + // ... +} +/* [DefaultFramebuffer-usage-clear] */ +}; + +struct B: Platform::Sdl2Application { + +Framebuffer framebuffer; + +/* [Framebuffer-usage-draw] */ +void drawEvent() override { + defaultFramebuffer.clear(FramebufferClear::Color); + framebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth|FramebufferClear::Stencil); + + framebuffer.bind(); + // ... + + defaultFramebuffer.bind(); + // ... + + swapBuffers(); +} +/* [Framebuffer-usage-draw] */ +}; diff --git a/doc/snippets/Magnum.cpp b/doc/snippets/Magnum.cpp new file mode 100644 index 000000000..ea88d21db --- /dev/null +++ b/doc/snippets/Magnum.cpp @@ -0,0 +1,1337 @@ +/* + 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 "Magnum/AbstractShaderProgram.h" +#include "Magnum/Buffer.h" +#include "Magnum/Context.h" +#include "Magnum/CubeMapTexture.h" +#include "Magnum/DefaultFramebuffer.h" +#include "Magnum/Extensions.h" +#include "Magnum/Framebuffer.h" +#include "Magnum/Image.h" +#include "Magnum/Mesh.h" +#include "Magnum/PixelFormat.h" +#include "Magnum/Renderer.h" +#include "Magnum/Renderbuffer.h" +#include "Magnum/Shader.h" +#include "Magnum/Texture.h" +#include "Magnum/TextureFormat.h" +#include "Magnum/Version.h" +#include "Magnum/Math/Matrix4.h" +#include "Magnum/MeshTools/Interleave.h" +#include "Magnum/MeshTools/CompressIndices.h" +#include "Magnum/Primitives/Cube.h" +#include "Magnum/Primitives/Plane.h" +#include "Magnum/Shaders/Phong.h" +#include "Magnum/Trade/MeshData3D.h" + +#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) +#include "Magnum/SampleQuery.h" +#endif + +#ifndef MAGNUM_TARGET_WEBGL +#include "Magnum/DebugOutput.h" +#ifndef CORRADE_TARGET_ANDROID +#include "Magnum/OpenGLTester.h" +#endif +#include "Magnum/TimeQuery.h" +#endif + +#ifndef MAGNUM_TARGET_GLES2 +#include "Magnum/BufferImage.h" +#include "Magnum/PrimitiveQuery.h" +#include "Magnum/TextureArray.h" +#include "Magnum/TransformFeedback.h" +#endif + +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) +#include "Magnum/BufferTexture.h" +#include "Magnum/BufferTextureFormat.h" +#include "Magnum/CubeMapTextureArray.h" +#include "Magnum/MultisampleTexture.h" +#endif + +#ifndef MAGNUM_TARGET_GLES +#include "Magnum/RectangleTexture.h" +#endif + +using namespace Magnum; +using namespace Magnum::Math::Literals; + +int main() { + +{ +auto importSomeMesh() -> std::tuple; +/* [opengl-wrapping-nocreate] */ +Mesh mesh{NoCreate}; +Buffer vertices{NoCreate}, indices{NoCreate}; +std::tie(mesh, vertices, indices) = importSomeMesh(); +/* [opengl-wrapping-nocreate] */ +} + +{ +struct Foo { + void setSomeBuffer(GLuint) {} + GLuint someBuffer() { return {}; } +} externalLib; +char someData[1]; +/* [opengl-wrapping-transfer] */ +/* Transferring the instance to external library */ +{ + Buffer buffer; + buffer.setData(someData, BufferUsage::StaticDraw); + GLuint id = buffer.release(); + externalLib.setSomeBuffer(id); /* The library is responsible for deletion */ +} + +/* Acquiring an instance from external library */ +{ + GLuint id = externalLib.someBuffer(); + Buffer buffer = Buffer::wrap(id, ObjectFlag::DeleteOnDestruction); + /* The buffer instance now handles deletion */ +} +/* [opengl-wrapping-transfer] */ +} + +#ifndef MAGNUM_TARGET_GLES +{ +struct: AbstractShaderProgram {} someShader; +/* [opengl-wrapping-state] */ +Buffer buffer; +Mesh mesh; +// ... +mesh.draw(someShader); + +{ + /* Entering a section with 3rd-party OpenGL code -- clean up all state that + could cause accidental modifications of our objects from outside */ + Context::current().resetState(Context::State::EnterExternal); + + /* Raw OpenGL calls */ + glBindBuffer(GL_ARRAY_BUFFER, buffer.id()); + glBufferStorage(GL_ARRAY_BUFFER, 32768, nullptr, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT); + // ... + + /* Exiting a section with 3rd-party OpenGL code -- reset our state tracker */ + Context::current().resetState(Context::State::ExitExternal); +} + +/* Use the buffer through Magnum again */ +auto data = buffer.map(0, 32768, Buffer::MapFlag::Read|Buffer::MapFlag::Write); +// ... +/* [opengl-wrapping-state] */ +static_cast(data); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +{ +/* [opengl-wrapping-extensions] */ +TextureFormat format; +if(Context::current().isExtensionSupported()) + format = TextureFormat::DepthComponent32F; +else + format = TextureFormat::DepthComponent24; +/* [opengl-wrapping-extensions] */ +static_cast(format); +} +#endif + +#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) +{ +/* [opengl-wrapping-dsa] */ +Texture2D texture; + +/* - on OpenGL 4.5+/ARB_direct_state_access this calls glTextureStorage2D() + - if EXT_direct_state_access is available, calls glTextureStorage2DEXT() + - on OpenGL 4.2+/ARB_texture_storage and OpenGL ES 3.0+ calls glTexStorage2D() + - on OpenGL ES 2.0 with EXT_texture_storage calls glTexStorage2DEXT() + - otherwise emulated using a sequence of four glTexImage2D() calls */ +texture.setStorage(4, TextureFormat::RGBA8, {256, 256}); +/* [opengl-wrapping-dsa] */ +} +#endif + +#ifndef MAGNUM_TARGET_GLES +struct MyShader: AbstractShaderProgram { +/* [AbstractShaderProgram-input-attributes] */ +typedef Attribute<0, Vector3> Position; +typedef Attribute<1, Vector3> Normal; +typedef Attribute<2, Vector2> TextureCoordinates; +/* [AbstractShaderProgram-input-attributes] */ + +/* [AbstractShaderProgram-output-attributes] */ +enum: UnsignedInt { + ColorOutput = 0, + NormalOutput = 1 +}; +/* [AbstractShaderProgram-output-attributes] */ + +/* [AbstractShaderProgram-constructor] */ +explicit MyShader() { + /* Load shader sources */ + Shader vert{Version::GL430, Shader::Type::Vertex}; + Shader frag{Version::GL430, Shader::Type::Fragment}; + vert.addFile("MyShader.vert"); + frag.addFile("MyShader.frag"); + + /* Invoke parallel compilation for best performance */ + CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({vert, frag})); + + /* Attach the shaders */ + attachShaders({vert, frag}); + + /* Link the program together */ + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); +} +/* [AbstractShaderProgram-constructor] */ + +/* [AbstractShaderProgram-uniforms] */ +MyShader& setProjectionMatrix(const Matrix4& matrix) { + setUniform(0, matrix); + return *this; +} +MyShader& setTransformationMatrix(const Matrix4& matrix) { + setUniform(1, matrix); + return *this; +} +MyShader& setNormalMatrix(const Matrix3x3& matrix) { + setUniform(2, matrix); + return *this; +} +/* [AbstractShaderProgram-uniforms] */ + +/* [AbstractShaderProgram-textures] */ +MyShader& bindDiffuseTexture(Texture2D& texture) { + texture.bind(0); + return *this; +} +MyShader& bindSpecularTexture(Texture2D& texture) { + texture.bind(1); + return *this; +} +/* [AbstractShaderProgram-textures] */ + +/* [AbstractShaderProgram-xfb] */ +MyShader& setTransformFeedback(TransformFeedback& feedback, Buffer& positions, Buffer& data) { + feedback.attachBuffers(0, {&positions, &data}); + return *this; +} +MyShader& setTransformFeedback(TransformFeedback& feedback, Int totalCount, Buffer& positions, GLintptr positionsOffset, Buffer& data, GLintptr dataOffset) { + feedback.attachBuffers(0, { + std::make_tuple(&positions, positionsOffset, totalCount*sizeof(Vector3)), + std::make_tuple(&data, dataOffset, totalCount*sizeof(Vector2ui)) + }); + return *this; +} +/* [AbstractShaderProgram-xfb] */ + +void foo() { +/* [AbstractShaderProgram-binding] */ +// Shaders attached... + +bindAttributeLocation(Position::Location, "position"); +bindAttributeLocation(Normal::Location, "normal"); +bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates"); + +bindFragmentDataLocationIndexed(ColorOutput, 0, "color"); +bindFragmentDataLocationIndexed(NormalOutput, 1, "normal"); + +// Link... +/* [AbstractShaderProgram-binding] */ + +/* [AbstractShaderProgram-uniform-location] */ +Int projectionMatrixUniform = uniformLocation("projectionMatrix"); +Int transformationMatrixUniform = uniformLocation("transformationMatrix"); +Int normalMatrixUniform = uniformLocation("normalMatrix"); +/* [AbstractShaderProgram-uniform-location] */ +static_cast(projectionMatrixUniform); +static_cast(transformationMatrixUniform); +static_cast(normalMatrixUniform); + +/* [AbstractShaderProgram-uniform-block-binding] */ +setUniformBlockBinding(uniformBlockIndex("matrices"), 0); +setUniformBlockBinding(uniformBlockIndex("material"), 1); +/* [AbstractShaderProgram-uniform-block-binding] */ + +/* [AbstractShaderProgram-texture-uniforms] */ +setUniform(uniformLocation("diffuseTexture"), 0); +setUniform(uniformLocation("specularTexture"), 1); +/* [AbstractShaderProgram-texture-uniforms] */ + +/* [AbstractShaderProgram-xfb-outputs] */ +setTransformFeedbackOutputs({ + // Buffer 0 + "position", "gl_SkipComponents1", "normal", "gl_SkipComponents1", + // Buffer 1 + "gl_NextBuffer", "velocity" + }, TransformFeedbackBufferMode::InterleavedAttributes); +/* [AbstractShaderProgram-xfb-outputs] */ +} +}; +#endif + +#ifndef MAGNUM_TARGET_GLES +{ +MyShader shader; +Mesh mesh; +Matrix4 transformation, projection; +Texture2D diffuseTexture, specularTexture; +/* [AbstractShaderProgram-rendering] */ +shader.setTransformationMatrix(transformation) + .setProjectionMatrix(projection) + .bindDiffuseTexture(diffuseTexture) + .bindSpecularTexture(specularTexture); + +mesh.draw(shader); +/* [AbstractShaderProgram-rendering] */ +} +#endif + +{ +Framebuffer framebuffer{{}}; +/* [AbstractFramebuffer-read1] */ +Image2D image = framebuffer.read(framebuffer.viewport(), + {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [AbstractFramebuffer-read1] */ +} + +#ifndef MAGNUM_TARGET_GLES2 +{ +Framebuffer framebuffer{{}}; +/* [AbstractFramebuffer-read2] */ +BufferImage2D image = framebuffer.read(framebuffer.viewport(), + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [AbstractFramebuffer-read2] */ +} +#endif + +{ +Buffer buffer; +/* [Buffer-setdata] */ +Containers::ArrayView data; +buffer.setData(data, BufferUsage::StaticDraw); +/* [Buffer-setdata] */ +} + +{ +Buffer buffer; +/* [Buffer-setdata-stl] */ +std::vector data; +buffer.setData(data, BufferUsage::StaticDraw); +/* [Buffer-setdata-stl] */ + +/* [Buffer-setdata-allocate] */ +buffer.setData({nullptr, 200*sizeof(Vector3)}, BufferUsage::StaticDraw); +/* [Buffer-setdata-allocate] */ +} + +#ifndef MAGNUM_TARGET_WEBGL +{ +Buffer buffer; +/* [Buffer-map] */ +Containers::ArrayView data = Containers::arrayCast(buffer.map(0, + 200*sizeof(Vector3), Buffer::MapFlag::Write|Buffer::MapFlag::InvalidateBuffer)); +CORRADE_INTERNAL_ASSERT(data); +for(Vector3& d: data) + d = {/*...*/}; +CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap()); +/* [Buffer-map] */ +} + +{ +Buffer buffer; +/* [Buffer-flush] */ +Containers::ArrayView data = Containers::arrayCast(buffer.map(0, + 200*sizeof(Vector3), Buffer::MapFlag::Write|Buffer::MapFlag::FlushExplicit)); +CORRADE_INTERNAL_ASSERT(data); +for(std::size_t i: {7, 27, 56, 128}) { + data[i] = {/*...*/}; + buffer.flushMappedRange(i*sizeof(Vector3), sizeof(Vector3)); +} +CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap()); +/* [Buffer-flush] */ +} +#endif + +{ +/* [Buffer-webgl] */ +Buffer vertices{Buffer::TargetHint::Array}; +Buffer indices{Buffer::TargetHint::ElementArray}; +/* [Buffer-webgl] */ +} + +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) +{ +/* [BufferTexture-usage] */ +Buffer buffer; +BufferTexture texture; +texture.setBuffer(BufferTextureFormat::RGB32F, buffer); + +Vector3 data[200]{ + // ... +}; +buffer.setData(data, BufferUsage::StaticDraw); +/* [BufferTexture-usage] */ +} +#endif + +#ifndef MAGNUM_TARGET_GLES +{ +/* [Context-supportedVersion] */ +Version v1 = Context::current().isVersionSupported(Version::GL330) ? + Version::GL330 : Version::GL210; +Version v2 = Context::current().supportedVersion({Version::GL330, Version::GL210}); +/* [Context-supportedVersion] */ +static_cast(v1); +static_cast(v2); + +/* [Context-isExtensionSupported] */ +if(Context::current().isExtensionSupported()) { + // draw fancy detailed model +} else { + // texture fallback +} +/* [Context-isExtensionSupported] */ + +/* [Context-isExtensionSupported-version] */ +const Version version = Context::current().supportedVersion({ + Version::GL320, Version::GL300, Version::GL210}); +if(Context::current().isExtensionSupported(version)) { + // Called only if ARB_explicit_attrib_location is supported + // *and* version is higher than GL 3.1 +} +/* [Context-isExtensionSupported-version] */ + +/* [Context-MAGNUM_ASSERT_VERSION_SUPPORTED] */ +MAGNUM_ASSERT_VERSION_SUPPORTED(Version::GL330); +/* [Context-MAGNUM_ASSERT_VERSION_SUPPORTED] */ + +/* [Context-MAGNUM_ASSERT_EXTENSION_SUPPORTED] */ +MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::geometry_shader4); +/* [Context-MAGNUM_ASSERT_EXTENSION_SUPPORTED] */ +} +#endif + +#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) +{ +char data[1]{}; +ImageView2D negativeX(PixelFormat::RGBA, PixelType::UnsignedByte, {256, 256}, data); +/* [CubeMapTexture-usage] */ +ImageView2D positiveX(PixelFormat::RGBA, PixelType::UnsignedByte, {256, 256}, data); +// ... + +CubeMapTexture texture; +texture.setMagnificationFilter(Sampler::Filter::Linear) + // ... + .setStorage(Math::log2(256)+1, TextureFormat::RGBA8, {256, 256}) + .setSubImage(CubeMapCoordinate::PositiveX, 0, {}, positiveX) + .setSubImage(CubeMapCoordinate::NegativeX, 0, {}, negativeX) + // ... +/* [CubeMapTexture-usage] */ + ; +} +#endif + +#ifndef MAGNUM_TARGET_GLES +{ +CubeMapTexture texture; +/* [CubeMapTexture-image1] */ +Image3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [CubeMapTexture-image1] */ +} + +{ +CubeMapTexture texture; +/* [CubeMapTexture-image2] */ +BufferImage3D image = texture.image(0, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [CubeMapTexture-image2] */ +} + +{ +CubeMapTexture texture; +/* [CubeMapTexture-compressedImage1] */ +CompressedImage3D image = texture.compressedImage(0, {}); +/* [CubeMapTexture-compressedImage1] */ +} + +{ +CubeMapTexture texture; +/* [CubeMapTexture-compressedImage2] */ +CompressedBufferImage3D image = texture.compressedImage(0, {}, + BufferUsage::StaticRead); +/* [CubeMapTexture-compressedImage2] */ +} + +{ +CubeMapTexture texture; +/* [CubeMapTexture-image3] */ +Image2D image = texture.image(CubeMapCoordinate::PositiveX, 0, + {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [CubeMapTexture-image3] */ +} + +{ +CubeMapTexture texture; +/* [CubeMapTexture-image4] */ +BufferImage2D image = texture.image(CubeMapCoordinate::PositiveX, 0, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [CubeMapTexture-image4] */ +} + +{ +CubeMapTexture texture; +/* [CubeMapTexture-compressedImage3] */ +CompressedImage2D image = texture.compressedImage(CubeMapCoordinate::PositiveX, + 0, {}); +/* [CubeMapTexture-compressedImage3] */ +} + +{ +CubeMapTexture texture; +/* [CubeMapTexture-compressedImage4] */ +CompressedBufferImage2D image = texture.compressedImage(CubeMapCoordinate::PositiveX, + 0, {}, BufferUsage::StaticRead); +/* [CubeMapTexture-compressedImage4] */ +} + +{ +CubeMapTexture texture; +Range3Di range; +/* [CubeMapTexture-subImage1] */ +Image3D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [CubeMapTexture-subImage1] */ +} + +{ +CubeMapTexture texture; +Range3Di range; +/* [CubeMapTexture-subImage2] */ +BufferImage3D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [CubeMapTexture-subImage2] */ +} + +{ +CubeMapTexture texture; +Range3Di range; +/* [CubeMapTexture-compressedSubImage1] */ +CompressedImage3D image = texture.compressedSubImage(0, range, {}); +/* [CubeMapTexture-compressedSubImage1] */ +} + +{ +CubeMapTexture texture; +Range3Di range; +/* [CubeMapTexture-compressedSubImage2] */ +CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, + BufferUsage::StaticRead); +/* [CubeMapTexture-compressedSubImage2] */ +} +#endif + +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) +{ +char data[1]{}; +ImageView3D imageNegativeX(PixelFormat::RGBA, PixelType::UnsignedByte, {64, 64, 1}, data); +ImageView3D imagePositiveY(PixelFormat::RGBA, PixelType::UnsignedByte, {64, 64, 1}, data); +/* [CubeMapTextureArray-usage] */ +CubeMapTextureArray texture; +texture.setMagnificationFilter(Sampler::Filter::Linear) + // ... + .setStorage(Math::log2(64)+1, TextureFormat::RGBA8, {64, 64, 24}); + +for(std::size_t i = 0; i != 4; i += 6) { + ImageView3D imagePositiveX(PixelFormat::RGBA, PixelType::UnsignedByte, {64, 64, 1}, data); + // ... + texture.setSubImage(0, Vector3i::zAxis(i+0), imagePositiveX); + texture.setSubImage(0, Vector3i::zAxis(i+1), imageNegativeX); + texture.setSubImage(0, Vector3i::zAxis(i+2), imagePositiveY); + // ... +} + +texture.generateMipmap(); +/* [CubeMapTextureArray-usage] */ +} + +#ifndef MAGNUM_TARGET_GLES +{ +CubeMapTextureArray texture; +/* [CubeMapTextureArray-image1] */ +Image3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [CubeMapTextureArray-image1] */ +} + +{ +CubeMapTextureArray texture; +/* [CubeMapTextureArray-image2] */ +BufferImage3D image = texture.image(0, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [CubeMapTextureArray-image2] */ +} + +{ +CubeMapTextureArray texture; +/* [CubeMapTextureArray-compressedImage1] */ +CompressedImage3D image = texture.compressedImage(0, {}); +/* [CubeMapTextureArray-compressedImage1] */ +} + +{ +CubeMapTextureArray texture; +/* [CubeMapTextureArray-compressedImage2] */ +CompressedBufferImage3D image = texture.compressedImage(0, {}, BufferUsage::StaticRead); +/* [CubeMapTextureArray-compressedImage2] */ +} + +{ +CubeMapTextureArray texture; +Range3Di range; +/* [CubeMapTextureArray-subImage1] */ +Image3D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [CubeMapTextureArray-subImage1] */ +} + +{ +CubeMapTextureArray texture; +Range3Di range; +/* [CubeMapTextureArray-subImage2] */ +BufferImage3D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [CubeMapTextureArray-subImage2] */ +} + +{ +CubeMapTextureArray texture; +Range3Di range; +/* [CubeMapTextureArray-compressedSubImage1] */ +CompressedImage3D image = texture.compressedSubImage(0, range, {}); +/* [CubeMapTextureArray-compressedSubImage1] */ +} + +{ +CubeMapTextureArray texture; +Range3Di range; +/* [CubeMapTextureArray-compressedSubImage2] */ +CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, + BufferUsage::StaticRead); +/* [CubeMapTextureArray-compressedSubImage2] */ +} +#endif +#endif + +#ifndef MAGNUM_TARGET_WEBGL +{ +Mesh mesh; +struct: AbstractShaderProgram {} shader; +/* [DebugOutput-usage] */ +Renderer::enable(Renderer::Feature::DebugOutput); +Renderer::enable(Renderer::Feature::DebugOutputSynchronous); +DebugOutput::setDefaultCallback(); + +/* Disable rather spammy "Buffer detailed info" debug messages on NVidia drivers */ +DebugOutput::setEnabled(DebugOutput::Source::Api, DebugOutput::Type::Other, {131185}, false); + +{ + DebugGroup group{DebugGroup::Source::Application, 42, "Scene rendering"}; + + DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, + 1337, DebugOutput::Severity::Notification, "Rendering transparent mesh"); + + Renderer::enable(Renderer::Feature::Blending); + mesh.draw(shader); + Renderer::disable(Renderer::Feature::Blending); + + // ... +} +/* [DebugOutput-usage] */ +} + +{ +/* [DebugOutput-setDefaultCallback] */ +DebugMessage::insert(DebugMessage::Source::Application, + DebugMessage::Type::Marker, 1337, DebugOutput::Severity::Notification, + "Hello from OpenGL command stream!"); +/* [DebugOutput-setDefaultCallback] */ +} + +{ +/* [DebugMessage-usage] */ +DebugMessage::insert(DebugMessage::Source::Application, + DebugMessage::Type::Marker, 1337, DebugOutput::Severity::Notification, + "Hello from OpenGL command stream!"); +/* [DebugMessage-usage] */ +} + +{ +Mesh mesh; +struct: AbstractShaderProgram {} shader; +/* [DebugGroup-usage1] */ +{ + /* Push debug group */ + DebugGroup group{DebugGroup::Source::Application, 42, "Scene rendering"}; + + Renderer::enable(Renderer::Feature::Blending); + mesh.draw(shader); + Renderer::disable(Renderer::Feature::Blending); + + /* The debug group is popped automatically at the end of the scope */ +} +/* [DebugGroup-usage1] */ +} + +{ +Mesh mesh; +struct: AbstractShaderProgram {} shader; +/* [DebugGroup-usage2] */ +DebugGroup group; + +group.push(DebugGroup::Source::Application, 42, "Scene rendering"); + +Renderer::enable(Renderer::Feature::Blending); +mesh.draw(shader); +Renderer::disable(Renderer::Feature::Blending); + +group.pop(); +/* [DebugGroup-usage2] */ +} +#endif + +{ +struct MyShader { + enum: UnsignedInt { + ColorOutput = 0, + NormalOutput = 1 + }; +}; +/* [DefaultFramebuffer-usage-map] */ +defaultFramebuffer.mapForDraw({ + {MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::Back}, + {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}}); +/* [DefaultFramebuffer-usage-map] */ +} + +#ifndef MAGNUM_TARGET_GLES2 +{ +/* [Framebuffer-usage-attach] */ +Framebuffer framebuffer{defaultFramebuffer.viewport()}; +Texture2D color, normal; +Renderbuffer depthStencil; + +// configure the textures and allocate texture memory... + +framebuffer.attachTexture(Framebuffer::ColorAttachment{0}, color, 0); +framebuffer.attachTexture(Framebuffer::ColorAttachment{1}, normal, 0); +framebuffer.attachRenderbuffer(Framebuffer::BufferAttachment::DepthStencil, depthStencil); +/* [Framebuffer-usage-attach] */ +} +#endif + +{ +struct MyShader { + enum: UnsignedInt { + ColorOutput = 0, + NormalOutput = 1 + }; +}; +Framebuffer framebuffer{{}}; +/* [Framebuffer-usage-map] */ +framebuffer.mapForDraw({{MyShader::ColorOutput, Framebuffer::ColorAttachment(0)}, + {MyShader::NormalOutput, Framebuffer::ColorAttachment(1)}}); +/* [Framebuffer-usage-map] */ +} + +{ +/* [Mesh-nonindexed] */ +/* Custom shader, needing only position data */ +class MyShader: public AbstractShaderProgram { + public: + typedef Attribute<0, Vector3> Position; + + // ... +}; + +/* Fill vertex buffer with position data */ +Vector3 positions[30]{ + // ... +}; +Buffer vertexBuffer; +vertexBuffer.setData(positions, BufferUsage::StaticDraw); + +/* Configure the mesh, add vertex buffer */ +Mesh mesh; +mesh.setPrimitive(MeshPrimitive::Triangles) + .addVertexBuffer(vertexBuffer, 0, MyShader::Position{}) + .setCount(30); +/* [Mesh-nonindexed] */ +} + +{ +/* [Mesh-interleaved] */ +/* Non-indexed primitive with positions and normals */ +Trade::MeshData3D plane = Primitives::Plane::solid(); + +/* Fill a vertex buffer with interleaved position and normal data */ +Buffer buffer; +buffer.setData(MeshTools::interleave(plane.positions(0), plane.normals(0)), BufferUsage::StaticDraw); + +/* Configure the mesh, add the vertex buffer */ +Mesh mesh; +mesh.setPrimitive(plane.primitive()) + .setCount(plane.positions(0).size()) + .addVertexBuffer(buffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}); +/* [Mesh-interleaved] */ +} + +{ +/* [Mesh-indexed] */ +/* Custom shader */ +class MyShader: public AbstractShaderProgram { + public: + typedef Attribute<0, Vector3> Position; + + // ... +}; + +/* Fill vertex buffer with position data */ +Vector3 positions[240]{ + // ... +}; +Buffer vertexBuffer; +vertexBuffer.setData(positions, BufferUsage::StaticDraw); + +/* Fill index buffer with index data */ +UnsignedByte indices[75]{ + // ... +}; +Buffer indexBuffer; +indexBuffer.setData(indices, BufferUsage::StaticDraw); + +/* Configure the mesh, add both vertex and index buffer */ +Mesh mesh; +mesh.setPrimitive(MeshPrimitive::Triangles) + .setCount(75) + .addVertexBuffer(vertexBuffer, 0, MyShader::Position{}) + .setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229); +/* [Mesh-indexed] */ +} + +{ +/* [Mesh-indexed-tools] */ +// Indexed primitive +Trade::MeshData3D cube = Primitives::Cube::solid(); + +// Fill vertex buffer with interleaved position and normal data +Buffer vertexBuffer; +vertexBuffer.setData(MeshTools::interleave(cube.positions(0), cube.normals(0)), BufferUsage::StaticDraw); + +// Compress index data +Containers::Array indexData; +Mesh::IndexType indexType; +UnsignedInt indexStart, indexEnd; +std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(cube.indices()); + +// Fill index buffer +Buffer indexBuffer; +indexBuffer.setData(indexData, BufferUsage::StaticDraw); + +// Configure the mesh, add both vertex and index buffer +Mesh mesh; +mesh.setPrimitive(cube.primitive()) + .setCount(cube.indices().size()) + .addVertexBuffer(vertexBuffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}) + .setIndexBuffer(indexBuffer, 0, indexType, indexStart, indexEnd); +/* [Mesh-indexed-tools] */ +} + +#ifndef MAGNUM_TARGET_GLES +{ +/* [Mesh-formats] */ +// Custom shader with colors specified as four floating-point values +class MyShader: public AbstractShaderProgram { + public: + typedef Attribute<0, Vector3> Position; + typedef Attribute<1, Color4> Color; + + // ... +}; + +/* Initial mesh configuration */ +Mesh mesh; +mesh.setPrimitive(MeshPrimitive::Triangles) + .setCount(30); + +/* Fill position buffer with positions specified as two-component XY (i.e., + no Z component, which is meant to be always 0) */ +Vector2 positions[30]{ + // ... +}; +Buffer positionBuffer; +positionBuffer.setData(positions, BufferUsage::StaticDraw); + +/* Specify layout of positions buffer -- only two components, unspecified Z + component will be automatically set to 0 */ +mesh.addVertexBuffer(positionBuffer, 0, + MyShader::Position{MyShader::Position::Components::Two}); + +/* Fill color buffer with colors specified as four-byte BGRA (i.e., directly + from a TGA file) */ +UnsignedByte colors[4*30]{ + // ... +}; +Buffer colorBuffer; +colorBuffer.setData(colors, BufferUsage::StaticDraw); + +/* Specify color buffer layout -- BGRA, each component unsigned byte and we + want to normalize them from [0, 255] to [0.0f, 1.0f] */ +mesh.addVertexBuffer(colorBuffer, 0, MyShader::Color{ + MyShader::Color::Components::BGRA, + MyShader::Color::DataType::UnsignedByte, + MyShader::Color::DataOption::Normalized}); +/* [Mesh-formats] */ +} +#endif + +{ +Mesh mesh; +Buffer colorBuffer; +/* [Mesh-dynamic] */ +mesh.addVertexBuffer(colorBuffer, 0, 4, DynamicAttribute{ + DynamicAttribute::Kind::GenericNormalized, 3, + DynamicAttribute::Components::Three, + DynamicAttribute::DataType::UnsignedByte}); +/* [Mesh-dynamic] */ +} + +{ +/* [Mesh-addVertexBuffer1] */ +Buffer buffer; +Mesh mesh; +mesh.addVertexBuffer(buffer, 76, /* initial array offset */ + 4, /* skip vertex weight (Float) */ + Shaders::Phong::Position(), /* vertex position */ + 8, /* skip texture coordinates (Vector2) */ + Shaders::Phong::Normal()); /* vertex normal */ +/* [Mesh-addVertexBuffer1] */ + +/* [Mesh-addVertexBuffer2] */ +mesh.addVertexBuffer(buffer, 76, 4, Shaders::Phong::Position{}, 20) + .addVertexBuffer(buffer, 76, 24, Shaders::Phong::Normal{}, 0); +/* [Mesh-addVertexBuffer2] */ + +/* [Mesh-addVertexBuffer3] */ +Int vertexCount = 352; +mesh.addVertexBuffer(buffer, 76 + 4*vertexCount, Shaders::Phong::Position{}) + .addVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::Phong::Normal{}); +/* [Mesh-addVertexBuffer3] */ +} + +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) +{ +/* [MultisampleTexture-usage] */ +MultisampleTexture2D texture; +texture.setStorage(16, TextureFormat::RGBA8, {1024, 1024}); +/* [MultisampleTexture-usage] */ +} +#endif + +#if !defined(MAGNUM_TARGET_WEBGL) && !defined(CORRADE_TARGET_ANDROID) +struct A: TestSuite::Tester { +void foo() { +/* [OpenGLTester-MAGNUM_VERIFY_NO_ERROR] */ +CORRADE_COMPARE(Magnum::Renderer::error(), Magnum::Renderer::Error::NoError); +/* [OpenGLTester-MAGNUM_VERIFY_NO_ERROR] */ +} +}; +#endif + +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) +{ +/* [PrimitiveQuery-usage] */ +PrimitiveQuery q{PrimitiveQuery::Target::PrimitivesGenerated}; + +q.begin(); +// rendering... +q.end(); + +if(!q.resultAvailable()) { + // do some work until to give OpenGL some time... +} + +// ...or block until the result is available +UnsignedInt primitiveCount = q.result(); +/* [PrimitiveQuery-usage] */ +static_cast(primitiveCount); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +{ +char data[1]{}; +/* [RectangleTexture-usage] */ +ImageView2D image{PixelFormat::RGBA, PixelType::UnsignedByte, {526, 137}, data}; + +RectangleTexture texture; +texture.setMagnificationFilter(Sampler::Filter::Linear) + .setMinificationFilter(Sampler::Filter::Linear) + .setWrapping(Sampler::Wrapping::ClampToEdge) + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setStorage(TextureFormat::RGBA8, {526, 137}) + .setSubImage({}, image); +/* [RectangleTexture-usage] */ +} + +{ +RectangleTexture texture; +/* [RectangleTexture-image1] */ +Image2D image = texture.image({PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [RectangleTexture-image1] */ +} + +{ +RectangleTexture texture; +/* [RectangleTexture-image2] */ +BufferImage2D image = texture.image( + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [RectangleTexture-image2] */ +} + +{ +RectangleTexture texture; +/* [RectangleTexture-compressedImage1] */ +CompressedImage2D image = texture.compressedImage({}); +/* [RectangleTexture-compressedImage1] */ +} + +{ +RectangleTexture texture; +/* [RectangleTexture-compressedImage2] */ +CompressedBufferImage2D image = texture.compressedImage({}, + BufferUsage::StaticRead); +/* [RectangleTexture-compressedImage2] */ +} + +{ +RectangleTexture texture; +Range2Di range; +/* [RectangleTexture-subImage1] */ +Image2D image = texture.subImage(range, + {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [RectangleTexture-subImage1] */ +} + +{ +RectangleTexture texture; +Range2Di range; +/* [RectangleTexture-subImage2] */ +BufferImage2D image = texture.subImage(range, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [RectangleTexture-subImage2] */ +} + +{ +RectangleTexture texture; +Range2Di range; +/* [RectangleTexture-compressedSubImage1] */ +CompressedImage2D image = texture.compressedSubImage(range, {}); +/* [RectangleTexture-compressedSubImage1] */ +} + +{ +RectangleTexture texture; +Range2Di range; +/* [RectangleTexture-compressedSubImage2] */ +CompressedBufferImage2D image = texture.compressedSubImage(range, {}, + BufferUsage::StaticRead); +/* [RectangleTexture-compressedSubImage2] */ +} +#endif + +#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) +{ +/* [SampleQuery-usage] */ +SampleQuery q{SampleQuery::Target::AnySamplesPassed}; + +q.begin(); +/* Render simplified object to test whether it is visible at all */ +// ... +q.end(); + +/* Render full version of the object only if it is visible */ +if(q.result()) { + // ... +} +/* [SampleQuery-usage] */ +} + +#ifndef MAGNUM_TARGET_GLES +{ +/* [SampleQuery-conditional-render] */ +SampleQuery q{SampleQuery::Target::AnySamplesPassed}; + +q.begin(); +/* Render simplified object to test whether it is visible at all */ +// ... +q.end(); + +q.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait); +/* Render full version of the object only if the query returns nonzero result */ +// ... +q.endConditionalRender(); +/* [SampleQuery-conditional-render] */ +} +#endif +#endif + +#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL)) +{ +char data[1]{}; +/* [Texture-usage] */ +ImageView2D image(PixelFormat::RGBA, PixelType::UnsignedByte, {4096, 4096}, data); + +Texture2D texture; +texture.setMagnificationFilter(Sampler::Filter::Linear) + .setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) + .setWrapping(Sampler::Wrapping::ClampToEdge) + .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) + .setStorage(Math::log2(4096)+1, TextureFormat::RGBA8, {4096, 4096}) + .setSubImage(0, {}, image) + .generateMipmap(); +/* [Texture-usage] */ +} +#endif + +#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL) +{ +Texture2D texture; +/* [Texture-setSwizzle] */ +texture.setSwizzle<'b', 'g', 'r', '0'>(); +/* [Texture-setSwizzle] */ +} +#endif + +#ifndef MAGNUM_TARGET_GLES +{ +Texture2D texture; +/* [Texture-image1] */ +Image2D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [Texture-image1] */ +} + +{ +Texture2D texture; +/* [Texture-image2] */ +BufferImage2D image = texture.image(0, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [Texture-image2] */ +} + +{ +Texture2D texture; +/* [Texture-compressedImage1] */ +CompressedImage2D image = texture.compressedImage(0, {}); +/* [Texture-compressedImage1] */ +} + +{ +Texture2D texture; +/* [Texture-compressedImage2] */ +CompressedBufferImage2D image = texture.compressedImage(0, {}, + BufferUsage::StaticRead); +/* [Texture-compressedImage2] */ +} + +{ +Texture2D texture; +Range2Di range; +/* [Texture-subImage1] */ +Image2D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [Texture-subImage1] */ +} + +{ +Texture2D texture; +Range2Di range; +/* [Texture-subImage2] */ +BufferImage2D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [Texture-subImage2] */ +} + +{ +Texture2D texture; +Range2Di range; +/* [Texture-compressedSubImage1] */ +CompressedImage2D image = texture.compressedSubImage(0, range, {}); +/* [Texture-compressedSubImage1] */ +} + +{ +Texture2D texture; +Range2Di range; +/* [Texture-compressedSubImage2] */ +CompressedBufferImage2D image = texture.compressedSubImage(0, range, {}, + BufferUsage::StaticRead); +/* [Texture-compressedSubImage2] */ +} +#endif + +#ifndef MAGNUM_TARGET_GLES2 +{ +/* [TextureArray-usage1] */ +Texture2DArray texture; +texture.setMagnificationFilter(Sampler::Filter::Linear) + .setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) + .setWrapping(Sampler::Wrapping::ClampToEdge) + .setMaxAnisotropy(Sampler::maxMaxAnisotropy());; +/* [TextureArray-usage1] */ + +Int levels{}; +char data[1]{}; +/* [TextureArray-usage2] */ +texture.setStorage(levels, TextureFormat::RGBA8, {64, 64, 16}); + +for(std::size_t i = 0; i != 16; ++i) { + ImageView3D image(PixelFormat::RGBA, PixelType::UnsignedByte, {64, 64, 1}, data); + texture.setSubImage(0, Vector3i::zAxis(i), image); +} +/* [TextureArray-usage2] */ +} + +#ifndef MAGNUM_TARGET_GLES +{ +Texture2DArray texture; +/* [TextureArray-image1] */ +Image3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [TextureArray-image1] */ +} + +{ +Texture2DArray texture; +/* [TextureArray-image2] */ +BufferImage3D image = texture.image(0, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [TextureArray-image2] */ +} + +{ +Texture2DArray texture; +/* [TextureArray-compressedImage1] */ +CompressedImage3D image = texture.compressedImage(0, {}); +/* [TextureArray-compressedImage1] */ +} + +{ +Texture2DArray texture; +/* [TextureArray-compressedImage2] */ +CompressedBufferImage3D image = texture.compressedImage(0, {}, + BufferUsage::StaticRead); +/* [TextureArray-compressedImage2] */ +} + +{ +Texture2DArray texture; +Range3Di range; +/* [TextureArray-subImage1] */ +Image3D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}); +/* [TextureArray-subImage1] */ +} + +{ +Texture2DArray texture; +Range3Di range; +/* [TextureArray-subImage2] */ +BufferImage3D image = texture.subImage(0, range, + {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); +/* [TextureArray-subImage2] */ +} + +{ +Texture2DArray texture; +Range3Di range; +/* [TextureArray-compressedSubImage1] */ +CompressedImage3D image = texture.compressedSubImage(0, range, {}); +/* [TextureArray-compressedSubImage1] */ +} + +{ +Texture2DArray texture; +Range3Di range; +/* [TextureArray-compressedSubImage2] */ +CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, + BufferUsage::StaticRead); +/* [TextureArray-compressedSubImage2] */ +} +#endif +#endif + +#ifndef MAGNUM_TARGET_WEBGL +{ +/* [TimeQuery-usage1] */ +TimeQuery q1{TimeQuery::Target::TimeElapsed}, + q2{TimeQuery::Target::TimeElapsed}; + +q1.begin(); +// rendering... +q1.end(); + +q2.begin(); +// another rendering... +q2.end(); + +UnsignedInt timeElapsed1 = q1.result(); +UnsignedInt timeElapsed2 = q2.result(); +/* [TimeQuery-usage1] */ +static_cast(timeElapsed1); +static_cast(timeElapsed2); +} + +{ +/* [TimeQuery-usage2] */ +TimeQuery q1{TimeQuery::Target::Timestamp}, + q2{TimeQuery::Target::Timestamp}, + q3{TimeQuery::Target::Timestamp}; + +q1.timestamp(); +// rendering... +q2.timestamp(); +// another rendering... +q3.timestamp(); + +UnsignedInt tmp = q2.result(); +UnsignedInt timeElapsed1 = tmp - q1.result(); +UnsignedInt timeElapsed2 = q3.result() - tmp; +/* [TimeQuery-usage2] */ +static_cast(timeElapsed1); +static_cast(timeElapsed2); +} +#endif + +} diff --git a/doc/snippets/opengl-wrapping.cpp b/doc/snippets/opengl-wrapping.cpp deleted file mode 100644 index c42f94a00..000000000 --- a/doc/snippets/opengl-wrapping.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include "Magnum/AbstractShaderProgram.h" -#include "Magnum/Buffer.h" -#include "Magnum/Context.h" -#include "Magnum/Extensions.h" -#include "Magnum/Mesh.h" -#include "Magnum/Texture.h" -#include "Magnum/TextureFormat.h" - -using namespace Magnum; - -std::tuple importSomeMesh(); - -struct Foo { - void setSomeBuffer(GLuint); - GLuint someBuffer(); -} externalLib; - -void foo(); -void foo() { - -{ -/* [nocreate] */ -Mesh mesh{NoCreate}; -Buffer vertices{NoCreate}, indices{NoCreate}; -std::tie(mesh, vertices, indices) = importSomeMesh(); -/* [nocreate] */ -} - -{ -char someData[1]; -/* [transfer] */ -/* Transferring the instance to external library */ -{ - Buffer buffer; - buffer.setData(someData, BufferUsage::StaticDraw); - GLuint id = buffer.release(); - externalLib.setSomeBuffer(id); /* The library is responsible for deletion */ -} - -/* Acquiring an instance from external library */ -{ - GLuint id = externalLib.someBuffer(); - Buffer buffer = Buffer::wrap(id, ObjectFlag::DeleteOnDestruction); - /* The buffer instance now handles deletion */ -} -/* [transfer] */ -} - -#ifndef MAGNUM_TARGET_GLES -{ -struct: AbstractShaderProgram {} someShader; -/* [state] */ -Buffer buffer; -Mesh mesh; -// ... -mesh.draw(someShader); - -{ - /* Entering a section with 3rd-party OpenGL code -- clean up all state that - could cause accidental modifications of our objects from outside */ - Context::current().resetState(Context::State::EnterExternal); - - /* Raw OpenGL calls */ - glBindBuffer(GL_ARRAY_BUFFER, buffer.id()); - glBufferStorage(GL_ARRAY_BUFFER, 32768, nullptr, GL_MAP_READ_BIT|GL_MAP_WRITE_BIT); - // ... - - /* Exiting a section with 3rd-party OpenGL code -- reset our state tracker */ - Context::current().resetState(Context::State::ExitExternal); -} - -/* Use the buffer through Magnum again */ -auto data = buffer.map(0, 32768, Buffer::MapFlag::Read|Buffer::MapFlag::Write); -// ... -/* [state] */ -static_cast(data); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -{ -/* [extensions] */ -TextureFormat format; -if(Context::current().isExtensionSupported()) - format = TextureFormat::DepthComponent32F; -else - format = TextureFormat::DepthComponent24; -/* [extensions] */ -static_cast(format); -} -#endif - -#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2)) -{ -/* [dsa] */ -Texture2D texture; - -/* - on OpenGL 4.5+/ARB_direct_state_access this calls glTextureStorage2D() - - if EXT_direct_state_access is available, calls glTextureStorage2DEXT() - - on OpenGL 4.2+/ARB_texture_storage and OpenGL ES 3.0+ calls glTexStorage2D() - - on OpenGL ES 2.0 with EXT_texture_storage calls glTexStorage2DEXT() - - otherwise emulated using a sequence of four glTexImage2D() calls */ -texture.setStorage(4, TextureFormat::RGBA8, {256, 256}); -/* [dsa] */ -} -#endif - -} diff --git a/src/Magnum/AbstractFramebuffer.h b/src/Magnum/AbstractFramebuffer.h index 71a375390..c485b022e 100644 --- a/src/Magnum/AbstractFramebuffer.h +++ b/src/Magnum/AbstractFramebuffer.h @@ -355,9 +355,7 @@ class MAGNUM_EXPORT AbstractFramebuffer { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image2D image = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp AbstractFramebuffer-read1 */ Image2D read(const Range2Di& rectangle, Image2D&& image); @@ -384,9 +382,7 @@ class MAGNUM_EXPORT AbstractFramebuffer { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage2D image = framebuffer.read(framebuffer.viewport(), {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp AbstractFramebuffer-read2 */ BufferImage2D read(const Range2Di& rectangle, BufferImage2D&& image, BufferUsage usage); #endif diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h index 18bd918ec..5a7f22a2c 100644 --- a/src/Magnum/AbstractShaderProgram.h +++ b/src/Magnum/AbstractShaderProgram.h @@ -57,95 +57,35 @@ functions and properties:
  • **Attribute definitions** with location and type for configuring meshes, for example: - @code{.cpp} - typedef Attribute<0, Vector3> Position; - typedef Attribute<1, Vector3> Normal; - typedef Attribute<2, Vector2> TextureCoordinates; - @endcode + @snippet Magnum.cpp AbstractShaderProgram-input-attributes
  • **Output attribute locations**, if desired, for example: - @code{.cpp} - enum: UnsignedInt { - ColorOutput = 0, - NormalOutput = 1 - }; - @endcode + @snippet Magnum.cpp AbstractShaderProgram-output-attributes
  • **Constructor**, which loads, compiles and attaches particular shaders and links the program together, for example: - @code{.cpp} - MyShader() { - // Load shader sources - Shader vert(Version::GL430, Shader::Type::Vertex); - Shader frag(Version::GL430, Shader::Type::Fragment); - vert.addFile("MyShader.vert"); - frag.addFile("MyShader.frag"); - - // Invoke parallel compilation for best performance - CORRADE_INTERNAL_ASSERT_OUTPUT(Shader::compile({vert, frag})); - - // Attach the shaders - attachShaders({vert, frag}); - - // Link the program together - CORRADE_INTERNAL_ASSERT_OUTPUT(link()); - } - @endcode + @snippet Magnum.cpp AbstractShaderProgram-constructor
  • **Uniform setting functions**, which will provide public interface for protected @ref setUniform() functions. For usability purposes you can implement also method chaining. Example: - @code{.cpp} - MyShader& setProjectionMatrix(const Matrix4& matrix) { - setUniform(0, matrix); - return *this; - } - MyShader& setTransformationMatrix(const Matrix4& matrix) { - setUniform(1, matrix); - return *this; - } - MyShader& setNormalMatrix(const Matrix3x3& matrix) { - setUniform(2, matrix); - return *this; - } - @endcode + @snippet Magnum.cpp AbstractShaderProgram-uniforms
  • -
  • **Texture and texture image setting functions** in which you bind the +
  • **Texture and texture image binding functions** in which you bind the textures/images to particular texture/image units using @ref Texture::bind() "*Texture::bind()" / @ref Texture::bindImage() "*Texture::bindImage()" and similar, for example: - @code{.cpp} - MyShader& setDiffuseTexture(Texture2D& texture) { - texture.bind(0); - return *this; - } - MyShader& setSpecularTexture(Texture2D& texture) { - texture.bind(1); - return *this; - } - @endcode + @snippet Magnum.cpp AbstractShaderProgram-textures
  • **Transform feedback setup function**, if needed, in which you bind buffers to particular indices using @ref TransformFeedback::attachBuffer() and similar, possibly with overloads based on desired use cases, e.g.: - @code{.cpp} - MyShader& setTransformFeedback(TransformFeedback& feedback, Buffer& positions, Buffer& data) { - feedback.attachBuffers(0, {positions, data}); - return *this; - } - MyShader& setTransformFeedback(TransformFeedback& feedback, Int totalCount, Buffer& positions, GLintptr positionsOffset, Buffer& data, GLintptr dataOffset) { - feedback.attachBuffers(0, { - std::make_tuple(positions, positionsOffset, totalCount*sizeof(Vector3)), - std::make_tuple(data, dataOffset, totalCount*sizeof(Vector2ui)) - }); - return *this; - } - @endcode + @snippet Magnum.cpp AbstractShaderProgram-xfb
  • @subsection AbstractShaderProgram-attribute-location Binding attribute location @@ -188,18 +128,7 @@ out vec4 color; out vec3 normal; @endcode -@code{.cpp} -// Shaders attached... - -bindAttributeLocation(Position::Location, "position"); -bindAttributeLocation(Normal::Location, "normal"); -bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates"); - -bindFragmentDataLocationIndexed(ColorOutput, 0, "color"); -bindFragmentDataLocationIndexed(NormalOutput, 1, "normal"); - -// Link... -@endcode +@snippet Magnum.cpp AbstractShaderProgram-binding @see @ref maxVertexAttributes(), @ref AbstractFramebuffer::maxDrawBuffers() @requires_gl30 Extension @extension{EXT,gpu_shader4} for using @@ -250,11 +179,7 @@ uniform mat4 transformationMatrix; uniform mat3 normalMatrix; @endcode -@code{.cpp} -Int projectionMatrixUniform = uniformLocation("projectionMatrix"); -Int transformationMatrixUniform = uniformLocation("transformationMatrix"); -Int normalMatrixUniform = uniformLocation("normalMatrix"); -@endcode +@snippet Magnum.cpp AbstractShaderProgram-uniform-location @see @ref maxUniformLocations() @requires_gl43 Extension @extension{ARB,explicit_uniform_location} for @@ -299,10 +224,7 @@ layout(std140) uniform material { }; @endcode -@code{.cpp} -setUniformBlockBinding(uniformBlockIndex("matrices"), 0); -setUniformBlockBinding(uniformBlockIndex("material"), 1); -@endcode +@snippet Magnum.cpp AbstractShaderProgram-uniform-block-binding @see @ref Buffer::maxUniformBindings() @requires_gl31 Extension @extension{ARB,uniform_buffer_object} @@ -360,10 +282,7 @@ uniform sampler2D diffuseTexture; uniform sampler2D specularTexture; @endcode -@code{.cpp} -setUniform(uniformLocation("diffuseTexture"), 0); -setUniform(uniformLocation("specularTexture"), 1); -@endcode +@snippet Magnum.cpp AbstractShaderProgram-texture-uniforms @see @ref Shader::maxTextureImageUnits(), @ref maxImageUnits() @requires_gl42 Extension @extension{ARB,shading_language_420pack} for explicit @@ -402,14 +321,7 @@ out block { out vec3 velocity; @endcode -@code{.cpp} -setTransformFeedbackOutputs({ - // Buffer 0 - "position", "gl_SkipComponents1", "normal", "gl_SkipComponents1", - // Buffer 1 - "gl_NextBuffer", "velocity" - }, TransformFeedbackBufferMode::InterleavedAttributes); -@endcode +@snippet Magnum.cpp AbstractShaderProgram-xfb-outputs @see @ref TransformFeedback::maxInterleavedComponents(), @ref TransformFeedback::maxSeparateAttributes(), @@ -435,14 +347,7 @@ needed (see @ref Framebuffer-usage "Framebuffer documentation" for more information). In each draw event set all required shader parameters, bind specific framebuffer (if needed) and then call @ref Mesh::draw(). Example: -@code{.cpp} -shader.setTransformation(transformation) - .setProjection(projection) - .setDiffuseTexture(diffuseTexture) - .setSpecularTexture(specularTexture); - -mesh.draw(shader); -@endcode +@snippet Magnum.cpp AbstractShaderProgram-rendering @section AbstractShaderProgram-compute-workflow Compute workflow diff --git a/src/Magnum/Buffer.h b/src/Magnum/Buffer.h index a3648ee56..5ff20cff3 100644 --- a/src/Magnum/Buffer.h +++ b/src/Magnum/Buffer.h @@ -147,54 +147,32 @@ Default way to set or update buffer data with @ref setData() or @ref setSubData( is to use @ref Corrade::Containers::ArrayView. See its documentation for more information about automatic conversions etc. -@code{.cpp} -Containers::ArrayView data; -buffer.setData(data, BufferUsage::StaticDraw); -@endcode +@snippet Magnum.cpp Buffer-setdata There is also overload for array-like containers from STL, such as @ref std::vector or @ref std::array "std::array": -@code{.cpp} -std::vector data; -buffer.setData(data, BufferUsage::StaticDraw); -@endcode +@snippet Magnum.cpp Buffer-setdata-stl @section Buffer-data-mapping Memory mapping Buffer data can be also updated asynchronously. First you need to allocate the buffer to desired size by passing @cpp nullptr @ce to @ref setData(), e.g.: -@code{.cpp} -buffer.setData({nullptr, 200*sizeof(Vector3)}, BufferUsage::StaticDraw); -@endcode +@snippet Magnum.cpp Buffer-setdata-allocate Then you can map the buffer to client memory and operate with the memory directly. After you are done with the operation, call @ref unmap() to unmap the buffer again. The @ref map() functions return a view on `char` array and you may want to cast it to some useful type first using @ref Containers::arrayCast(): -@code{.cpp} -Containers::ArrayView data = Containers::arrayCast(buffer.map(0, 200*sizeof(Vector3), Buffer::MapFlag::Write|Buffer::MapFlag::InvalidateBuffer)); -CORRADE_INTERNAL_ASSERT(data); -for(Vector3& d: data) - d = ...; -CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap()); -@endcode +@snippet Magnum.cpp Buffer-map If you are updating only a few discrete portions of the buffer, you can use @ref MapFlag::FlushExplicit and @ref flushMappedRange() to reduce number of memory operations performed by OpenGL on unmapping. Example: -@code{.cpp} -Containers::ArrayView data = Containers::arrayCast(buffer.map(0, 200*sizeof(Vector3), Buffer::MapFlag::Write|Buffer::MapFlag::FlushExplicit)); -CORRADE_INTERNAL_ASSERT(data); -for(std::size_t i: {7, 27, 56, 128}) { - data[i] = ...; - buffer.flushMappedRange(i*sizeof(Vector3), sizeof(Vector3)); -} -CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap()); -@endcode +@snippet Magnum.cpp Buffer-flush @section Buffer-webgl-restrictions WebGL restrictions @@ -205,10 +183,7 @@ default uses any sufficient target when binding the buffer internally (e.g. for setting data). To avoid GL errors, set target hint to desired target, either in constructor or using @ref Buffer::setTargetHint(): -@code{.cpp} -Buffer vertices{Buffer::Target::Array}; -Buffer indices{Buffer::Target::ElementArray}; -@endcode +@snippet Magnum.cpp Buffer-webgl To ease up the development, @ref Mesh checks proper target hint when adding vertex and index buffers in WebGL. diff --git a/src/Magnum/BufferTexture.h b/src/Magnum/BufferTexture.h index cfa52de00..a81b19b54 100644 --- a/src/Magnum/BufferTexture.h +++ b/src/Magnum/BufferTexture.h @@ -55,16 +55,7 @@ for more textures or store more than one data in it. Example usage: -@code{.cpp} -Buffer buffer; -BufferTexture texture; -texture.setBuffer(BufferTextureFormat::RGB32F, buffer); - -constexpr static Vector3 data[] = { - // ... -}; -buffer.setData(data, BufferUsage::StaticDraw); -@endcode +@snippet Magnum.cpp BufferTexture-usage In shader, the texture is used via @glsl samplerBuffer @ce, @glsl isamplerBuffer @ce or @glsl usamplerBuffer @ce. Unlike in classic diff --git a/src/Magnum/Context.h b/src/Magnum/Context.h index a1d966342..bd004b33d 100644 --- a/src/Magnum/Context.h +++ b/src/Magnum/Context.h @@ -497,12 +497,10 @@ class MAGNUM_EXPORT Context { * @brief Get supported OpenGL version * * Returns first supported OpenGL version from passed list. Convenient - * equivalent to subsequent @ref isVersionSupported() calls, e.g.: + * equivalent to subsequent @ref isVersionSupported() calls --- the two + * following examples produce the same result: * - * @code{.cpp} - * Version v = isVersionSupported(Version::GL330) ? Version::GL330 : Version::GL210; - * Version v = supportedVersion({Version::GL330, Version::GL210}); - * @endcode + * @snippet Magnum.cpp Context-supportedVersion * * If no version from the list is supported, returns lowest available * OpenGL version (@ref Version::GL210 for desktop OpenGL, @@ -517,13 +515,7 @@ class MAGNUM_EXPORT Context { * Extensions usable with this function are listed in @ref Extensions * namespace in header @ref Extensions.h. Example usage: * - * @code{.cpp} - * if(Context::current().isExtensionSupported()) { - * // draw fancy detailed model - * } else { - * // texture fallback - * } - * @endcode + * @snippet Magnum.cpp Context-isExtensionSupported * * @see @ref isExtensionSupported(const Extension&) const, * @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED(), @@ -541,13 +533,7 @@ class MAGNUM_EXPORT Context { * @p version. Useful mainly in shader compilation when the decisions * depend on selected GLSL version, for example: * - * @code{.cpp} - * const Version version = Context::current()supportedVersion({Version::GL320, Version::GL300, Version::GL210}); - * if(Context::current().isExtensionSupported(version)) { - * // Called only if ARB_explicit_attrib_location is supported - * // *and* version is higher than GL 3.1 - * } - * @endcode + * @snippet Magnum.cpp Context-isExtensionSupported-version */ template bool isExtensionSupported(Version version) const { return _extensionRequiredVersion[T::Index] <= version && _extensionStatus[T::Index]; @@ -708,9 +694,7 @@ By default, if assertion fails, an message is printed to error output and the application aborts. If `CORRADE_NO_ASSERT` is defined, this macro does nothing. Example usage: -@code{.cpp} -MAGNUM_ASSERT_VERSION_SUPPORTED(Version::GL330); -@endcode +@snippet Magnum.cpp Context-MAGNUM_ASSERT_VERSION_SUPPORTED @see @ref Magnum::Context::isVersionSupported() "Context::isVersionSupported()", @ref MAGNUM_ASSERT_EXTENSION_SUPPORTED(), @ref CORRADE_ASSERT(), @@ -739,9 +723,7 @@ By default, if assertion fails, an message is printed to error output and the application aborts. If `CORRADE_NO_ASSERT` is defined, this macro does nothing. Example usage: -@code{.cpp} -MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::geometry_shader4); -@endcode +@snippet Magnum.cpp Context-MAGNUM_ASSERT_EXTENSION_SUPPORTED @see @ref Magnum::Context::isExtensionSupported() "Context::isExtensionSupported()", @ref MAGNUM_ASSERT_VERSION_SUPPORTED(), @ref CORRADE_ASSERT(), diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index e19fd6eee..23abf7e86 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -72,18 +72,7 @@ See @ref Texture documentation for introduction. Common usage is to fully configure all texture parameters and then set the data from e.g. set of Image objects: -@code{.cpp} -Image2D positiveX(PixelFormat::RGBA, PixelType::UnsignedByte, {256, 256}, data); -// ... - -CubeMapTexture texture; -texture.setMagnificationFilter(Sampler::Filter::Linear) - // ... - .setStorage(Math::log2(256)+1, TextureFormat::RGBA8, {256, 256}) - .setSubImage(CubeMapCoordinate::PositiveX, 0, {}, positiveX) - .setSubImage(CubeMapCoordinate::NegativeX, 0, {}, negativeX) - // ... -@endcode +@snippet Magnum.cpp CubeMapTexture-usage In shader, the texture is used via @cpp samplerCube @ce, @cpp samplerCubeShadow @ce, @cpp isamplerCube @ce or @cpp usamplerCube @ce. Unlike in classic textures, @@ -542,9 +531,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-image1 */ Image3D image(Int level, Image3D&& image); @@ -565,9 +552,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-image2 */ BufferImage3D image(Int level, BufferImage3D&& image, BufferUsage usage); @@ -593,9 +578,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage3D image = texture.compressedImage(0, {}); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-compressedImage1 */ CompressedImage3D compressedImage(Int level, CompressedImage3D&& image); @@ -616,9 +599,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage3D image = texture.compressedImage(0, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-compressedImage2 */ CompressedBufferImage3D compressedImage(Int level, CompressedBufferImage3D&& image, BufferUsage usage); @@ -658,9 +639,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image2D image = texture.image(CubeMapCoordinate::PositiveX, 0, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-image3 */ Image2D image(CubeMapCoordinate coordinate, Int level, Image2D&& image); @@ -680,9 +659,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage2D image = texture.image(CubeMapCoordinate::PositiveX, 0, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-image4 */ BufferImage2D image(CubeMapCoordinate coordinate, Int level, BufferImage2D&& image, BufferUsage usage); @@ -722,9 +699,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage2D image = texture.compressedImage(CubeMapCoordinate::PositiveX, 0, {}); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-compressedImage3 */ CompressedImage2D compressedImage(CubeMapCoordinate coordinate, Int level, CompressedImage2D&& image); @@ -745,9 +720,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage2D image = texture.compressedImage(CubeMapCoordinate::PositiveX, 0, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-compressedImage4 */ CompressedBufferImage2D compressedImage(CubeMapCoordinate coordinate, Int level, CompressedBufferImage2D&& image, BufferUsage usage); @@ -769,9 +742,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image3D image = texture.subImage(0, range, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-subImage1 */ Image3D subImage(Int level, const Range3Di& range, Image3D&& image); @@ -793,9 +764,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage3D image = texture.subImage(0, range, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-subImage2 */ BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage); @@ -821,9 +790,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage3D image = texture.compressedSubImage(0, range, {}); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-compressedSubImage1 */ CompressedImage3D compressedSubImage(Int level, const Range3Di& range, CompressedImage3D&& image); @@ -849,9 +816,7 @@ class MAGNUM_EXPORT CubeMapTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTexture-compressedSubImage2 */ CompressedBufferImage3D compressedSubImage(Int level, const Range3Di& range, CompressedBufferImage3D&& image, BufferUsage usage); #endif diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index b7be9c4a8..559ea2d02 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -52,23 +52,7 @@ You have to allocate the memory for all layers and faces first by calling @ref setStorage(). Example: array with 4 layers of cube maps, each cube map consisting of six 64x64 images, i.e. 24 layers total: -@code{.cpp} -CubeMapTextureArray texture; -texture.setMagnificationFilter(Sampler::Filter::Linear) - // ... - .setStorage(Math::log2(64)+1, TextureFormat::RGBA8, {64, 64, 24}); - -for(std::size_t i = 0; i != 4; i += 6) { - Image3D imagePositiveX(PixelFormat::RGBA, PixelType::UnsignedByte, {64, 64, 1}, data); - // ... - texture.setSubImage(0, Vector3i::zAxis(i+0), imagePositiveX); - texture.setSubImage(0, Vector3i::zAxis(i+1), imageNegativeX); - texture.setSubImage(0, Vector3i::zAxis(i+2), imagePositiveY); - // ... -} - -texture.generateMipmap(); -@endcode +@snippet Magnum.cpp CubeMapTextureArray-usage In shader, the texture is used via @glsl samplerCubeArray @ce, @glsl samplerCubeArrayShadow @ce, @glsl isamplerCubeArray @ce or @@ -459,9 +443,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-image1 */ Image3D image(Int level, Image3D&& image); @@ -482,9 +464,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-image2 */ BufferImage3D image(Int level, BufferImage3D&& image, BufferUsage usage); @@ -505,9 +485,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage3D image = texture.compressedImage(0, {}); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-compressedImage1 */ CompressedImage3D compressedImage(Int level, CompressedImage3D&& image); @@ -528,9 +506,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage3D image = texture.compressedImage(0, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-compressedImage2 */ CompressedBufferImage3D compressedImage(Int level, CompressedBufferImage3D&& image, BufferUsage usage); @@ -552,9 +528,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image3D image = texture.subImage(0, range, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-subImage1 */ Image3D subImage(Int level, const Range3Di& range, Image3D&& image); @@ -576,9 +550,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage3D image = texture.subImage(0, range, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-subImage2 */ BufferImage3D subImage(Int level, const Range3Di& range, BufferImage3D&& image, BufferUsage usage); @@ -604,9 +576,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage3D image = texture.compressedSubImage(0, range, {}); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-compressedSubImage1 */ CompressedImage3D compressedSubImage(Int level, const Range3Di& range, CompressedImage3D&& image); @@ -632,9 +602,7 @@ class MAGNUM_EXPORT CubeMapTextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp CubeMapTextureArray-compressedSubImage2 */ CompressedBufferImage3D compressedSubImage(Int level, const Range3Di& range, CompressedBufferImage3D&& image, BufferUsage usage); #endif diff --git a/src/Magnum/DebugOutput.h b/src/Magnum/DebugOutput.h index 80e9bbff7..ffd7177a4 100644 --- a/src/Magnum/DebugOutput.h +++ b/src/Magnum/DebugOutput.h @@ -74,27 +74,7 @@ application itself by setting up message callback using @ref setCallback() or @ref Renderer::Feature::DebugOutputSynchronous. Example usage, completely with @ref DebugGroup and @link DebugMessage @endlink: -@code{.cpp} -Renderer::enable(Renderer::Feature::DebugOutput); -Renderer::enable(Renderer::Feature::DebugOutputSynchronous); -DebugOutput::setDefaultCallback(); - -// Disable rather spammy "Buffer detailed info" debug messages on NVidia drivers -DebugOutput::setEnabled(DebugOutput::Source::Api, DebugOutput::Type::Other, {131185}, false); - -{ - DebugGroup group{DebugGroup::Source::Application, 42, "Scene rendering"}; - - DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, - 1337, DebugOutput::Severity::Notification, "Rendering transparent mesh"); - - Renderer::enable(Renderer::Feature::Blending); - mesh.draw(shader); - Renderer::disable(Renderer::Feature::Blending); - - // ... -} -@endcode +@snippet Magnum.cpp DebugOutput-usage With default callback the group entering/leaving and the inserted message (and possibly also other messages) will be printed on standard output: @@ -402,10 +382,7 @@ class MAGNUM_EXPORT DebugOutput { * to @ref Corrade::Utility::Debug "Debug" output in the following * format: * - * @code{.cpp} - * DebugMessage::insert(DebugMessage::Source::Application, - * DebugMessage::Type::Marker, 1337, DebugOutput::Severity::Notification, "Hello from OpenGL command stream!"); - * @endcode + * @snippet Magnum.cpp DebugOutput-setDefaultCallback * * @code{.shell-session} * Debug output: application marker (1337): Hello from OpenGL command stream! @@ -461,14 +438,13 @@ available and default debug output callback is enabled for given kind of messages, the inserted message will be printed on standard output in the following form: -@code{.cpp} -DebugMessage::insert(DebugMessage::Source::Application, DebugMessage::Type::Marker, - 1337, DebugOutput::Severity::Notification, "Hello from OpenGL command stream!"); -@endcode +@snippet Magnum.cpp DebugMessage-usage +

    @code{.shell-session} Debug output: application marker (1337): Hello from OpenGL command stream! @endcode +

    If only @extension{EXT,debug_marker} or @extension{GREMEDY,string_marker} are available, the message can be seen only through graphics debugger. @@ -638,33 +614,12 @@ See @ref DebugOutput for introduction. Easiest way is to push debug group by creating instance and pop it automatically at the end of scope: -@code{.cpp} -{ - // Push debug group - DebugGroup group{DebugGroup::Source::Application, 42, "Scene rendering"}; - - Renderer::enable(Renderer::Feature::Blending); - mesh.draw(shader); - Renderer::disable(Renderer::Feature::Blending); - - // The debug group is popped automatically at the end of the scope -} -@endcode +@snippet Magnum.cpp DebugGroup-usage1 If, for some reason, you need to pop in different scope, you can call @ref push() and @ref pop() manually: -@code{.cpp} -DebugGroup group; - -group.push(DebugGroup::Source::Application, 42, "Scene rendering"); - -Renderer::enable(Renderer::Feature::Blending); -mesh.draw(shader); -Renderer::disable(Renderer::Feature::Blending); - -group.pop(); -@endcode +@snippet Magnum.cpp DebugGroup-usage2 If OpenGL 4.3 / OpenGL ES 3.2 is supported or @extension{KHR,debug} desktop or ES extension (covered also by @extension{ANDROID,extension_pack_es31a}) is diff --git a/src/Magnum/DefaultFramebuffer.h b/src/Magnum/DefaultFramebuffer.h index 8107ec304..db03c36e9 100644 --- a/src/Magnum/DefaultFramebuffer.h +++ b/src/Magnum/DefaultFramebuffer.h @@ -47,25 +47,13 @@ must ensure that it is properly resized when application surface is resized, i.e. you must pass the new size in your @ref Platform::Sdl2Application::viewportEvent() "viewportEvent()" implementation, for example: -@code{.cpp} -void viewportEvent(const Vector2i& size) override { - defaultFramebuffer.setViewport({{}, size}); - - // ... -} -@endcode +@snippet Magnum-framebuffer.cpp DefaultFramebuffer-usage-viewport Next thing you probably want is to clear all used buffers before performing any drawing in your @ref Platform::Sdl2Application::drawEvent() "drawEvent()" implementation, for example: -@code{.cpp} -void drawEvent() override { - defaultFramebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth); - - // ... -} -@endcode +@snippet Magnum-framebuffer.cpp DefaultFramebuffer-usage-clear See documentation of particular functions and @ref Framebuffer documentation for more involved usage, usage of non-default or multiple framebuffers. @@ -379,10 +367,7 @@ class MAGNUM_EXPORT DefaultFramebuffer: public AbstractFramebuffer { * can achieve the same by passing @ref DrawAttachment::None as * attachment. Example usage: * - * @code{.cpp} - * defaultFramebuffer.mapForDraw({{MyShader::ColorOutput, DefaultFramebuffer::DrawAttachment::Back}, - * {MyShader::NormalOutput, DefaultFramebuffer::DrawAttachment::None}}); - * @endcode + * @snippet Magnum.cpp DefaultFramebuffer-usage-map * * If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) * nor @extension{EXT,direct_state_access} desktop extension is diff --git a/src/Magnum/Framebuffer.h b/src/Magnum/Framebuffer.h index 5eae6bd4d..24188186b 100644 --- a/src/Magnum/Framebuffer.h +++ b/src/Magnum/Framebuffer.h @@ -56,42 +56,18 @@ textures for actual on-screen rendering. First you need to create the framebuffer with the same viewport as default framebuffer and attach textures and renderbuffers to desired outputs: -@code{.cpp} -Framebuffer framebuffer({defaultFramebuffer.viewportPosition(), defaultFramebuffer.viewportSize()}); -Texture2D color, normal; -Renderbuffer depthStencil; - -// configure the textures and allocate texture memory... - -framebuffer.attachTexture(Framebuffer::ColorAttachment(0), color); -framebuffer.attachTexture(Framebuffer::ColorAttachment(1), normal); -framebuffer.attachRenderbuffer(Framebuffer::BufferAttachment::DepthStencil, depthStencil); -@endcode +@snippet Magnum.cpp Framebuffer-usage-attach Then you need to map outputs of your shader to color attachments in the framebuffer: -@code{.cpp} -framebuffer.mapForDraw({{MyShader::ColorOutput, Framebuffer::ColorAttachment(0)}, - {MyShader::NormalOutput, Framebuffer::ColorAttachment(1)}}); -@endcode +@snippet Magnum.cpp Framebuffer-usage-map The actual @ref Platform::Sdl2Application::drawEvent() "drawEvent()" might look like this. First you clear all buffers you need, perform drawing to off-screen framebuffer, then bind the default and render the textures on screen: -@code{.cpp} -void drawEvent() { - defaultFramebuffer.clear(FramebufferClear::Color) - framebuffer.clear(FramebufferClear::Color|FramebufferClear::Depth|FramebufferClear::Stencil); - - framebuffer.bind(); - // ... - - defaultFramebuffer.bind(); - // ... -} -@endcode +@snippet Magnum-framebuffer.cpp Framebuffer-usage-draw @section Framebuffer-performance-optimizations Performance optimizations diff --git a/src/Magnum/Mesh.h b/src/Magnum/Mesh.h index a4de87708..e793eb03c 100644 --- a/src/Magnum/Mesh.h +++ b/src/Magnum/Mesh.h @@ -168,155 +168,26 @@ commands are issued when calling @ref draw(). @subsubsection Mesh-configuration-example-basic Basic non-indexed mesh -@code{.cpp} -// Custom shader, needing only position data -class MyShader: public AbstractShaderProgram { - public: - typedef Attribute<0, Vector3> Position; - - // ... -}; - -// Fill vertex buffer with position data -static constexpr Vector3 positions[30] = { - // ... -}; -Buffer vertexBuffer; -vertexBuffer.setData(positions, BufferUsage::StaticDraw); - -// Configure the mesh, add vertex buffer -Mesh mesh; -mesh.setPrimitive(MeshPrimitive::Triangles) - .setCount(30) - .addVertexBuffer(vertexBuffer, 0, MyShader::Position{}); -@endcode +@snippet Magnum.cpp Mesh-nonindexed @subsubsection Mesh-configuration-interleaved Interleaved vertex data -@code{.cpp} -// Non-indexed primitive with positions and normals -Trade::MeshData3D plane = Primitives::Plane::solid(); - -// Fill vertex buffer with interleaved position and normal data -Buffer vertexBuffer; -vertexBuffer.setData(MeshTools::interleave(plane.positions(0), plane.normals(0)), BufferUsage::StaticDraw); - -// Configure the mesh, add vertex buffer -Mesh mesh; -mesh.setPrimitive(plane.primitive()) - .setCount(plane.positions(0).size()) - .addVertexBuffer(buffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}); -@endcode +@snippet Magnum.cpp Mesh-interleaved @subsubsection Mesh-configuration-indexed Indexed mesh -@code{.cpp} -// Custom shader -class MyShader: public AbstractShaderProgram { - public: - typedef Attribute<0, Vector3> Position; - - // ... -}; - -// Fill vertex buffer with position data -static constexpr Vector3 positions[300] = { - // ... -}; -Buffer vertexBuffer; -vertexBuffer.setData(positions, BufferUsage::StaticDraw); - -// Fill index buffer with index data -static constexpr GLubyte indices[75] = { - // ... -}; -Buffer indexBuffer; -indexBuffer.setData(indices, BufferUsage::StaticDraw); - -// Configure the mesh, add both vertex and index buffer -Mesh mesh; -mesh.setPrimitive(MeshPrimitive::Triangles) - .setCount(75) - .addVertexBuffer(vertexBuffer, 0, MyShader::Position{}) - .setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229); -@endcode +@snippet Magnum.cpp Mesh-indexed Or using @ref MeshTools::interleave() and @ref MeshTools::compressIndices(): -@code{.cpp} -// Indexed primitive -Trade::MeshData3D cube = Primitives::Cube::solid(); - -// Fill vertex buffer with interleaved position and normal data -Buffer vertexBuffer; -vertexBuffer.setData(MeshTools::interleave(cube.positions(0), cube.normals(0)), BufferUsage::StaticDraw); - -// Compress index data -Containers::Array indexData; -Mesh::IndexType indexType; -UnsignedInt indexStart, indexEnd; -std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(cube.indices()); - -// Fill index buffer -Buffer indexBuffer; -indexBuffer.setData(data); - -// Configure the mesh, add both vertex and index buffer -Mesh mesh; -mesh.setPrimitive(plane.primitive()) - .setCount(cube.indices().size()) - .addVertexBuffer(vertexBuffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{}) - .setIndexBuffer(indexBuffer, 0, indexType, indexStart, indexEnd); -@endcode +@snippet Magnum.cpp Mesh-indexed-tools Or, if you plan to use the mesh with stock shaders, you can just use @ref MeshTools::compile(). @subsubsection Mesh-configuration-formats Specific formats of vertex data -@code{.cpp} -// Custom shader with colors specified as four floating-point values -class MyShader: public AbstractShaderProgram { - public: - typedef Attribute<0, Vector3> Position; - typedef Attribute<1, Color4> Color; - - // ... -}; - -// Initial mesh configuration -Mesh mesh; -mesh.setPrimitive(...) - .setCount(30); - -// Fill position buffer with positions specified as two-component XY (i.e., -// no Z component, which is meant to be always 0) -Vector2 positions[30] = { - // ... -}; -Buffer positionBuffer; -positionBuffer.setData(positions, BufferUsage::StaticDraw); - -// Specify layout of positions buffer -- only two components, unspecified Z -// component will be automatically set to 0 -mesh.addVertexBuffer(positionBuffer, 0, - MyShader::Position{MyShader::Position::Components::Two}); - -// Fill color buffer with colors specified as four-byte BGRA (e.g. directly -// from TGA file) -GLubyte colors[4*30] = { - // ... -}; -Buffer colorBuffer; -colorBuffer.setData(colors, BufferUsage::StaticDraw); - -// Specify layout of color buffer -- BGRA, each component unsigned byte and we -// want to normalize them from [0, 255] to [0.0f, 1.0f] -mesh.addVertexBuffer(colorBuffer, 0, MyShader::Color{ - MyShader::Color::Components::BGRA, - MyShader::Color::DataType::UnsignedByte, - MyShader::Color::DataOption::Normalized}); -@endcode +@snippet Magnum.cpp Mesh-formats @subsubsection Mesh-configuration-dynamic Dynamically specified attributes @@ -328,13 +199,7 @@ that case, there are overloads of @ref addVertexBuffer() and unsigned byte to float with one byte padding at the end could then look like this: -@code{.cpp} -mesh.addVertexBuffer(colorBuffer, 0, 4, DynamicAttribute{ - DynamicAttribute::Kind::GenericNormalized, 3, - DynamicAttribute::Components::Three, - DynamicAttribute::DataType::UnsignedByte}); -}); -@endcode +@snippet Magnum.cpp Mesh-dynamic @section Mesh-rendering Rendering meshes @@ -729,25 +594,14 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * position and normal, so you have to skip weight and texture * coordinate in each vertex: * - * @code{.cpp} - * Buffer buffer; - * Mesh mesh; - * mesh.addVertexBuffer(buffer, 76, // initial array offset - * 4, // skip vertex weight (Float) - * Shaders::Phong::Position(), // vertex position - * 8, // skip texture coordinates (Vector2) - * Shaders::Phong::Normal()); // vertex normal - * @endcode + * @snippet Magnum.cpp Mesh-addVertexBuffer1 * * You can also achieve the same effect by calling @ref addVertexBuffer() * more times with explicitly specified gaps before and after the * attributes. This can be used for e.g. runtime-dependent * configuration, as it isn't dependent on the variadic template: * - * @code{.cpp} - * mesh.addVertexBuffer(buffer, 76, 4, Shaders::Phong::Position(), 20) - * .addVertexBuffer(buffer, 76, 24, Shaders::Phong::Normal(), 0); - * @endcode + * @snippet Magnum.cpp Mesh-addVertexBuffer2 * * If specifying more than one attribute, the function assumes that * the array is interleaved. Adding non-interleaved vertex buffer can @@ -755,11 +609,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * Above example with weight, position, texture coordinate and normal * arrays one after another (non-interleaved): * - * @code{.cpp} - * Int vertexCount = 352; - * mesh.addVertexBuffer(buffer, 76 + 4*vertexCount, Shaders::Phong::Position()) - * .addVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::Phong::Normal()); - * @endcode + * @snippet Magnum.cpp Mesh-addVertexBuffer3 * * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL * ES 3.0, WebGL 2.0, @extension{OES,vertex_array_object} in OpenGL diff --git a/src/Magnum/MultisampleTexture.h b/src/Magnum/MultisampleTexture.h index 09ad5e091..6b0d5ad15 100644 --- a/src/Magnum/MultisampleTexture.h +++ b/src/Magnum/MultisampleTexture.h @@ -77,10 +77,7 @@ also @ref AbstractTexture documentation for more information. As multisample textures have no sampler state, the only thing you need is to set storage: -@code{.cpp} -MultisampleTexture2D texture; -texture.setStorage(16, TextureFormat::RGBA8, {1024, 1024}); -@endcode +@snippet Magnum.cpp MultisampleTexture-usage In shader, the texture is used via @glsl sampler2DMS @ce / @glsl sampler2DMSArray @ce, @glsl isampler2DMS @ce / @glsl isampler2DMSArray @ce or @glsl usampler2DMS @ce diff --git a/src/Magnum/OpenGLTester.h b/src/Magnum/OpenGLTester.h index d933aea58..5ec0b86ff 100644 --- a/src/Magnum/OpenGLTester.h +++ b/src/Magnum/OpenGLTester.h @@ -237,9 +237,7 @@ class OpenGLTester: public TestSuite::Tester { Equivalent to -@code{.cpp} -CORRADE_COMPARE(Magnum::Renderer::error(), Magnum::Renderer::Error::NoError) -@endcode +@snippet Magnum.cpp OpenGLTester-MAGNUM_VERIFY_NO_ERROR */ #define MAGNUM_VERIFY_NO_ERROR() CORRADE_COMPARE(Magnum::Renderer::error(), Magnum::Renderer::Error::NoError) diff --git a/src/Magnum/PrimitiveQuery.h b/src/Magnum/PrimitiveQuery.h index 42e80670f..917484521 100644 --- a/src/Magnum/PrimitiveQuery.h +++ b/src/Magnum/PrimitiveQuery.h @@ -42,20 +42,7 @@ namespace Magnum { Queries count of generated primitives from vertex shader, geometry shader or transform feedback. Example usage: -@code{.cpp} -PrimitiveQuery q; - -q.begin(PrimitiveQuery::Target::PrimitivesGenerated); -// rendering... -q.end(); - -if(!q.resultAvailable()) { - // do some work until to give OpenGL some time... -} - -// ...or block until the result is available -UnsignedInt primitiveCount = q.result(); -@endcode +@snippet Magnum.cpp PrimitiveQuery-usage @see @ref SampleQuery, @ref TimeQuery, @ref TransformFeedback @requires_gl30 Extension @extension{EXT,transform_feedback} diff --git a/src/Magnum/RectangleTexture.h b/src/Magnum/RectangleTexture.h index 7ccc40371..78d37af4c 100644 --- a/src/Magnum/RectangleTexture.h +++ b/src/Magnum/RectangleTexture.h @@ -48,17 +48,7 @@ See also @ref AbstractTexture documentation for more information. Common usage is to fully configure all texture parameters and then set the data from e.g. @ref Image2D. Example configuration: -@code{.cpp} -Image2D image(PixelFormat::RGBA, PixelType::UnsignedByte, {526, 137}, data); - -RectangleTexture texture; -texture.setMagnificationFilter(Sampler::Filter::Linear) - .setMinificationFilter(Sampler::Filter::Linear) - .setWrapping(Sampler::Wrapping::ClampToEdge) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) - .setStorage(TextureFormat::RGBA8, {526, 137}) - .setSubImage({}, image); -@endcode +@snippet Magnum.cpp RectangleTexture-usage In shader, the texture is used via @glsl sampler2DRect @ce, @glsl sampler2DRectShadow @ce, @glsl isampler2DRect @ce or @glsl usampler2DRect @ce. @@ -337,9 +327,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image2D image = texture.image({PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp RectangleTexture-image1 */ Image2D image(Image2D&& image); @@ -357,9 +345,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage2D image = texture.image({PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp RectangleTexture-image2 */ BufferImage2D image(BufferImage2D&& image, BufferUsage usage); @@ -377,9 +363,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage2D image = texture.compressedimage({}); - * @endcode + * @snippet Magnum.cpp RectangleTexture-compressedImage1 */ CompressedImage2D compressedImage(CompressedImage2D&& image); @@ -397,9 +381,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage2D image = texture.compressedImage({}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp RectangleTexture-compressedImage2 */ CompressedBufferImage2D compressedImage(CompressedBufferImage2D&& image, BufferUsage usage); @@ -418,9 +400,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image2D image = texture.subImage(range, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp RectangleTexture-subImage1 */ Image2D subImage(const Range2Di& range, Image2D&& image); @@ -439,9 +419,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage2D image = texture.subImage(range, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp RectangleTexture-subImage2 */ BufferImage2D subImage(const Range2Di& range, BufferImage2D&& image, BufferUsage usage); @@ -464,9 +442,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage2D image = texture.compressedSubImage(range, {}); - * @endcode + * @snippet Magnum.cpp RectangleTexture-compressedSubImage1 */ CompressedImage2D compressedSubImage(const Range2Di& range, CompressedImage2D&& image); @@ -489,9 +465,7 @@ class MAGNUM_EXPORT RectangleTexture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage2D image = texture.compressedSubImage(range, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp RectangleTexture-compressedSubImage2 */ CompressedBufferImage2D compressedSubImage(const Range2Di& range, CompressedBufferImage2D&& image, BufferUsage usage); diff --git a/src/Magnum/SampleQuery.h b/src/Magnum/SampleQuery.h index d39a6d474..cb34ebf0c 100644 --- a/src/Magnum/SampleQuery.h +++ b/src/Magnum/SampleQuery.h @@ -43,18 +43,7 @@ Queries count of samples passed from fragment shader or boolean value indicating whether any samples passed. Can be used for example for conditional rendering: -@code{.cpp} -SampleQuery q; - -q.begin(SampleQuery::Target::AnySamplesPassed); -// render simplified object to test whether it is visible at all... -q.end(); - -// render full version of the object only if it is visible -if(q.result()) { - // ... -} -@endcode +@snippet Magnum.cpp SampleQuery-usage This approach has some drawbacks, as the rendering is blocked until result is available for the CPU to decide. This can be improved by using conditional @@ -62,17 +51,7 @@ rendering on GPU itself. The drawing commands will be sent to the GPU and processed or discarded later, so CPU can continue executing the code without waiting for the result. -@code{.cpp} -SampleQuery q; - -q.begin(SampleQuery::Target::AnySamplesPassed); -// render simplified object to test whether it is visible at all... -q.end(); - -q.beginConditionalRender(SampleQuery::ConditionalRenderMode::Wait); -// render full version of the object only if the query returns nonzero result -q.endConditionalRender(); -@endcode +@snippet Magnum.cpp SampleQuery-conditional-render @see @ref PrimitiveQuery, @ref TimeQuery @requires_gles30 Extension @extension{EXT,occlusion_query_boolean} in diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index 11823049f..07311e0c6 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -68,18 +68,7 @@ Common usage is to fully configure all texture parameters and then set the data from e.g. @ref Image. Example configuration of high quality texture with trilinear anisotropic filtering, i.e. the best you can ask for: -@code{.cpp} -Image2D image(PixelFormat::RGBA, PixelType::UnsignedByte, {4096, 4096}, data); - -Texture2D texture; -texture.setMagnificationFilter(Sampler::Filter::Linear) - .setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) - .setWrapping(Sampler::Wrapping::ClampToEdge) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy()) - .setStorage(Math::log2(4096)+1, TextureFormat::RGBA8, {4096, 4096}) - .setSubImage(0, {}, image) - .generateMipmap(); -@endcode +@snippet Magnum.cpp Texture-usage @attention Note that default configuration is to use mipmaps. Be sure to either reduce mip level count using @ref setBaseLevel() and @ref setMaxLevel(), @@ -596,9 +585,7 @@ template class Texture: public AbstractTexture { * @cpp '1' @ce for zero and one, similarly as in the * @ref Math::swizzle() function. Example usage: * - * @code{.cpp} - * texture.setSwizzle<'b', 'g', 'r', '0'>(); - * @endcode + * @snippet Magnum.cpp Texture-setSwizzle * * If neither @extension{ARB,direct_state_access} (part of OpenGL 4.5) * nor @extension{EXT,direct_state_access} desktop extension is @@ -796,9 +783,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image2D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp Texture-image1 */ Image image(Int level, Image&& image); @@ -825,9 +810,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage2D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp Texture-image2 */ BufferImage image(Int level, BufferImage&& image, BufferUsage usage); @@ -871,9 +854,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage2D image = texture.compressedImage(0, {}); - * @endcode + * @snippet Magnum.cpp Texture-compressedImage1 */ CompressedImage compressedImage(Int level, CompressedImage&& image); @@ -900,9 +881,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage2D image = texture.compressedImage(0, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp Texture-compressedImage2 */ CompressedBufferImage compressedImage(Int level, CompressedBufferImage&& image, BufferUsage usage); @@ -930,9 +909,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image2D image = texture.subImage(0, rect, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp Texture-subImage1 */ Image subImage(Int level, const RangeTypeFor& range, Image&& image); @@ -959,9 +936,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage2D image = texture.subImage(0, rect, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp Texture-subImage2 */ BufferImage subImage(Int level, const RangeTypeFor& range, BufferImage&& image, BufferUsage usage); @@ -997,9 +972,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage2D image = texture.compressedSubImage(0, rect, {}); - * @endcode + * @snippet Magnum.cpp Texture-compressedSubImage1 */ CompressedImage compressedSubImage(Int level, const RangeTypeFor& range, CompressedImage&& image); @@ -1029,9 +1002,7 @@ template class Texture: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage2D image = texture.compressedSubImage(0, rect, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp Texture-compressedSubImage2 */ CompressedBufferImage compressedSubImage(Int level, const RangeTypeFor& range, CompressedBufferImage&& image, BufferUsage usage); #endif diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h index e0f5eb54f..1824f4096 100644 --- a/src/Magnum/TextureArray.h +++ b/src/Magnum/TextureArray.h @@ -60,26 +60,13 @@ See @ref Texture documentation for introduction. Common usage is to fully configure all texture parameters and then set the data. Example configuration: -@code{.cpp} -Texture2DArray texture; -texture.setMagnificationFilter(Sampler::Filter::Linear) - .setMinificationFilter(Sampler::Filter::Linear, Sampler::Mipmap::Linear) - .setWrapping(Sampler::Wrapping::ClampToEdge) - .setMaxAnisotropy(Sampler::maxMaxAnisotropy());; -@endcode +@snippet Magnum.cpp TextureArray-usage1 It is often more convenient to first allocate the memory for all layers by calling @ref setStorage() and then specify each layer separately using @ref setSubImage(): -@code{.cpp} -texture.setStorage(levels, TextureFormat::RGBA8, {64, 64, 16}); - -for(std::size_t i = 0; i != 16; ++i) { - Image3D image(PixelFormat::RGBA, PixelType::UnsignedByte, {64, 64, 1}, ...); - texture.setSubImage(0, Vector3i::zAxis(i), image); -} -@endcode +@snippet Magnum.cpp TextureArray-usage2 In shader, the texture is used via @glsl sampler1DArray @ce / @glsl sampler2DArray @ce, @glsl sampler1DArrayShadow @ce / @glsl sampler1DArrayShadow @ce, @glsl isampler1DArray @ce @@ -493,9 +480,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp TextureArray-image1 */ Image image(Int level, Image&& image); @@ -516,9 +501,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage3D image = texture.image(0, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp TextureArray-image2 */ BufferImage image(Int level, BufferImage&& image, BufferUsage usage); @@ -539,9 +522,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage3D image = texture.compressedImage(0, {}); - * @endcode + * @snippet Magnum.cpp TextureArray-compressedImage1 */ CompressedImage compressedImage(Int level, CompressedImage&& image); @@ -562,9 +543,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage3D image = texture.compressedImage(0, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp TextureArray-compressedImage2 */ CompressedBufferImage compressedImage(Int level, CompressedBufferImage&& image, BufferUsage usage); @@ -586,9 +565,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * Image3D image = texture.subImage(0, range, {PixelFormat::RGBA, PixelType::UnsignedByte}); - * @endcode + * @snippet Magnum.cpp TextureArray-subImage1 */ Image subImage(Int level, const RangeTypeFor& range, Image&& image); @@ -610,9 +587,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * BufferImage3D image = texture.subImage(0, range, {PixelFormat::RGBA, PixelType::UnsignedByte}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp TextureArray-subImage2 */ BufferImage subImage(Int level, const RangeTypeFor& range, BufferImage&& image, BufferUsage usage); @@ -638,9 +613,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedImage3D image = texture.compressedSubImage(0, range, {}); - * @endcode + * @snippet Magnum.cpp TextureArray-compressedSubImage1 */ CompressedImage compressedSubImage(Int level, const RangeTypeFor& range, CompressedImage&& image); @@ -666,9 +639,7 @@ template class TextureArray: public AbstractTexture { * * Convenience alternative to the above, example usage: * - * @code{.cpp} - * CompressedBufferImage3D image = texture.compressedSubImage(0, range, {}, BufferUsage::StaticRead); - * @endcode + * @snippet Magnum.cpp TextureArray-compressedSubImage2 */ CompressedBufferImage compressedSubImage(Int level, const RangeTypeFor& range, CompressedBufferImage&& image, BufferUsage usage); #endif diff --git a/src/Magnum/TimeQuery.h b/src/Magnum/TimeQuery.h index daaabdaca..d214aa272 100644 --- a/src/Magnum/TimeQuery.h +++ b/src/Magnum/TimeQuery.h @@ -43,29 +43,9 @@ Queries timestamp after all previous OpenGL calls have been processed. It can query either duration of sequence of commands or absolute timestamp. Example usage of both methods: -@code{.cpp} -TimeQuery q1, q2; -q1.begin(TimeQuery::Target::TimeElapsed); -// rendering... -q1.end(); -q2.begin(TimeQuery::Target::TimeElapsed); -// another rendering... -q2.end(); -UnsignedInt timeElapsed1 = q1.result(); -UnsignedInt timeElapsed2 = q2.result(); -@endcode - -@code{.cpp} -TimeQuery q1, q2, q3; -q1.timestamp(); -// rendering... -q2.timestamp(); -// another rendering... -q3.timestamp(); -UnsignedInt tmp = q2.result(); -UnsignedInt timeElapsed1 = tmp-q1.result(); -UnsignedInt timeElapsed2 = q3.result()-tmp; -@endcode +@snippet Magnum.cpp TimeQuery-usage1 + +@snippet Magnum.cpp TimeQuery-usage2 Using the latter results in fewer OpenGL calls when doing more measures.