mirror of https://github.com/mosra/magnum.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1659 lines
46 KiB
1659 lines
46 KiB
|
8 years ago
|
/*
|
||
|
|
This file is part of Magnum.
|
||
|
|
|
||
|
6 years ago
|
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019,
|
||
|
3 years ago
|
2020, 2021, 2022, 2023 Vladimír Vondruš <mosra@centrum.cz>
|
||
|
8 years ago
|
|
||
|
|
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.
|
||
|
|
*/
|
||
|
|
|
||
|
7 years ago
|
#include <Corrade/Containers/ArrayViewStl.h>
|
||
|
4 years ago
|
#include <Corrade/Containers/Iterable.h>
|
||
|
3 years ago
|
#include <Corrade/Containers/Pair.h>
|
||
|
7 years ago
|
#include <Corrade/Containers/Reference.h>
|
||
|
3 years ago
|
#include <Corrade/Containers/StringIterable.h>
|
||
|
|
#include <Corrade/Containers/StringView.h>
|
||
|
4 years ago
|
#include <Corrade/Containers/Triple.h>
|
||
|
7 years ago
|
#include <Corrade/TestSuite/Tester.h>
|
||
|
7 years ago
|
|
||
|
8 years ago
|
#include "Magnum/Image.h"
|
||
|
7 years ago
|
#include "Magnum/ImageView.h"
|
||
|
8 years ago
|
#include "Magnum/PixelFormat.h"
|
||
|
8 years ago
|
#include "Magnum/GL/AbstractShaderProgram.h"
|
||
|
|
#include "Magnum/GL/Buffer.h"
|
||
|
|
#include "Magnum/GL/Context.h"
|
||
|
|
#include "Magnum/GL/CubeMapTexture.h"
|
||
|
|
#include "Magnum/GL/DefaultFramebuffer.h"
|
||
|
|
#include "Magnum/GL/Extensions.h"
|
||
|
|
#include "Magnum/GL/Framebuffer.h"
|
||
|
|
#include "Magnum/GL/Mesh.h"
|
||
|
|
#include "Magnum/GL/PixelFormat.h"
|
||
|
|
#include "Magnum/GL/Renderer.h"
|
||
|
|
#include "Magnum/GL/Renderbuffer.h"
|
||
|
7 years ago
|
#include "Magnum/GL/RenderbufferFormat.h"
|
||
|
8 years ago
|
#include "Magnum/GL/Shader.h"
|
||
|
|
#include "Magnum/GL/Texture.h"
|
||
|
|
#include "Magnum/GL/TextureFormat.h"
|
||
|
|
#include "Magnum/GL/Version.h"
|
||
|
5 years ago
|
#include "Magnum/Math/Color.h"
|
||
|
|
#include "Magnum/Math/Half.h"
|
||
|
8 years ago
|
#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"
|
||
|
5 years ago
|
#include "Magnum/Shaders/FlatGL.h"
|
||
|
5 years ago
|
#include "Magnum/Shaders/PhongGL.h"
|
||
|
6 years ago
|
#include "Magnum/Trade/MeshData.h"
|
||
|
8 years ago
|
|
||
|
|
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
|
||
|
8 years ago
|
#include "Magnum/GL/SampleQuery.h"
|
||
|
8 years ago
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_WEBGL
|
||
|
8 years ago
|
#include "Magnum/GL/DebugOutput.h"
|
||
|
|
#include "Magnum/GL/TimeQuery.h"
|
||
|
8 years ago
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
8 years ago
|
#include "Magnum/GL/BufferImage.h"
|
||
|
|
#include "Magnum/GL/PrimitiveQuery.h"
|
||
|
|
#include "Magnum/GL/TextureArray.h"
|
||
|
|
#include "Magnum/GL/TransformFeedback.h"
|
||
|
8 years ago
|
#endif
|
||
|
|
|
||
|
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
|
||
|
8 years ago
|
#include "Magnum/GL/BufferTexture.h"
|
||
|
|
#include "Magnum/GL/BufferTextureFormat.h"
|
||
|
|
#include "Magnum/GL/CubeMapTextureArray.h"
|
||
|
|
#include "Magnum/GL/MultisampleTexture.h"
|
||
|
8 years ago
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
8 years ago
|
#include "Magnum/GL/RectangleTexture.h"
|
||
|
8 years ago
|
#endif
|
||
|
|
|
||
|
4 years ago
|
#define DOXYGEN_ELLIPSIS(...) __VA_ARGS__
|
||
|
5 years ago
|
|
||
|
8 years ago
|
using namespace Magnum;
|
||
|
|
using namespace Magnum::Math::Literals;
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
8 years ago
|
struct MyShader: GL::AbstractShaderProgram {
|
||
|
8 years ago
|
/* [AbstractShaderProgram-input-attributes] */
|
||
|
8 years ago
|
typedef GL::Attribute<0, Vector3> Position;
|
||
|
|
typedef GL::Attribute<1, Vector3> Normal;
|
||
|
|
typedef GL::Attribute<2, Vector2> TextureCoordinates;
|
||
|
8 years ago
|
/* [AbstractShaderProgram-input-attributes] */
|
||
|
|
|
||
|
|
/* [AbstractShaderProgram-output-attributes] */
|
||
|
|
enum: UnsignedInt {
|
||
|
|
ColorOutput = 0,
|
||
|
|
NormalOutput = 1
|
||
|
|
};
|
||
|
|
/* [AbstractShaderProgram-output-attributes] */
|
||
|
|
|
||
|
4 years ago
|
/* [AbstractShaderProgram-subclass-macro] */
|
||
|
|
MAGNUM_GL_ABSTRACTSHADERPROGRAM_SUBCLASS_DRAW_IMPLEMENTATION(MyShader)
|
||
|
|
/* [AbstractShaderProgram-subclass-macro] */
|
||
|
6 years ago
|
|
||
|
8 years ago
|
/* [AbstractShaderProgram-constructor] */
|
||
|
|
explicit MyShader() {
|
||
|
|
/* Load shader sources */
|
||
|
8 years ago
|
GL::Shader vert{GL::Version::GL430, GL::Shader::Type::Vertex};
|
||
|
|
GL::Shader frag{GL::Version::GL430, GL::Shader::Type::Fragment};
|
||
|
8 years ago
|
vert.addFile("MyShader.vert");
|
||
|
|
frag.addFile("MyShader.frag");
|
||
|
|
|
||
|
4 years ago
|
/* Compile them */
|
||
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(vert.compile() && frag.compile());
|
||
|
8 years ago
|
|
||
|
|
/* 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] */
|
||
|
8 years ago
|
MyShader& bindDiffuseTexture(GL::Texture2D& texture) {
|
||
|
8 years ago
|
texture.bind(0);
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
8 years ago
|
MyShader& bindSpecularTexture(GL::Texture2D& texture) {
|
||
|
8 years ago
|
texture.bind(1);
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
/* [AbstractShaderProgram-textures] */
|
||
|
|
|
||
|
|
/* [AbstractShaderProgram-xfb] */
|
||
|
7 years ago
|
MyShader& setTransformFeedback(GL::TransformFeedback& feedback,
|
||
|
|
GL::Buffer& positions, GL::Buffer& data)
|
||
|
|
{
|
||
|
8 years ago
|
feedback.attachBuffers(0, {&positions, &data});
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
7 years ago
|
MyShader& setTransformFeedback(GL::TransformFeedback& feedback, Int totalCount,
|
||
|
|
GL::Buffer& positions, GLintptr positionsOffset, GL::Buffer& data,
|
||
|
|
GLintptr dataOffset)
|
||
|
|
{
|
||
|
8 years ago
|
feedback.attachBuffers(0, {
|
||
|
4 years ago
|
{&positions, positionsOffset, GLsizeiptr(totalCount*sizeof(Vector3))},
|
||
|
|
{&data, dataOffset, GLsizeiptr(totalCount*sizeof(Vector2ui))}
|
||
|
8 years ago
|
});
|
||
|
|
return *this;
|
||
|
|
}
|
||
|
|
/* [AbstractShaderProgram-xfb] */
|
||
|
|
|
||
|
|
void foo() {
|
||
|
8 years ago
|
{
|
||
|
8 years ago
|
GL::Version version{};
|
||
|
8 years ago
|
/* [portability-shaders-bind] */
|
||
|
8 years ago
|
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version)) {
|
||
|
8 years ago
|
bindAttributeLocation(Position::Location, "position");
|
||
|
|
// ...
|
||
|
|
}
|
||
|
|
/* [portability-shaders-bind] */
|
||
|
|
}
|
||
|
|
|
||
|
8 years ago
|
/* [AbstractShaderProgram-binding] */
|
||
|
|
// Shaders attached...
|
||
|
|
|
||
|
|
bindAttributeLocation(Position::Location, "position");
|
||
|
|
bindAttributeLocation(Normal::Location, "normal");
|
||
|
|
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
|
||
|
|
|
||
|
7 years ago
|
bindFragmentDataLocation(ColorOutput, "color");
|
||
|
|
bindFragmentDataLocation(NormalOutput, "normal");
|
||
|
8 years ago
|
|
||
|
|
// Link...
|
||
|
|
/* [AbstractShaderProgram-binding] */
|
||
|
|
|
||
|
|
/* [AbstractShaderProgram-uniform-location] */
|
||
|
|
Int projectionMatrixUniform = uniformLocation("projectionMatrix");
|
||
|
|
Int transformationMatrixUniform = uniformLocation("transformationMatrix");
|
||
|
|
Int normalMatrixUniform = uniformLocation("normalMatrix");
|
||
|
|
/* [AbstractShaderProgram-uniform-location] */
|
||
|
|
static_cast<void>(projectionMatrixUniform);
|
||
|
|
static_cast<void>(transformationMatrixUniform);
|
||
|
|
static_cast<void>(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
|
||
|
|
|
||
|
4 years ago
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
namespace Foo {
|
||
|
|
|
||
|
|
struct MyShader: GL::AbstractShaderProgram {
|
||
|
|
class CompileState;
|
||
|
|
|
||
|
|
MyShader(NoInitT);
|
||
|
|
MyShader(CompileState&&);
|
||
|
|
MyShader(int);
|
||
|
|
|
||
|
|
static CompileState compile(int);
|
||
|
|
};
|
||
|
|
|
||
|
|
/* [AbstractShaderProgram-async] */
|
||
|
|
class MyShader::CompileState: public MyShader {
|
||
|
|
friend MyShader;
|
||
|
|
|
||
|
|
explicit CompileState(MyShader&& shader, GL::Shader&& vert, GL::Shader&& frag):
|
||
|
|
MyShader{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)} {}
|
||
|
|
|
||
|
|
GL::Shader _vert, _frag;
|
||
|
|
};
|
||
|
|
|
||
|
|
MyShader::CompileState MyShader::compile(DOXYGEN_ELLIPSIS(int)) {
|
||
|
|
GL::Shader vert{GL::Version::GL430, GL::Shader::Type::Vertex};
|
||
|
|
GL::Shader frag{GL::Version::GL430, GL::Shader::Type::Fragment};
|
||
|
|
DOXYGEN_ELLIPSIS()
|
||
|
|
vert.submitCompile();
|
||
|
|
frag.submitCompile();
|
||
|
|
|
||
|
|
MyShader out{NoInit};
|
||
|
|
DOXYGEN_ELLIPSIS()
|
||
|
|
out.attachShaders({vert, frag});
|
||
|
|
out.submitLink();
|
||
|
|
|
||
|
|
return CompileState{std::move(out), std::move(vert), std::move(frag)};
|
||
|
|
}
|
||
|
|
|
||
|
|
MyShader::MyShader(NoInitT) {}
|
||
|
|
|
||
|
|
MyShader::MyShader(CompileState&& state):
|
||
|
|
MyShader{static_cast<MyShader&&>(std::move(state))}
|
||
|
|
{
|
||
|
4 years ago
|
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink({state._vert, state._frag}));
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS()
|
||
|
|
}
|
||
|
|
|
||
|
|
MyShader::MyShader(DOXYGEN_ELLIPSIS(int a)): MyShader{compile(DOXYGEN_ELLIPSIS(a))} {}
|
||
|
|
/* [AbstractShaderProgram-async] */
|
||
|
|
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
2 years ago
|
/* Make sure the name doesn't conflict with any other snippets to avoid linker
|
||
|
|
warnings, unlike with `int main()` there now has to be a declaration to
|
||
|
|
avoid -Wmisssing-prototypes */
|
||
|
|
void mainGL();
|
||
|
|
void mainGL() {
|
||
|
4 years ago
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
|
{
|
||
|
|
ImageView2D diffuse{PixelFormat::RGBA8Unorm, {}};
|
||
|
|
ImageView2D specular{PixelFormat::RGBA8Unorm, {}};
|
||
|
|
ImageView2D bump{PixelFormat::RGBA8Unorm, {}};
|
||
|
|
/* [method-chaining-texture] */
|
||
|
|
GL::Texture2D carDiffuseTexture, carSpecularTexture, carBumpTexture;
|
||
|
|
|
||
|
|
carDiffuseTexture.setStorage(5, GL::TextureFormat::SRGB8, {256, 256});
|
||
|
|
carSpecularTexture.setStorage(3, GL::TextureFormat::R8, {256, 256});
|
||
|
|
carBumpTexture.setStorage(5, GL::TextureFormat::RGB8, {256, 256});
|
||
|
|
carDiffuseTexture.setSubImage(0, {}, diffuse);
|
||
|
|
carSpecularTexture.setSubImage(0, {}, specular);
|
||
|
|
carBumpTexture.setSubImage(0, {}, bump);
|
||
|
|
carDiffuseTexture.generateMipmap();
|
||
|
|
carSpecularTexture.generateMipmap();
|
||
|
|
carBumpTexture.generateMipmap();
|
||
|
|
/* [method-chaining-texture] */
|
||
|
|
|
||
|
|
/* [method-chaining-texture-chained] */
|
||
|
|
carDiffuseTexture.setStorage(5, GL::TextureFormat::SRGB8, {256, 256})
|
||
|
|
.setSubImage(0, {}, diffuse)
|
||
|
|
.generateMipmap();
|
||
|
|
carSpecularTexture.setStorage(3, GL::TextureFormat::R8, {256, 256})
|
||
|
|
.setSubImage(0, {}, diffuse)
|
||
|
|
.generateMipmap();
|
||
|
|
carBumpTexture.setStorage(5, GL::TextureFormat::RGB8, {256, 256})
|
||
|
|
.setSubImage(0, {}, bump)
|
||
|
|
.generateMipmap();
|
||
|
|
/* [method-chaining-texture-chained] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
{
|
||
|
|
struct Foo {
|
||
|
|
void setSomeBuffer(GLuint) {}
|
||
|
|
GLuint someBuffer() { return {}; }
|
||
|
|
} externalLib;
|
||
|
|
char someData[1];
|
||
|
|
/* [opengl-wrapping-transfer] */
|
||
|
|
/* Transferring the instance to external library */
|
||
|
|
{
|
||
|
|
GL::Buffer buffer;
|
||
|
|
buffer.setData(someData, GL::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();
|
||
|
|
GL::Buffer buffer = GL::Buffer::wrap(id, GL::ObjectFlag::DeleteOnDestruction);
|
||
|
|
/* The buffer instance now handles deletion */
|
||
|
|
}
|
||
|
|
/* [opengl-wrapping-transfer] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
struct: GL::AbstractShaderProgram {} someShader;
|
||
|
|
/* [opengl-wrapping-state] */
|
||
|
|
GL::Buffer buffer;
|
||
|
|
GL::Mesh mesh;
|
||
|
|
// ...
|
||
|
|
someShader.draw(mesh);
|
||
|
|
|
||
|
|
{
|
||
|
|
/* Entering a section with 3rd-party OpenGL code -- clean up all state that
|
||
|
|
could cause accidental modifications of our objects from outside */
|
||
|
|
GL::Context::current().resetState(GL::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 */
|
||
|
|
GL::Context::current().resetState(GL::Context::State::ExitExternal);
|
||
|
|
}
|
||
|
|
|
||
|
|
/* Use the buffer through Magnum again */
|
||
|
|
auto data = buffer.map(0, 32768, GL::Buffer::MapFlag::Read|GL::Buffer::MapFlag::Write);
|
||
|
|
// ...
|
||
|
|
/* [opengl-wrapping-state] */
|
||
|
|
static_cast<void>(data);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
/* [opengl-wrapping-extensions] */
|
||
|
|
GL::TextureFormat format;
|
||
|
|
if(GL::Context::current().isExtensionSupported<GL::Extensions::ARB::depth_buffer_float>())
|
||
|
|
format = GL::TextureFormat::DepthComponent32F;
|
||
|
|
else
|
||
|
|
format = GL::TextureFormat::DepthComponent24;
|
||
|
|
/* [opengl-wrapping-extensions] */
|
||
|
|
static_cast<void>(format);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
|
||
|
|
{
|
||
|
|
/* [opengl-wrapping-dsa] */
|
||
|
|
GL::Texture2D texture;
|
||
|
|
|
||
|
|
/* - on OpenGL 4.5+/ARB_direct_state_access this calls glTextureStorage2D()
|
||
|
|
- 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, GL::TextureFormat::RGBA8, {256, 256});
|
||
|
|
/* [opengl-wrapping-dsa] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [portability-targets] */
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
GL::Renderer::setPolygonMode(GL::Renderer::PolygonMode::Line);
|
||
|
|
// draw mesh as wireframe...
|
||
|
|
#else
|
||
|
|
// use different mesh, as polygon mode is not supported in OpenGL ES...
|
||
|
|
#endif
|
||
|
|
/* [portability-targets] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
/* [portability-extensions] */
|
||
|
|
if(GL::Context::current().isExtensionSupported<GL::Extensions::ARB::geometry_shader4>()) {
|
||
|
|
// draw mesh with wireframe on top in one pass using geometry shader...
|
||
|
|
} else {
|
||
|
|
// draw underlying mesh...
|
||
|
|
GL::Renderer::setPolygonMode(GL::Renderer::PolygonMode::Line);
|
||
|
|
// draw mesh as wirefreame in second pass...
|
||
|
|
}
|
||
|
|
/* [portability-extensions] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [portability-extension-assert] */
|
||
|
|
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ARB::geometry_shader4);
|
||
|
|
// just use geometry shader and don't care about old hardware
|
||
|
|
/* [portability-extension-assert] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [portability-shaders] */
|
||
|
|
// MyShader.cpp
|
||
|
|
GL::Version version = GL::Context::current().supportedVersion({
|
||
|
|
GL::Version::GL430, GL::Version::GL330, GL::Version::GL210});
|
||
|
|
GL::Shader vert{version, GL::Shader::Type::Vertex};
|
||
|
|
vert.addFile("MyShader.vert");
|
||
|
|
/* [portability-shaders] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
8 years ago
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
8 years ago
|
Matrix4 transformation, projection;
|
||
|
8 years ago
|
GL::Texture2D diffuseTexture, specularTexture;
|
||
|
8 years ago
|
/* [AbstractShaderProgram-rendering] */
|
||
|
4 years ago
|
MyShader shader;
|
||
|
8 years ago
|
shader.setTransformationMatrix(transformation)
|
||
|
|
.setProjectionMatrix(projection)
|
||
|
|
.bindDiffuseTexture(diffuseTexture)
|
||
|
6 years ago
|
.bindSpecularTexture(specularTexture)
|
||
|
|
.draw(mesh);
|
||
|
8 years ago
|
/* [AbstractShaderProgram-rendering] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
4 years ago
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
using Foo::MyShader;
|
||
|
|
/* [AbstractShaderProgram-async-usage] */
|
||
|
|
MyShader::CompileState state = MyShader::compile(DOXYGEN_ELLIPSIS(0));
|
||
|
|
// Other shaders to compile....
|
||
|
|
|
||
|
|
while(!state.isLinkFinished()) {
|
||
|
|
// Do other work...
|
||
|
|
}
|
||
|
|
|
||
|
|
MyShader shader{std::move(state)};
|
||
|
|
/* [AbstractShaderProgram-async-usage] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
8 years ago
|
{
|
||
|
8 years ago
|
GL::Framebuffer framebuffer{{}};
|
||
|
8 years ago
|
/* [AbstractFramebuffer-read1] */
|
||
|
|
Image2D image = framebuffer.read(framebuffer.viewport(),
|
||
|
8 years ago
|
{PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [AbstractFramebuffer-read1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
|
{
|
||
|
8 years ago
|
GL::Framebuffer framebuffer{{}};
|
||
|
8 years ago
|
/* [AbstractFramebuffer-read2] */
|
||
|
8 years ago
|
GL::BufferImage2D image = framebuffer.read(framebuffer.viewport(),
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [AbstractFramebuffer-read2] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [Buffer-setdata] */
|
||
|
5 years ago
|
const Vector3 data[]{
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS({})
|
||
|
5 years ago
|
};
|
||
|
|
|
||
|
|
GL::Buffer buffer;
|
||
|
6 years ago
|
buffer.setData(data);
|
||
|
|
|
||
|
|
GL::Buffer buffer2{data}; // or construct & fill in a single step
|
||
|
8 years ago
|
/* [Buffer-setdata] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Buffer buffer;
|
||
|
8 years ago
|
/* [Buffer-setdata-stl] */
|
||
|
4 years ago
|
std::vector<Vector3> data = DOXYGEN_ELLIPSIS({});
|
||
|
6 years ago
|
buffer.setData(data);
|
||
|
8 years ago
|
/* [Buffer-setdata-stl] */
|
||
|
5 years ago
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
Containers::ArrayView<const void> data;
|
||
|
|
/* [Buffer-setstorage] */
|
||
|
|
GL::Buffer buffer;
|
||
|
|
buffer.setStorage(data, {});
|
||
|
|
/* [Buffer-setstorage] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
8 years ago
|
|
||
|
5 years ago
|
{
|
||
|
|
GL::Buffer buffer;
|
||
|
8 years ago
|
/* [Buffer-setdata-allocate] */
|
||
|
6 years ago
|
buffer.setData({nullptr, 200*sizeof(Vector3)});
|
||
|
8 years ago
|
/* [Buffer-setdata-allocate] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_WEBGL
|
||
|
|
{
|
||
|
8 years ago
|
GL::Buffer buffer;
|
||
|
8 years ago
|
/* [Buffer-map] */
|
||
|
5 years ago
|
Containers::ArrayView<Vector3> data = Containers::arrayCast<Vector3>(
|
||
|
|
buffer.map(0, 200*sizeof(Vector3),
|
||
|
|
GL::Buffer::MapFlag::Write|GL::Buffer::MapFlag::InvalidateBuffer));
|
||
|
8 years ago
|
CORRADE_INTERNAL_ASSERT(data);
|
||
|
|
for(Vector3& d: data)
|
||
|
|
d = {/*...*/};
|
||
|
|
CORRADE_INTERNAL_ASSERT_OUTPUT(buffer.unmap());
|
||
|
|
/* [Buffer-map] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Buffer buffer;
|
||
|
8 years ago
|
/* [Buffer-flush] */
|
||
|
5 years ago
|
Containers::ArrayView<Vector3> data = Containers::arrayCast<Vector3>(
|
||
|
|
buffer.map(0, 200*sizeof(Vector3),
|
||
|
|
GL::Buffer::MapFlag::Write|GL::Buffer::MapFlag::FlushExplicit));
|
||
|
8 years ago
|
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
|
||
|
|
|
||
|
8 years ago
|
{
|
||
|
|
/* [Buffer-webgl-nope] */
|
||
|
5 years ago
|
GL::Buffer vertices;
|
||
|
|
GL::Buffer indices;
|
||
|
8 years ago
|
/* [Buffer-webgl-nope] */
|
||
|
|
}
|
||
|
|
|
||
|
8 years ago
|
{
|
||
|
|
/* [Buffer-webgl] */
|
||
|
5 years ago
|
GL::Buffer vertices{GL::Buffer::TargetHint::Array};
|
||
|
|
GL::Buffer indices{GL::Buffer::TargetHint::ElementArray};
|
||
|
8 years ago
|
/* [Buffer-webgl] */
|
||
|
|
}
|
||
|
|
|
||
|
8 years ago
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
|
{
|
||
|
|
char data[3];
|
||
|
|
/* [BufferImage-usage] */
|
||
|
|
GL::BufferImage2D image{GL::PixelFormat::RGBA, GL::PixelType::UnsignedByte,
|
||
|
|
{512, 256}, data, GL::BufferUsage::StaticDraw};
|
||
|
|
/* [BufferImage-usage] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [BufferImage-usage-wrap] */
|
||
|
|
GL::Buffer buffer;
|
||
|
|
GL::BufferImage2D image{GL::PixelFormat::RGBA, GL::PixelType::UnsignedByte,
|
||
|
|
{512, 256}, std::move(buffer), 524288};
|
||
|
|
/* [BufferImage-usage-wrap] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
/* [BufferImage-usage-query] */
|
||
|
|
GL::Texture2D texture;
|
||
|
|
GL::BufferImage2D image = texture.image(0, {GL::PixelFormat::RGBA,
|
||
|
|
GL::PixelType::UnsignedByte}, GL::BufferUsage::StaticRead);
|
||
|
|
/* [BufferImage-usage-query] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
{
|
||
|
|
char data[3];
|
||
|
|
/* [CompressedBufferImage-usage] */
|
||
|
|
GL::CompressedBufferImage2D image{GL::CompressedPixelFormat::RGBS3tcDxt1,
|
||
|
|
{512, 256}, data, GL::BufferUsage::StaticDraw};
|
||
|
|
/* [CompressedBufferImage-usage] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [CompressedBufferImage-usage-wrap] */
|
||
|
|
GL::Buffer buffer;
|
||
|
|
GL::CompressedBufferImage2D image{GL::CompressedPixelFormat::RGBS3tcDxt1,
|
||
|
|
{512, 256}, std::move(buffer), 65536};
|
||
|
|
/* [CompressedBufferImage-usage-wrap] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
/* [CompressedBufferImage-usage-query] */
|
||
|
|
GL::Texture2D texture;
|
||
|
|
GL::CompressedBufferImage2D image = texture.compressedImage(0, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
|
/* [CompressedBufferImage-usage-query] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
8 years ago
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
|
||
|
|
{
|
||
|
|
/* [BufferTexture-usage] */
|
||
|
8 years ago
|
GL::Buffer buffer;
|
||
|
|
GL::BufferTexture texture;
|
||
|
|
texture.setBuffer(GL::BufferTextureFormat::RGB32F, buffer);
|
||
|
8 years ago
|
|
||
|
|
Vector3 data[200]{
|
||
|
|
// ...
|
||
|
|
};
|
||
|
8 years ago
|
buffer.setData(data, GL::BufferUsage::StaticDraw);
|
||
|
8 years ago
|
/* [BufferTexture-usage] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
/* [Context-supportedVersion] */
|
||
|
8 years ago
|
GL::Version v1 = GL::Context::current().isVersionSupported(GL::Version::GL330) ?
|
||
|
|
GL::Version::GL330 : GL::Version::GL210;
|
||
|
|
GL::Version v2 = GL::Context::current().supportedVersion({
|
||
|
|
GL::Version::GL330, GL::Version::GL210});
|
||
|
8 years ago
|
/* [Context-supportedVersion] */
|
||
|
|
static_cast<void>(v1);
|
||
|
|
static_cast<void>(v2);
|
||
|
|
|
||
|
|
/* [Context-isExtensionSupported] */
|
||
|
8 years ago
|
if(GL::Context::current().isExtensionSupported<GL::Extensions::ARB::tessellation_shader>()) {
|
||
|
8 years ago
|
// draw fancy detailed model
|
||
|
|
} else {
|
||
|
|
// texture fallback
|
||
|
|
}
|
||
|
|
/* [Context-isExtensionSupported] */
|
||
|
|
|
||
|
|
/* [Context-isExtensionSupported-version] */
|
||
|
8 years ago
|
const GL::Version version = GL::Context::current().supportedVersion({
|
||
|
|
GL::Version::GL320, GL::Version::GL300, GL::Version::GL210});
|
||
|
|
if(GL::Context::current().isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version)) {
|
||
|
8 years ago
|
// Called only if ARB_explicit_attrib_location is supported
|
||
|
|
// *and* version is higher than GL 3.1
|
||
|
|
}
|
||
|
|
/* [Context-isExtensionSupported-version] */
|
||
|
|
|
||
|
8 years ago
|
/* [Context-MAGNUM_ASSERT_GL_VERSION_SUPPORTED] */
|
||
|
8 years ago
|
MAGNUM_ASSERT_GL_VERSION_SUPPORTED(GL::Version::GL330);
|
||
|
8 years ago
|
/* [Context-MAGNUM_ASSERT_GL_VERSION_SUPPORTED] */
|
||
|
8 years ago
|
|
||
|
8 years ago
|
/* [Context-MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED] */
|
||
|
8 years ago
|
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ARB::geometry_shader4);
|
||
|
8 years ago
|
/* [Context-MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED] */
|
||
|
8 years ago
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
|
||
|
|
{
|
||
|
|
char data[1]{};
|
||
|
8 years ago
|
ImageView2D negativeX(GL::PixelFormat::RGBA, GL::PixelType::UnsignedByte, {256, 256}, data);
|
||
|
8 years ago
|
/* [CubeMapTexture-usage] */
|
||
|
8 years ago
|
ImageView2D positiveX(GL::PixelFormat::RGBA, GL::PixelType::UnsignedByte, {256, 256}, data);
|
||
|
8 years ago
|
// ...
|
||
|
|
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
|
texture.setMagnificationFilter(GL::SamplerFilter::Linear)
|
||
|
8 years ago
|
// ...
|
||
|
8 years ago
|
.setStorage(Math::log2(256)+1, GL::TextureFormat::RGBA8, {256, 256})
|
||
|
|
.setSubImage(GL::CubeMapCoordinate::PositiveX, 0, {}, positiveX)
|
||
|
|
.setSubImage(GL::CubeMapCoordinate::NegativeX, 0, {}, negativeX)
|
||
|
8 years ago
|
// ...
|
||
|
|
/* [CubeMapTexture-usage] */
|
||
|
|
;
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-image1] */
|
||
|
8 years ago
|
Image3D image = texture.image(0, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [CubeMapTexture-image1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-image2] */
|
||
|
8 years ago
|
GL::BufferImage3D image = texture.image(0,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTexture-image2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-compressedImage1] */
|
||
|
|
CompressedImage3D image = texture.compressedImage(0, {});
|
||
|
|
/* [CubeMapTexture-compressedImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-compressedImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage3D image = texture.compressedImage(0, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTexture-compressedImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-image3] */
|
||
|
8 years ago
|
Image2D image = texture.image(GL::CubeMapCoordinate::PositiveX, 0,
|
||
|
|
{PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [CubeMapTexture-image3] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-image4] */
|
||
|
8 years ago
|
GL::BufferImage2D image = texture.image(GL::CubeMapCoordinate::PositiveX, 0,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTexture-image4] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-compressedImage3] */
|
||
|
8 years ago
|
CompressedImage2D image = texture.compressedImage(GL::CubeMapCoordinate::PositiveX,
|
||
|
8 years ago
|
0, {});
|
||
|
|
/* [CubeMapTexture-compressedImage3] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
/* [CubeMapTexture-compressedImage4] */
|
||
|
8 years ago
|
GL::CompressedBufferImage2D image = texture.compressedImage(GL::CubeMapCoordinate::PositiveX,
|
||
|
|
0, {}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTexture-compressedImage4] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTexture-subImage1] */
|
||
|
8 years ago
|
Image3D image = texture.subImage(0, range, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [CubeMapTexture-subImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTexture-subImage2] */
|
||
|
8 years ago
|
GL::BufferImage3D image = texture.subImage(0, range,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTexture-subImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTexture-compressedSubImage1] */
|
||
|
|
CompressedImage3D image = texture.compressedSubImage(0, range, {});
|
||
|
|
/* [CubeMapTexture-compressedSubImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTexture texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTexture-compressedSubImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage3D image = texture.compressedSubImage(0, range, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTexture-compressedSubImage2] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
|
||
|
|
{
|
||
|
|
char data[1]{};
|
||
|
8 years ago
|
ImageView3D imageNegativeX(PixelFormat::RGBA8Unorm, {64, 64, 1}, data);
|
||
|
|
ImageView3D imagePositiveY(PixelFormat::RGBA8Unorm, {64, 64, 1}, data);
|
||
|
8 years ago
|
/* [CubeMapTextureArray-usage] */
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
|
texture.setMagnificationFilter(GL::SamplerFilter::Linear)
|
||
|
8 years ago
|
// ...
|
||
|
8 years ago
|
.setStorage(Math::log2(64)+1, GL::TextureFormat::RGBA8, {64, 64, 24});
|
||
|
8 years ago
|
|
||
|
|
for(std::size_t i = 0; i != 4; i += 6) {
|
||
|
8 years ago
|
ImageView3D imagePositiveX(PixelFormat::RGBA8Unorm, {64, 64, 1}, data);
|
||
|
8 years ago
|
// ...
|
||
|
|
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
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
/* [CubeMapTextureArray-image1] */
|
||
|
8 years ago
|
Image3D image = texture.image(0, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [CubeMapTextureArray-image1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
/* [CubeMapTextureArray-image2] */
|
||
|
8 years ago
|
GL::BufferImage3D image = texture.image(0,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTextureArray-image2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
/* [CubeMapTextureArray-compressedImage1] */
|
||
|
|
CompressedImage3D image = texture.compressedImage(0, {});
|
||
|
|
/* [CubeMapTextureArray-compressedImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
/* [CubeMapTextureArray-compressedImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage3D image = texture.compressedImage(0, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTextureArray-compressedImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTextureArray-subImage1] */
|
||
|
8 years ago
|
Image3D image = texture.subImage(0, range, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [CubeMapTextureArray-subImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTextureArray-subImage2] */
|
||
|
8 years ago
|
GL::BufferImage3D image = texture.subImage(0, range,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTextureArray-subImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTextureArray-compressedSubImage1] */
|
||
|
|
CompressedImage3D image = texture.compressedSubImage(0, range, {});
|
||
|
|
/* [CubeMapTextureArray-compressedSubImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::CubeMapTextureArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [CubeMapTextureArray-compressedSubImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage3D image = texture.compressedSubImage(0, range, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [CubeMapTextureArray-compressedSubImage2] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_WEBGL
|
||
|
|
{
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
|
struct: GL::AbstractShaderProgram {} shader;
|
||
|
8 years ago
|
/* [DebugOutput-usage] */
|
||
|
8 years ago
|
GL::Renderer::enable(GL::Renderer::Feature::DebugOutput);
|
||
|
|
GL::Renderer::enable(GL::Renderer::Feature::DebugOutputSynchronous);
|
||
|
|
GL::DebugOutput::setDefaultCallback();
|
||
|
8 years ago
|
|
||
|
|
/* Disable rather spammy "Buffer detailed info" debug messages on NVidia drivers */
|
||
|
8 years ago
|
GL::DebugOutput::setEnabled(
|
||
|
|
GL::DebugOutput::Source::Api, GL::DebugOutput::Type::Other, {131185}, false);
|
||
|
8 years ago
|
|
||
|
|
{
|
||
|
7 years ago
|
GL::DebugGroup group{GL::DebugGroup::Source::Application, 42,
|
||
|
|
"Scene rendering"};
|
||
|
8 years ago
|
|
||
|
7 years ago
|
GL::DebugMessage::insert(GL::DebugMessage::Source::Application,
|
||
|
|
GL::DebugMessage::Type::Marker, 1337,
|
||
|
|
GL::DebugOutput::Severity::Notification, "Rendering a transparent mesh");
|
||
|
8 years ago
|
|
||
|
8 years ago
|
GL::Renderer::enable(GL::Renderer::Feature::Blending);
|
||
|
6 years ago
|
shader.draw(mesh);
|
||
|
8 years ago
|
GL::Renderer::disable(GL::Renderer::Feature::Blending);
|
||
|
8 years ago
|
|
||
|
|
// ...
|
||
|
|
}
|
||
|
|
/* [DebugOutput-usage] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [DebugOutput-setDefaultCallback] */
|
||
|
8 years ago
|
GL::DebugMessage::insert(GL::DebugMessage::Source::Application,
|
||
|
|
GL::DebugMessage::Type::Marker, 1337, GL::DebugOutput::Severity::Notification,
|
||
|
8 years ago
|
"Hello from OpenGL command stream!");
|
||
|
|
/* [DebugOutput-setDefaultCallback] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [DebugMessage-usage] */
|
||
|
8 years ago
|
GL::DebugMessage::insert(GL::DebugMessage::Source::Application,
|
||
|
|
GL::DebugMessage::Type::Marker, 1337, GL::DebugOutput::Severity::Notification,
|
||
|
8 years ago
|
"Hello from OpenGL command stream!");
|
||
|
|
/* [DebugMessage-usage] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
|
struct: GL::AbstractShaderProgram {} shader;
|
||
|
8 years ago
|
/* [DebugGroup-usage1] */
|
||
|
|
{
|
||
|
|
/* Push debug group */
|
||
|
8 years ago
|
GL::DebugGroup group{GL::DebugGroup::Source::Application, 42, "Scene rendering"};
|
||
|
8 years ago
|
|
||
|
8 years ago
|
GL::Renderer::enable(GL::Renderer::Feature::Blending);
|
||
|
6 years ago
|
shader.draw(mesh);
|
||
|
8 years ago
|
GL::Renderer::disable(GL::Renderer::Feature::Blending);
|
||
|
8 years ago
|
|
||
|
|
/* The debug group is popped automatically at the end of the scope */
|
||
|
|
}
|
||
|
|
/* [DebugGroup-usage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
|
struct: GL::AbstractShaderProgram {} shader;
|
||
|
8 years ago
|
/* [DebugGroup-usage2] */
|
||
|
8 years ago
|
GL::DebugGroup group;
|
||
|
8 years ago
|
|
||
|
8 years ago
|
group.push(GL::DebugGroup::Source::Application, 42, "Scene rendering");
|
||
|
8 years ago
|
|
||
|
8 years ago
|
GL::Renderer::enable(GL::Renderer::Feature::Blending);
|
||
|
6 years ago
|
shader.draw(mesh);
|
||
|
8 years ago
|
GL::Renderer::disable(GL::Renderer::Feature::Blending);
|
||
|
8 years ago
|
|
||
|
|
group.pop();
|
||
|
|
/* [DebugGroup-usage2] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
{
|
||
|
|
struct MyShader {
|
||
|
|
enum: UnsignedInt {
|
||
|
|
ColorOutput = 0,
|
||
|
|
NormalOutput = 1
|
||
|
|
};
|
||
|
|
};
|
||
|
|
/* [DefaultFramebuffer-usage-map] */
|
||
|
8 years ago
|
GL::defaultFramebuffer.mapForDraw({
|
||
|
|
{MyShader::ColorOutput, GL::DefaultFramebuffer::DrawAttachment::Back},
|
||
|
|
{MyShader::NormalOutput, GL::DefaultFramebuffer::DrawAttachment::None}});
|
||
|
8 years ago
|
/* [DefaultFramebuffer-usage-map] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
|
{
|
||
|
7 years ago
|
struct MyShader {
|
||
|
|
void bindTexture(GL::Texture2D&) {}
|
||
|
|
} myShader;
|
||
|
|
Vector2i size;
|
||
|
|
/* [Framebuffer-usage] */
|
||
|
|
GL::Texture2D color;
|
||
|
8 years ago
|
GL::Renderbuffer depthStencil;
|
||
|
7 years ago
|
color.setStorage(1, GL::TextureFormat::RGBA8, size);
|
||
|
|
depthStencil.setStorage(GL::RenderbufferFormat::Depth24Stencil8, size);
|
||
|
8 years ago
|
|
||
|
7 years ago
|
GL::Framebuffer framebuffer{{{}, size}};
|
||
|
8 years ago
|
framebuffer.attachTexture(GL::Framebuffer::ColorAttachment{0}, color, 0);
|
||
|
7 years ago
|
framebuffer.attachRenderbuffer(
|
||
|
|
GL::Framebuffer::BufferAttachment::DepthStencil, depthStencil);
|
||
|
7 years ago
|
/* [Framebuffer-usage] */
|
||
|
|
|
||
|
|
/* [Framebuffer-usage-rendering] */
|
||
|
|
framebuffer
|
||
|
|
.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
|
||
|
|
.bind();
|
||
|
|
|
||
|
|
// draw to this framebuffer ...
|
||
|
|
|
||
|
|
/* Switch back to the default framebuffer */
|
||
|
|
GL::defaultFramebuffer
|
||
|
|
.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
|
||
|
|
.bind();
|
||
|
|
|
||
|
|
// use the rendered texture in a shader ...
|
||
|
|
myShader.bindTexture(color);
|
||
|
|
/* [Framebuffer-usage-rendering] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
|
{
|
||
|
|
/* [Framebuffer-usage-multisample] */
|
||
|
|
Vector2i size = GL::defaultFramebuffer.viewport().size();
|
||
|
|
|
||
|
|
/* 8x MSAA */
|
||
|
|
GL::Renderbuffer color, depthStencil;
|
||
|
|
color.setStorageMultisample(8, GL::RenderbufferFormat::RGBA8, size);
|
||
|
|
depthStencil.setStorageMultisample(8,
|
||
|
|
GL::RenderbufferFormat::Depth24Stencil8, size);
|
||
|
|
|
||
|
|
GL::Framebuffer framebuffer{{{}, size}};
|
||
|
|
framebuffer.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, color);
|
||
|
|
framebuffer.attachRenderbuffer(
|
||
|
|
GL::Framebuffer::BufferAttachment::DepthStencil, depthStencil);
|
||
|
|
|
||
|
|
framebuffer.clear(GL::FramebufferClear::Color|GL::FramebufferClear::Depth)
|
||
|
|
.bind();
|
||
|
|
|
||
|
|
// draw to the multisampled framebuffer ...
|
||
|
|
|
||
|
|
/* Resolve the color output to a single-sampled default framebuffer */
|
||
|
|
GL::defaultFramebuffer.clear(GL::FramebufferClear::Color)
|
||
|
|
.bind();
|
||
|
|
GL::Framebuffer::blit(framebuffer, GL::defaultFramebuffer,
|
||
|
|
{{}, size}, GL::FramebufferBlit::Color);
|
||
|
|
/* [Framebuffer-usage-multisample] */
|
||
|
8 years ago
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
7 years ago
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
8 years ago
|
{
|
||
|
|
struct MyShader {
|
||
|
|
enum: UnsignedInt {
|
||
|
|
ColorOutput = 0,
|
||
|
|
NormalOutput = 1
|
||
|
|
};
|
||
|
|
};
|
||
|
7 years ago
|
/* [Framebuffer-usage-deferred] */
|
||
|
|
GL::Framebuffer framebuffer{GL::defaultFramebuffer.viewport()};
|
||
|
|
GL::Texture2D color, normal;
|
||
|
|
GL::Renderbuffer depthStencil;
|
||
|
|
// setStorage() ...
|
||
|
|
|
||
|
|
framebuffer.attachTexture(GL::Framebuffer::ColorAttachment{0}, color, 0);
|
||
|
|
framebuffer.attachTexture(GL::Framebuffer::ColorAttachment{1}, normal, 0);
|
||
|
|
framebuffer.attachRenderbuffer(
|
||
|
|
GL::Framebuffer::BufferAttachment::DepthStencil, depthStencil);
|
||
|
7 years ago
|
framebuffer.mapForDraw({
|
||
|
|
{MyShader::ColorOutput, GL::Framebuffer::ColorAttachment(0)},
|
||
|
|
{MyShader::NormalOutput, GL::Framebuffer::ColorAttachment(1)}});
|
||
|
7 years ago
|
/* [Framebuffer-usage-deferred] */
|
||
|
7 years ago
|
|
||
|
|
/* [Framebuffer-mapForDraw] */
|
||
|
|
framebuffer.mapForDraw({
|
||
|
|
{MyShader::ColorOutput, GL::Framebuffer::ColorAttachment(0)},
|
||
|
|
{MyShader::NormalOutput, GL::Framebuffer::DrawAttachment::None}});
|
||
|
|
/* [Framebuffer-mapForDraw] */
|
||
|
8 years ago
|
}
|
||
|
7 years ago
|
#endif
|
||
|
8 years ago
|
|
||
|
|
{
|
||
|
5 years ago
|
/* [Mesh-vertices] */
|
||
|
|
const Vector3 positions[]{
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS({})
|
||
|
8 years ago
|
};
|
||
|
5 years ago
|
GL::Buffer vertices{positions};
|
||
|
8 years ago
|
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
5 years ago
|
mesh.setCount(Containers::arraySize(positions))
|
||
|
|
.addVertexBuffer(vertices, 0, Shaders::FlatGL3D::Position{});
|
||
|
|
/* [Mesh-vertices] */
|
||
|
8 years ago
|
}
|
||
|
|
|
||
|
|
{
|
||
|
5 years ago
|
/* [Mesh-vertices-interleaved] */
|
||
|
|
struct Vertex {
|
||
|
|
Vector3 position;
|
||
|
|
Vector3 normal;
|
||
|
|
};
|
||
|
|
const Vertex vertexData[]{
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS({})
|
||
|
5 years ago
|
};
|
||
|
|
GL::Buffer vertices{vertexData};
|
||
|
8 years ago
|
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
5 years ago
|
mesh.setCount(Containers::arraySize(vertexData))
|
||
|
|
.addVertexBuffer(vertices, 0,
|
||
|
|
Shaders::PhongGL::Position{},
|
||
|
|
Shaders::PhongGL::Normal{});
|
||
|
|
/* [Mesh-vertices-interleaved] */
|
||
|
8 years ago
|
}
|
||
|
|
|
||
|
|
{
|
||
|
5 years ago
|
GL::Mesh mesh;
|
||
|
|
/* [Mesh-indices] */
|
||
|
|
const UnsignedInt indexData[]{
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS(0)
|
||
|
8 years ago
|
};
|
||
|
5 years ago
|
GL::Buffer indices{indexData};
|
||
|
8 years ago
|
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS()
|
||
|
5 years ago
|
mesh.setIndexBuffer(indices, 0, MeshIndexType::UnsignedInt);
|
||
|
|
/* [Mesh-indices] */
|
||
|
8 years ago
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
5 years ago
|
/* [Mesh-vertices-interleaved-tool] */
|
||
|
4 years ago
|
Containers::ArrayView<const Vector3> positions = DOXYGEN_ELLIPSIS({});
|
||
|
|
Containers::ArrayView<const Vector3> normals = DOXYGEN_ELLIPSIS({});
|
||
|
5 years ago
|
GL::Buffer vertices{MeshTools::interleave(positions, normals)};
|
||
|
|
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS()
|
||
|
5 years ago
|
mesh.addVertexBuffer(vertices, 0,
|
||
|
|
Shaders::PhongGL::Position{},
|
||
|
|
Shaders::PhongGL::Normal{});
|
||
|
|
/* [Mesh-vertices-interleaved-tool] */
|
||
|
8 years ago
|
}
|
||
|
|
|
||
|
|
{
|
||
|
5 years ago
|
GL::Mesh mesh;
|
||
|
|
const UnsignedInt indexData[1]{};
|
||
|
|
/* [Mesh-indices-tool] */
|
||
|
3 years ago
|
Containers::Pair<Containers::Array<char>, MeshIndexType> compressed =
|
||
|
|
MeshTools::compressIndices(indexData);
|
||
|
|
GL::Buffer indices{compressed.first()};
|
||
|
8 years ago
|
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS()
|
||
|
3 years ago
|
mesh.setIndexBuffer(indices, 0, compressed.second());
|
||
|
5 years ago
|
/* [Mesh-indices-tool] */
|
||
|
|
}
|
||
|
8 years ago
|
|
||
|
4 years ago
|
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
|
||
|
5 years ago
|
/* The damn thing doesn't understand unnamed bitfields in local structs */
|
||
|
|
#ifndef CORRADE_MSVC2015_COMPATIBILITY
|
||
|
5 years ago
|
{
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
5 years ago
|
/* [Mesh-formats] */
|
||
|
|
struct Packed {
|
||
|
|
Vector3h position;
|
||
|
|
Short:16;
|
||
|
|
Vector3s normal;
|
||
|
|
Short:16;
|
||
|
8 years ago
|
};
|
||
|
5 years ago
|
const Packed vertexData[]{
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS({})
|
||
|
8 years ago
|
};
|
||
|
5 years ago
|
GL::Buffer vertices{vertexData};
|
||
|
|
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS()
|
||
|
5 years ago
|
mesh.addVertexBuffer(vertices, 0,
|
||
|
|
Shaders::PhongGL::Position{Shaders::PhongGL::Position::Components::Three,
|
||
|
|
Shaders::PhongGL::Position::DataType::Half},
|
||
|
|
2,
|
||
|
|
Shaders::PhongGL::Normal{Shaders::PhongGL::Normal::Components::Three,
|
||
|
|
Shaders::PhongGL::Normal::DataType::Short,
|
||
|
|
Shaders::PhongGL::Normal::DataOption::Normalized},
|
||
|
|
2);
|
||
|
8 years ago
|
/* [Mesh-formats] */
|
||
|
5 years ago
|
|
||
|
|
/* [Mesh-formats-vertexformat] */
|
||
|
|
mesh.addVertexBuffer(vertices, offsetof(Packed, position), sizeof(Packed),
|
||
|
|
GL::DynamicAttribute{Shaders::PhongGL::Position{},
|
||
|
|
VertexFormat::Vector3h});
|
||
|
|
mesh.addVertexBuffer(vertices, offsetof(Packed, normal), sizeof(Packed),
|
||
|
|
GL::DynamicAttribute{Shaders::PhongGL::Normal{},
|
||
|
|
VertexFormat::Vector3sNormalized});
|
||
|
|
/* [Mesh-formats-vertexformat] */
|
||
|
8 years ago
|
}
|
||
|
5 years ago
|
#endif
|
||
|
4 years ago
|
#endif
|
||
|
8 years ago
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Mesh mesh;
|
||
|
|
GL::Buffer colorBuffer;
|
||
|
8 years ago
|
/* [Mesh-dynamic] */
|
||
|
8 years ago
|
mesh.addVertexBuffer(colorBuffer, 0, 4, GL::DynamicAttribute{
|
||
|
|
GL::DynamicAttribute::Kind::GenericNormalized, 3,
|
||
|
|
GL::DynamicAttribute::Components::Three,
|
||
|
|
GL::DynamicAttribute::DataType::UnsignedByte});
|
||
|
8 years ago
|
/* [Mesh-dynamic] */
|
||
|
|
}
|
||
|
|
|
||
|
8 years ago
|
{
|
||
|
|
GL::Mesh mesh;
|
||
|
|
/* [Mesh-buffer-ownership] */
|
||
|
|
GL::Buffer vertices, indices;
|
||
|
4 years ago
|
DOXYGEN_ELLIPSIS()
|
||
|
8 years ago
|
mesh.addVertexBuffer(std::move(vertices), 0,
|
||
|
5 years ago
|
Shaders::PhongGL::Position{},
|
||
|
|
Shaders::PhongGL::Normal{})
|
||
|
8 years ago
|
.setIndexBuffer(std::move(indices), 0, MeshIndexType::UnsignedInt);
|
||
|
|
/* [Mesh-buffer-ownership] */
|
||
|
|
|
||
|
|
/* [Mesh-buffer-ownership-multiple] */
|
||
|
5 years ago
|
mesh.addVertexBuffer(vertices, 0, Shaders::PhongGL::Position{}, 20)
|
||
|
|
.addVertexBuffer(std::move(vertices), 0, 20, Shaders::PhongGL::Normal{});
|
||
|
8 years ago
|
/* [Mesh-buffer-ownership-multiple] */
|
||
|
|
}
|
||
|
|
|
||
|
5 years ago
|
{
|
||
|
|
GL::Mesh mesh;
|
||
|
|
/* [Mesh-draw] */
|
||
|
4 years ago
|
Shaders::PhongGL shader{DOXYGEN_ELLIPSIS()};
|
||
|
|
DOXYGEN_ELLIPSIS()
|
||
|
5 years ago
|
shader.draw(mesh);
|
||
|
|
/* [Mesh-draw] */
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
8 years ago
|
{
|
||
|
|
/* [Mesh-addVertexBuffer1] */
|
||
|
8 years ago
|
GL::Buffer buffer;
|
||
|
|
GL::Mesh mesh;
|
||
|
8 years ago
|
mesh.addVertexBuffer(buffer, 76, /* initial array offset */
|
||
|
|
4, /* skip vertex weight (Float) */
|
||
|
5 years ago
|
Shaders::PhongGL::Position(), /* vertex position */
|
||
|
8 years ago
|
8, /* skip texture coordinates (Vector2) */
|
||
|
5 years ago
|
Shaders::PhongGL::Normal()); /* vertex normal */
|
||
|
8 years ago
|
/* [Mesh-addVertexBuffer1] */
|
||
|
|
|
||
|
|
/* [Mesh-addVertexBuffer2] */
|
||
|
5 years ago
|
mesh.addVertexBuffer(buffer, 76, 4, Shaders::PhongGL::Position{}, 20)
|
||
|
|
.addVertexBuffer(buffer, 76, 24, Shaders::PhongGL::Normal{}, 0);
|
||
|
8 years ago
|
/* [Mesh-addVertexBuffer2] */
|
||
|
|
|
||
|
|
/* [Mesh-addVertexBuffer3] */
|
||
|
|
Int vertexCount = 352;
|
||
|
5 years ago
|
mesh.addVertexBuffer(buffer, 76 + 4*vertexCount, Shaders::PhongGL::Position{})
|
||
|
|
.addVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::PhongGL::Normal{});
|
||
|
8 years ago
|
/* [Mesh-addVertexBuffer3] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
|
||
|
|
{
|
||
|
|
/* [MultisampleTexture-usage] */
|
||
|
8 years ago
|
GL::MultisampleTexture2D texture;
|
||
|
|
texture.setStorage(16, GL::TextureFormat::RGBA8, {1024, 1024});
|
||
|
8 years ago
|
/* [MultisampleTexture-usage] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
struct A: TestSuite::Tester {
|
||
|
|
void foo() {
|
||
|
8 years ago
|
/* [OpenGLTester-MAGNUM_VERIFY_NO_GL_ERROR] */
|
||
|
8 years ago
|
CORRADE_COMPARE(Magnum::GL::Renderer::error(), Magnum::GL::Renderer::Error::NoError);
|
||
|
8 years ago
|
/* [OpenGLTester-MAGNUM_VERIFY_NO_GL_ERROR] */
|
||
|
8 years ago
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
|
||
|
|
{
|
||
|
|
/* [PrimitiveQuery-usage] */
|
||
|
8 years ago
|
GL::PrimitiveQuery q{GL::PrimitiveQuery::Target::PrimitivesGenerated};
|
||
|
8 years ago
|
|
||
|
|
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<UnsignedInt>();
|
||
|
|
/* [PrimitiveQuery-usage] */
|
||
|
|
static_cast<void>(primitiveCount);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
char data[1]{};
|
||
|
|
/* [RectangleTexture-usage] */
|
||
|
8 years ago
|
ImageView2D image{PixelFormat::RGBA8Unorm, {526, 137}, data};
|
||
|
|
|
||
|
|
GL::RectangleTexture texture;
|
||
|
|
texture.setMagnificationFilter(GL::SamplerFilter::Linear)
|
||
|
|
.setMinificationFilter(GL::SamplerFilter::Linear)
|
||
|
|
.setWrapping(GL::SamplerWrapping::ClampToEdge)
|
||
|
|
.setMaxAnisotropy(GL::Sampler::maxMaxAnisotropy())
|
||
|
|
.setStorage(GL::TextureFormat::RGBA8, {526, 137})
|
||
|
8 years ago
|
.setSubImage({}, image);
|
||
|
|
/* [RectangleTexture-usage] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
/* [RectangleTexture-image1] */
|
||
|
8 years ago
|
Image2D image = texture.image({PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [RectangleTexture-image1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
/* [RectangleTexture-image2] */
|
||
|
8 years ago
|
GL::BufferImage2D image = texture.image(
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [RectangleTexture-image2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
/* [RectangleTexture-compressedImage1] */
|
||
|
|
CompressedImage2D image = texture.compressedImage({});
|
||
|
|
/* [RectangleTexture-compressedImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
/* [RectangleTexture-compressedImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage2D image = texture.compressedImage({},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [RectangleTexture-compressedImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [RectangleTexture-subImage1] */
|
||
|
8 years ago
|
Image2D image = texture.subImage(range, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [RectangleTexture-subImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [RectangleTexture-subImage2] */
|
||
|
8 years ago
|
GL::BufferImage2D image = texture.subImage(range,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [RectangleTexture-subImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [RectangleTexture-compressedSubImage1] */
|
||
|
|
CompressedImage2D image = texture.compressedSubImage(range, {});
|
||
|
|
/* [RectangleTexture-compressedSubImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::RectangleTexture texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [RectangleTexture-compressedSubImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage2D image = texture.compressedSubImage(range, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [RectangleTexture-compressedSubImage2] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
7 years ago
|
{
|
||
|
|
GL::Renderer::Feature feature = GL::Renderer::Feature::Blending;
|
||
|
|
bool enabled{};
|
||
|
|
/* [Renderer-setFeature] */
|
||
|
|
enabled ? GL::Renderer::enable(feature) : GL::Renderer::disable(feature)
|
||
|
|
/* [Renderer-setFeature] */
|
||
|
|
;
|
||
|
|
}
|
||
|
|
|
||
|
6 years ago
|
{
|
||
|
|
/* [Renderer-setBlendFunction] */
|
||
|
|
GL::Renderer::enable(GL::Renderer::Feature::Blending);
|
||
|
|
GL::Renderer::setBlendFunction(
|
||
|
|
GL::Renderer::BlendFunction::One, /* or SourceAlpha for non-premultiplied */
|
||
|
|
GL::Renderer::BlendFunction::OneMinusSourceAlpha);
|
||
|
|
/* [Renderer-setBlendFunction] */
|
||
|
|
}
|
||
|
|
|
||
|
8 years ago
|
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
|
||
|
|
{
|
||
|
|
/* [SampleQuery-usage] */
|
||
|
8 years ago
|
GL::SampleQuery q{GL::SampleQuery::Target::AnySamplesPassed};
|
||
|
8 years ago
|
|
||
|
|
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<bool>()) {
|
||
|
|
// ...
|
||
|
|
}
|
||
|
|
/* [SampleQuery-usage] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
|
/* [SampleQuery-conditional-render] */
|
||
|
8 years ago
|
GL::SampleQuery q{GL::SampleQuery::Target::AnySamplesPassed};
|
||
|
8 years ago
|
|
||
|
|
q.begin();
|
||
|
|
/* Render simplified object to test whether it is visible at all */
|
||
|
|
// ...
|
||
|
|
q.end();
|
||
|
|
|
||
|
8 years ago
|
q.beginConditionalRender(GL::SampleQuery::ConditionalRenderMode::Wait);
|
||
|
8 years ago
|
/* 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] */
|
||
|
8 years ago
|
ImageView2D image(PixelFormat::RGBA8Unorm, {4096, 4096}, data);
|
||
|
|
|
||
|
|
GL::Texture2D texture;
|
||
|
|
texture.setMagnificationFilter(GL::SamplerFilter::Linear)
|
||
|
|
.setMinificationFilter(GL::SamplerFilter::Linear, GL::SamplerMipmap::Linear)
|
||
|
|
.setWrapping(GL::SamplerWrapping::ClampToEdge)
|
||
|
|
.setMaxAnisotropy(GL::Sampler::maxMaxAnisotropy())
|
||
|
|
.setStorage(Math::log2(4096)+1, GL::TextureFormat::RGBA8, {4096, 4096})
|
||
|
8 years ago
|
.setSubImage(0, {}, image)
|
||
|
|
.generateMipmap();
|
||
|
|
/* [Texture-usage] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
/* [Texture-setSwizzle] */
|
||
|
|
texture.setSwizzle<'b', 'g', 'r', '0'>();
|
||
|
|
/* [Texture-setSwizzle] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
/* [Texture-image1] */
|
||
|
8 years ago
|
Image2D image = texture.image(0, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [Texture-image1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
/* [Texture-image2] */
|
||
|
8 years ago
|
GL::BufferImage2D image = texture.image(0,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [Texture-image2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
/* [Texture-compressedImage1] */
|
||
|
|
CompressedImage2D image = texture.compressedImage(0, {});
|
||
|
|
/* [Texture-compressedImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
/* [Texture-compressedImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage2D image = texture.compressedImage(0, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [Texture-compressedImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [Texture-subImage1] */
|
||
|
8 years ago
|
Image2D image = texture.subImage(0, range, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [Texture-subImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [Texture-subImage2] */
|
||
|
8 years ago
|
GL::BufferImage2D image = texture.subImage(0, range,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [Texture-subImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [Texture-compressedSubImage1] */
|
||
|
|
CompressedImage2D image = texture.compressedSubImage(0, range, {});
|
||
|
|
/* [Texture-compressedSubImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2D texture;
|
||
|
8 years ago
|
Range2Di range;
|
||
|
|
/* [Texture-compressedSubImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage2D image = texture.compressedSubImage(0, range, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [Texture-compressedSubImage2] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES2
|
||
|
|
{
|
||
|
|
/* [TextureArray-usage1] */
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
|
texture.setMagnificationFilter(GL::SamplerFilter::Linear)
|
||
|
|
.setMinificationFilter(GL::SamplerFilter::Linear, GL::SamplerMipmap::Linear)
|
||
|
|
.setWrapping(GL::SamplerWrapping::ClampToEdge)
|
||
|
|
.setMaxAnisotropy(GL::Sampler::maxMaxAnisotropy());;
|
||
|
8 years ago
|
/* [TextureArray-usage1] */
|
||
|
|
|
||
|
|
Int levels{};
|
||
|
|
char data[1]{};
|
||
|
|
/* [TextureArray-usage2] */
|
||
|
8 years ago
|
texture.setStorage(levels, GL::TextureFormat::RGBA8, {64, 64, 16});
|
||
|
8 years ago
|
|
||
|
|
for(std::size_t i = 0; i != 16; ++i) {
|
||
|
8 years ago
|
ImageView3D image(PixelFormat::RGBA8Unorm, {64, 64, 1}, data);
|
||
|
8 years ago
|
texture.setSubImage(0, Vector3i::zAxis(i), image);
|
||
|
|
}
|
||
|
|
/* [TextureArray-usage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_GLES
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
/* [TextureArray-image1] */
|
||
|
8 years ago
|
Image3D image = texture.image(0, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [TextureArray-image1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
/* [TextureArray-image2] */
|
||
|
8 years ago
|
GL::BufferImage3D image = texture.image(0,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [TextureArray-image2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
/* [TextureArray-compressedImage1] */
|
||
|
|
CompressedImage3D image = texture.compressedImage(0, {});
|
||
|
|
/* [TextureArray-compressedImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
/* [TextureArray-compressedImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage3D image = texture.compressedImage(0, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [TextureArray-compressedImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [TextureArray-subImage1] */
|
||
|
8 years ago
|
Image3D image = texture.subImage(0, range, {PixelFormat::RGBA8Unorm});
|
||
|
8 years ago
|
/* [TextureArray-subImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [TextureArray-subImage2] */
|
||
|
8 years ago
|
GL::BufferImage3D image = texture.subImage(0, range,
|
||
|
|
{PixelFormat::RGBA8Unorm}, GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [TextureArray-subImage2] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [TextureArray-compressedSubImage1] */
|
||
|
|
CompressedImage3D image = texture.compressedSubImage(0, range, {});
|
||
|
|
/* [TextureArray-compressedSubImage1] */
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
8 years ago
|
GL::Texture2DArray texture;
|
||
|
8 years ago
|
Range3Di range;
|
||
|
|
/* [TextureArray-compressedSubImage2] */
|
||
|
8 years ago
|
GL::CompressedBufferImage3D image = texture.compressedSubImage(0, range, {},
|
||
|
|
GL::BufferUsage::StaticRead);
|
||
|
8 years ago
|
/* [TextureArray-compressedSubImage2] */
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
#ifndef MAGNUM_TARGET_WEBGL
|
||
|
|
{
|
||
|
|
/* [TimeQuery-usage1] */
|
||
|
8 years ago
|
GL::TimeQuery q1{GL::TimeQuery::Target::TimeElapsed},
|
||
|
|
q2{GL::TimeQuery::Target::TimeElapsed};
|
||
|
8 years ago
|
|
||
|
|
q1.begin();
|
||
|
|
// rendering...
|
||
|
|
q1.end();
|
||
|
|
|
||
|
|
q2.begin();
|
||
|
|
// another rendering...
|
||
|
|
q2.end();
|
||
|
|
|
||
|
|
UnsignedInt timeElapsed1 = q1.result<UnsignedInt>();
|
||
|
|
UnsignedInt timeElapsed2 = q2.result<UnsignedInt>();
|
||
|
|
/* [TimeQuery-usage1] */
|
||
|
|
static_cast<void>(timeElapsed1);
|
||
|
|
static_cast<void>(timeElapsed2);
|
||
|
|
}
|
||
|
|
|
||
|
|
{
|
||
|
|
/* [TimeQuery-usage2] */
|
||
|
8 years ago
|
GL::TimeQuery q1{GL::TimeQuery::Target::Timestamp},
|
||
|
|
q2{GL::TimeQuery::Target::Timestamp},
|
||
|
|
q3{GL::TimeQuery::Target::Timestamp};
|
||
|
8 years ago
|
|
||
|
|
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;
|
||
|
|
/* [TimeQuery-usage2] */
|
||
|
|
static_cast<void>(timeElapsed1);
|
||
|
|
static_cast<void>(timeElapsed2);
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
|
||
|
|
}
|