Browse Source

doc: compiled code snippets for the root namespace.

Oh boy, so much was not compiling, outdated or just plain wrong.
pull/205/head
Vladimír Vondruš 8 years ago
parent
commit
d16c3a2c04
  1. 10
      doc/opengl-wrapping.dox
  2. 14
      doc/snippets/CMakeLists.txt
  3. 68
      doc/snippets/Magnum-framebuffer.cpp
  4. 1337
      doc/snippets/Magnum.cpp
  5. 108
      doc/snippets/opengl-wrapping.cpp
  6. 8
      src/Magnum/AbstractFramebuffer.h
  7. 121
      src/Magnum/AbstractShaderProgram.h
  8. 37
      src/Magnum/Buffer.h
  9. 11
      src/Magnum/BufferTexture.h
  10. 32
      src/Magnum/Context.h
  11. 61
      src/Magnum/CubeMapTexture.h
  12. 50
      src/Magnum/CubeMapTextureArray.h
  13. 59
      src/Magnum/DebugOutput.h
  14. 21
      src/Magnum/DefaultFramebuffer.h
  15. 30
      src/Magnum/Framebuffer.h
  16. 168
      src/Magnum/Mesh.h
  17. 5
      src/Magnum/MultisampleTexture.h
  18. 4
      src/Magnum/OpenGLTester.h
  19. 15
      src/Magnum/PrimitiveQuery.h
  20. 44
      src/Magnum/RectangleTexture.h
  21. 25
      src/Magnum/SampleQuery.h
  22. 49
      src/Magnum/Texture.h
  23. 49
      src/Magnum/TextureArray.h
  24. 26
      src/Magnum/TimeQuery.h

10
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
*/
}

14
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(

68
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š <mosra@centrum.cz>
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] */
};

1337
doc/snippets/Magnum.cpp

File diff suppressed because it is too large Load Diff

108
doc/snippets/opengl-wrapping.cpp

@ -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<Mesh, Buffer, Buffer> 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<void>(data);
}
#endif
#ifndef MAGNUM_TARGET_GLES
{
/* [extensions] */
TextureFormat format;
if(Context::current().isExtensionSupported<Extensions::GL::ARB::depth_buffer_float>())
format = TextureFormat::DepthComponent32F;
else
format = TextureFormat::DepthComponent24;
/* [extensions] */
static_cast<void>(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
}

8
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

121
src/Magnum/AbstractShaderProgram.h

@ -57,95 +57,35 @@ functions and properties:
<li> **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
</li>
<li> **Output attribute locations**, if desired, for example:
@code{.cpp}
enum: UnsignedInt {
ColorOutput = 0,
NormalOutput = 1
};
@endcode
@snippet Magnum.cpp AbstractShaderProgram-output-attributes
</li>
<li> **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
</li>
<li> **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
</li>
<li> **Texture and texture image setting functions** in which you bind the
<li> **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
</li>
<li> **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
</li></ul>
@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

37
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<Vector3> 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<Vector3> 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<Vector3> data = Containers::arrayCast<Vector3>(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<Vector3> data = Containers::arrayCast<Vector3>(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.

11
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

32
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<Extensions::GL::ARB::tessellation_shader>()) {
* // 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<Extensions::GL::ARB::explicit_attrib_location>(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<class T> 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(),

61
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

50
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

59
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
<p>
@code{.shell-session}
Debug output: application marker (1337): Hello from OpenGL command stream!
@endcode
</p>
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

21
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

30
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

168
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<char> 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

5
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

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

15
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<UnsignedInt>();
@endcode
@snippet Magnum.cpp PrimitiveQuery-usage
@see @ref SampleQuery, @ref TimeQuery, @ref TransformFeedback
@requires_gl30 Extension @extension{EXT,transform_feedback}

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

25
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<bool>()) {
// ...
}
@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

49
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<UnsignedInt dimensions> 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<UnsignedInt dimensions> 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<dimensions> image(Int level, Image<dimensions>&& image);
@ -825,9 +810,7 @@ template<UnsignedInt dimensions> 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<dimensions> image(Int level, BufferImage<dimensions>&& image, BufferUsage usage);
@ -871,9 +854,7 @@ template<UnsignedInt dimensions> 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<dimensions> compressedImage(Int level, CompressedImage<dimensions>&& image);
@ -900,9 +881,7 @@ template<UnsignedInt dimensions> 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<dimensions> compressedImage(Int level, CompressedBufferImage<dimensions>&& image, BufferUsage usage);
@ -930,9 +909,7 @@ template<UnsignedInt dimensions> 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<dimensions> subImage(Int level, const RangeTypeFor<dimensions, Int>& range, Image<dimensions>&& image);
@ -959,9 +936,7 @@ template<UnsignedInt dimensions> 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<dimensions> subImage(Int level, const RangeTypeFor<dimensions, Int>& range, BufferImage<dimensions>&& image, BufferUsage usage);
@ -997,9 +972,7 @@ template<UnsignedInt dimensions> 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<dimensions> compressedSubImage(Int level, const RangeTypeFor<dimensions, Int>& range, CompressedImage<dimensions>&& image);
@ -1029,9 +1002,7 @@ template<UnsignedInt dimensions> 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<dimensions> compressedSubImage(Int level, const RangeTypeFor<dimensions, Int>& range, CompressedBufferImage<dimensions>&& image, BufferUsage usage);
#endif

49
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<UnsignedInt dimensions> 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<dimensions+1> image(Int level, Image<dimensions+1>&& image);
@ -516,9 +501,7 @@ template<UnsignedInt dimensions> 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<dimensions+1> image(Int level, BufferImage<dimensions+1>&& image, BufferUsage usage);
@ -539,9 +522,7 @@ template<UnsignedInt dimensions> 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<dimensions+1> compressedImage(Int level, CompressedImage<dimensions+1>&& image);
@ -562,9 +543,7 @@ template<UnsignedInt dimensions> 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<dimensions+1> compressedImage(Int level, CompressedBufferImage<dimensions+1>&& image, BufferUsage usage);
@ -586,9 +565,7 @@ template<UnsignedInt dimensions> 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<dimensions+1> subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, Image<dimensions+1>&& image);
@ -610,9 +587,7 @@ template<UnsignedInt dimensions> 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<dimensions+1> subImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, BufferImage<dimensions+1>&& image, BufferUsage usage);
@ -638,9 +613,7 @@ template<UnsignedInt dimensions> 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<dimensions+1> compressedSubImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedImage<dimensions+1>&& image);
@ -666,9 +639,7 @@ template<UnsignedInt dimensions> 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<dimensions+1> compressedSubImage(Int level, const RangeTypeFor<dimensions+1, Int>& range, CompressedBufferImage<dimensions+1>&& image, BufferUsage usage);
#endif

26
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>();
UnsignedInt timeElapsed2 = q2.result<UnsignedInt>();
@endcode
@code{.cpp}
TimeQuery q1, q2, q3;
q1.timestamp();
// rendering...
q2.timestamp();
// another rendering...
q3.timestamp();
UnsignedInt tmp = q2.result<UnsignedInt>();
UnsignedInt timeElapsed1 = tmp-q1.result<UnsignedInt>();
UnsignedInt timeElapsed2 = q3.result<UnsignedInt>()-tmp;
@endcode
@snippet Magnum.cpp TimeQuery-usage1
@snippet Magnum.cpp TimeQuery-usage2
Using the latter results in fewer OpenGL calls when doing more measures.

Loading…
Cancel
Save