Browse Source

Shaders: minor cleanup & document new async compilation APIs.

Apart from docs mostly just reordering declaratios, removing usage of
auto and providing default arguments where missing.
pull/589/head
Vladimír Vondruš 4 years ago
parent
commit
48326ac418
  1. 21
      doc/snippets/MagnumShaders-gl.cpp
  2. 6
      src/Magnum/Shaders/DistanceFieldVectorGL.cpp
  3. 68
      src/Magnum/Shaders/DistanceFieldVectorGL.h
  4. 14
      src/Magnum/Shaders/FlatGL.cpp
  5. 70
      src/Magnum/Shaders/FlatGL.h
  6. 60
      src/Magnum/Shaders/MeshVisualizerGL.cpp
  7. 154
      src/Magnum/Shaders/MeshVisualizerGL.h
  8. 13
      src/Magnum/Shaders/PhongGL.cpp
  9. 69
      src/Magnum/Shaders/PhongGL.h
  10. 25
      src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp
  11. 27
      src/Magnum/Shaders/Test/FlatGLTest.cpp
  12. 46
      src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp
  13. 26
      src/Magnum/Shaders/Test/PhongGLTest.cpp
  14. 26
      src/Magnum/Shaders/Test/VectorGLTest.cpp
  15. 18
      src/Magnum/Shaders/Test/VertexColorGLTest.cpp
  16. 14
      src/Magnum/Shaders/VectorGL.cpp
  17. 70
      src/Magnum/Shaders/VectorGL.h
  18. 13
      src/Magnum/Shaders/VertexColorGL.cpp
  19. 69
      src/Magnum/Shaders/VertexColorGL.h

21
doc/snippets/MagnumShaders-gl.cpp

@ -341,6 +341,27 @@ shader
/* [shaders-meshvisualizer] */
}
{
/* [shaders-async] */
Shaders::FlatGL3D::CompileState flatState =
Shaders::FlatGL3D::compile();
Shaders::FlatGL3D::CompileState flatTexturedState =
Shaders::FlatGL3D::compile(Shaders::FlatGL3D::Flag::Textured);
Shaders::MeshVisualizerGL3D::CompileState meshVisualizerState =
Shaders::MeshVisualizerGL3D::compile(DOXYGEN_ELLIPSIS(Shaders::MeshVisualizerGL3D::Flag::Wireframe));
while(!flatState.isLinkFinished() ||
!flatTexturedState.isLinkFinished() ||
!meshVisualizerState.isLinkFinished()) {
// Do other work ...
}
Shaders::FlatGL3D flat{std::move(flatState)};
Shaders::FlatGL3D flatTextured{std::move(flatTexturedState)};
Shaders::MeshVisualizerGL3D meshVisualizer{std::move(meshVisualizerState)};
/* [shaders-async] */
}
/* internal compiler error: in gimplify_init_constructor, at gimplify.c:4271
on GCC 4.8 in the [60] array */
#if !defined(CORRADE_TARGET_GCC) || defined(CORRADE_TARGET_CLANG) || __GNUC__ >= 5

6
src/Magnum/Shaders/DistanceFieldVectorGL.cpp

@ -162,13 +162,13 @@ template<UnsignedInt dimensions> typename DistanceFieldVectorGL<dimensions>::Com
return CompileState{std::move(out), std::move(vert), std::move(frag), version};
}
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>::DistanceFieldVectorGL(CompileState&& cs): DistanceFieldVectorGL{static_cast<DistanceFieldVectorGL&&>(std::move(cs))} {
if (id() == 0) return;
template<UnsignedInt dimensions> DistanceFieldVectorGL<dimensions>::DistanceFieldVectorGL(CompileState&& state): DistanceFieldVectorGL{static_cast<DistanceFieldVectorGL&&>(std::move(state))} {
if(!id()) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
const GL::Version version = state._version;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))

68
src/Magnum/Shaders/DistanceFieldVectorGL.h

@ -121,6 +121,8 @@ example.
*/
template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVectorGL: public GL::AbstractShaderProgram {
public:
class CompileState;
/**
* @brief Vertex position
*
@ -218,6 +220,34 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
typedef Implementation::DistanceFieldVectorGLFlags Flags;
#endif
/**
* @brief Compile asynchronously
* @m_since_latest
*
* Compared to @ref DistanceFieldVectorGL(Flags) can perform an
* asynchronous compilation and linking. See @ref shaders-async for
* more information.
* @see @ref DistanceFieldVectorGL(CompileState&&),
* @ref compile(Flags, UnsignedInt, UnsignedInt)
*/
static CompileState compile(Flags flags = {});
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Compile for a multi-draw scenario asynchronously
* @m_since_latest
*
* Compared to @ref DistanceFieldVectorGL(Flags, UnsignedInt, UnsignedInt)
* can perform an asynchronous compilation and linking. See
* @ref shaders-async for more information.
* @see @ref DistanceFieldVectorGL(CompileState&&), @ref compile(Flags)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
static CompileState compile(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Constructor
* @param flags Flags
@ -226,6 +256,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref DistanceFieldVectorGL(Flags, UnsignedInt, UnsignedInt) with
* @p materialCount and @p drawCount set to @cpp 1 @ce.
* @see @ref compile(Flags)
*/
explicit DistanceFieldVectorGL(Flags flags = {});
@ -251,6 +282,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
* If @p flags don't contain @ref Flag::UniformBuffers,
* @p materialCount and @p drawCount is ignored and the constructor
* behaves the same as @ref DistanceFieldVectorGL(Flags).
* @see @ref compile(Flags, UnsignedInt, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@ -267,6 +299,16 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
explicit DistanceFieldVectorGL(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Finalize an asynchronous compilation
* @m_since_latest
*
* Takes an asynchronous compilation state returned by @ref compile()
* and forms a ready-to-use shader object. See @ref shaders-async for
* more information.
*/
explicit DistanceFieldVectorGL(CompileState&& state);
/**
* @brief Construct without creating the underlying OpenGL object
*
@ -281,20 +323,6 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
*/
explicit DistanceFieldVectorGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
class CompileState;
explicit DistanceFieldVectorGL(CompileState&& cs);
static CompileState compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags);
#endif
/** @brief Copying is not allowed */
DistanceFieldVectorGL(const DistanceFieldVectorGL<dimensions>&) = delete;
@ -617,6 +645,8 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
#endif
private:
/* Creates the GL shader program object but does nothing else.
Internal, used by compile(). */
explicit DistanceFieldVectorGL(NoInitT);
/* Prevent accidentally calling irrelevant functions */
@ -644,15 +674,19 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
#endif
};
/**
@brief Asynchronous compilation state
@m_since_latest
Returned by @ref compile(). See @ref shaders-async for more information.
*/
template<UnsignedInt dimensions> class DistanceFieldVectorGL<dimensions>::CompileState: public DistanceFieldVectorGL<dimensions> {
private:
/* Everything deliberately private except for the inheritance */
friend class DistanceFieldVectorGL;
explicit CompileState(NoCreateT): DistanceFieldVectorGL{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(DistanceFieldVectorGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version):
DistanceFieldVectorGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
explicit CompileState(DistanceFieldVectorGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version): DistanceFieldVectorGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
GL::Shader _vert, _frag;
GL::Version _version;

14
src/Magnum/Shaders/FlatGL.cpp

@ -67,10 +67,10 @@ namespace {
#endif
}
template<UnsignedInt dimensions> typename FlatGL<dimensions>::CompileState FlatGL<dimensions>::compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
template<UnsignedInt dimensions> typename FlatGL<dimensions>::CompileState FlatGL<dimensions>::compile(const Flags flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
) {
#ifndef CORRADE_NO_ASSERT
{
@ -237,13 +237,13 @@ template<UnsignedInt dimensions> typename FlatGL<dimensions>::CompileState FlatG
return CompileState{std::move(out), std::move(vert), std::move(frag), version};
}
template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(CompileState&& cs): FlatGL{static_cast<FlatGL&&>(std::move(cs))} {
if (id() == 0) return;
template<UnsignedInt dimensions> FlatGL<dimensions>::FlatGL(CompileState&& state): FlatGL{static_cast<FlatGL&&>(std::move(state))} {
if(!id()) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
const GL::Version version = state._version;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))

70
src/Magnum/Shaders/FlatGL.h

@ -202,6 +202,8 @@ all shaders, see @ref shaders-usage-multidraw for an example.
*/
template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::AbstractShaderProgram {
public:
class CompileState;
/**
* @brief Vertex position
*
@ -541,6 +543,34 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
typedef Implementation::FlatGLFlags Flags;
#endif
/**
* @brief Compile asynchronously
* @m_since_latest
*
* Compared to @ref FlatGL(Flags) can perform an asynchronous
* compilation and linking. See @ref shaders-async for more
* information.
* @see @ref FlatGL(CompileState&&),
* @ref compile(Flags, UnsignedInt, UnsignedInt)
*/
static CompileState compile(Flags flags = {});
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Compile for a multi-draw scenario asynchronously
* @m_since_latest
*
* Compared to @ref FlatGL(Flags, UnsignedInt, UnsignedInt) can perform
* an asynchronous compilation and linking. See @ref shaders-async for
* more information.
* @see @ref FlatGL(CompileState&&), @ref compile(Flags)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
static CompileState compile(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Constructor
* @param flags Flags
@ -549,6 +579,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref FlatGL(Flags, UnsignedInt, UnsignedInt) with @p materialCount
* and @p drawCount set to @cpp 1 @ce.
* @see @ref compile(Flags)
*/
explicit FlatGL(Flags flags = {});
@ -573,6 +604,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
* If @p flags don't contain @ref Flag::UniformBuffers,
* @p materialCount and @p drawCount is ignored and the constructor
* behaves the same as @ref FlatGL(Flags).
* @see @ref compile(Flags, UnsignedInt, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@ -589,6 +621,16 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
explicit FlatGL(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Finalize an asynchronous compilation
* @m_since_latest
*
* Takes an asynchronous compilation state returned by @ref compile()
* and forms a ready-to-use shader object. See @ref shaders-async for
* more information.
*/
explicit FlatGL(CompileState&& state);
/**
* @brief Construct without creating the underlying OpenGL object
*
@ -603,20 +645,6 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
*/
explicit FlatGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
class CompileState;
explicit FlatGL(CompileState&& cs);
static CompileState compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags);
#endif
/** @brief Copying is not allowed */
FlatGL(const FlatGL<dimensions>&) = delete;
@ -1026,7 +1054,8 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
#endif
private:
/* Creates the GL shader program object but nothing else. Internal, used by compile(). */
/* Creates the GL shader program object but does nothing else.
Internal, used by compile(). */
explicit FlatGL(NoInitT);
/* Prevent accidentally calling irrelevant functions */
@ -1056,14 +1085,19 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT FlatGL: public GL::
#endif
};
/**
@brief Asynchronous compilation state
@m_since_latest
Returned by @ref compile(). See @ref shaders-async for more information.
*/
template<UnsignedInt dimensions> class FlatGL<dimensions>::CompileState: public FlatGL<dimensions> {
private:
/* Everything deliberately private except for the inheritance */
friend class FlatGL;
explicit CompileState(NoCreateT): FlatGL{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(FlatGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version):
FlatGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
explicit CompileState(FlatGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version): FlatGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
GL::Shader _vert, _frag;
GL::Version _version;

60
src/Magnum/Shaders/MeshVisualizerGL.cpp

@ -139,10 +139,9 @@ void MeshVisualizerGLBase::assertExtensions(const FlagsBase flags) {
#endif
}
GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs,
const FlagsBase flags
GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs, const FlagsBase flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
, const UnsignedInt materialCount, UnsignedInt const drawCount
#endif
) {
GL::Context& context = GL::Context::current();
@ -376,12 +375,12 @@ MeshVisualizerGLBase& MeshVisualizerGLBase::bindObjectIdTexture(GL::Texture2DArr
}
MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(Flags flags
MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(const Flags flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
) {
FlagsBase baseFlags = Implementation::MeshVisualizerGLBase::FlagBase(UnsignedInt(flags));
const FlagsBase baseFlags = Implementation::MeshVisualizerGLBase::FlagBase(UnsignedInt(flags));
assertExtensions(baseFlags);
#ifndef MAGNUM_TARGET_GLES2
@ -410,9 +409,9 @@ MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(Flags flags
GL::Shader vert{NoCreate};
GL::Shader frag{NoCreate};
const GL::Version version = setupShaders(vert, frag, rs, baseFlags
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
);
Containers::Optional<GL::Shader> geom;
@ -472,7 +471,7 @@ MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(Flags flags
vert.submitCompile();
frag.submitCompile();
if (geom) geom->submitCompile();
if(geom) geom->submitCompile();
MeshVisualizerGL2D out{NoInit};
out._flags = baseFlags;
@ -482,7 +481,7 @@ MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(Flags flags
#endif
out.attachShaders({vert, frag});
if (geom) out.attachShader(*geom);
if(geom) out.attachShader(*geom);
/* ES3 has this done in the shader directly */
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
@ -519,26 +518,24 @@ MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(Flags flags
return CompileState{std::move(out), std::move(vert), std::move(frag), std::move(geom), flags, version};
}
MeshVisualizerGL2D::MeshVisualizerGL2D(Flags flags) : MeshVisualizerGL2D{compile(flags)} {}
MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags): MeshVisualizerGL2D{compile(flags)} {}
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(Flags flags) {
MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(const Flags flags) {
return compile(flags, 1, 1);
}
MeshVisualizerGL2D::MeshVisualizerGL2D(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount)
: MeshVisualizerGL2D{compile(flags, materialCount, drawCount)} {}
MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags, const UnsignedInt materialCount, const UnsignedInt drawCount): MeshVisualizerGL2D{compile(flags, materialCount, drawCount)} {}
#endif
MeshVisualizerGL2D::MeshVisualizerGL2D(CompileState&& cs)
: MeshVisualizerGL2D{static_cast<MeshVisualizerGL2D&&>(std::move(cs))} {
if (id() == 0) return;
MeshVisualizerGL2D::MeshVisualizerGL2D(CompileState&& state): MeshVisualizerGL2D{static_cast<MeshVisualizerGL2D&&>(std::move(state))} {
if(!id()) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
Flags flags = cs._flags;
const GL::Version version = state._version;
const Flags flags = state._flags;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
@ -744,9 +741,9 @@ MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(Flags flags
GL::Shader vert{NoCreate};
GL::Shader frag{NoCreate};
const GL::Version version = setupShaders(vert, frag, rs, baseFlags
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
);
Containers::Optional<GL::Shader> geom;
@ -840,7 +837,7 @@ MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(Flags flags
vert.submitCompile();
frag.submitCompile();
if (geom) geom->submitCompile();
if(geom) geom->submitCompile();
MeshVisualizerGL3D out{NoInit};
out._flags = baseFlags;
@ -850,7 +847,7 @@ MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(Flags flags
#endif
out.attachShaders({vert, frag});
if (geom) out.attachShader(*geom);
if(geom) out.attachShader(*geom);
/* ES3 has this done in the shader directly */
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
@ -903,14 +900,14 @@ MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(Flags flags
return CompileState{std::move(out), std::move(vert), std::move(frag), std::move(geom), flags, version};
}
MeshVisualizerGL3D::MeshVisualizerGL3D(CompileState&& cs): MeshVisualizerGL3D{static_cast<MeshVisualizerGL3D&&>(std::move(cs))} {
if (id() == 0) return;
MeshVisualizerGL3D::MeshVisualizerGL3D(CompileState&& state): MeshVisualizerGL3D{static_cast<MeshVisualizerGL3D&&>(std::move(state))} {
if(!id()) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
Flags flags = cs._flags;
const GL::Version version = state._version;
Flags flags = state._flags;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
@ -1043,15 +1040,14 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(CompileState&& cs): MeshVisualizerGL3D{st
static_cast<void>(version);
}
MeshVisualizerGL3D::MeshVisualizerGL3D(Flags flags) : MeshVisualizerGL3D{compile(flags)} {}
MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags): MeshVisualizerGL3D{compile(flags)} {}
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(Flags flags) {
MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(const Flags flags) {
return compile(flags, 1, 1);
}
MeshVisualizerGL3D::MeshVisualizerGL3D(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount):
MeshVisualizerGL3D{compile(flags, materialCount, drawCount)} {}
MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags, const UnsignedInt materialCount, const UnsignedInt drawCount): MeshVisualizerGL3D{compile(flags, materialCount, drawCount)} {}
#endif
MeshVisualizerGL3D& MeshVisualizerGL3D::setTransformationMatrix(const Matrix4& matrix) {

154
src/Magnum/Shaders/MeshVisualizerGL.h

@ -76,8 +76,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGLBase: public GL::AbstractShaderProgr
explicit MeshVisualizerGLBase(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
static MAGNUM_SHADERS_LOCAL void assertExtensions(const FlagsBase flags);
static MAGNUM_SHADERS_LOCAL GL::Version setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs,
const FlagsBase flags
static MAGNUM_SHADERS_LOCAL GL::Version setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs, const FlagsBase flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
@ -189,6 +188,8 @@ texture offset (or offset and layer).
*/
class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisualizerGLBase {
public:
class CompileState;
/**
* @brief Vertex position
*
@ -446,6 +447,35 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
/** @brief Flags */
typedef Containers::EnumSet<Flag> Flags;
/**
* @brief Compile asynchronously
* @m_since_latest
*
* Compared to @ref MeshVisualizerGL2D(Flags) can perform an
* asynchronous compilation and linking. See @ref shaders-async for
* more information.
* @see @ref MeshVisualizerGL2D(CompileState&&),
* @ref compile(Flags, UnsignedInt, UnsignedInt)
*/
/* No default value, consistently with MeshVisualizerGL2D(Flags) */
static CompileState compile(Flags flags);
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Compile for a multi-draw scenario asynchronously
* @m_since_latest
*
* Compared to @ref MeshVisualizerGL2D(Flags, UnsignedInt, UnsignedInt)
* can perform an asynchronous compilation and linking. See
* @ref shaders-async for more information.
* @see @ref MeshVisualizerGL2D(CompileState&&), @ref compile(Flags)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
static CompileState compile(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Constructor
* @param flags Flags
@ -456,6 +486,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref MeshVisualizerGL2D(Flags, UnsignedInt, UnsignedInt) with
* @p materialCount and @p drawCount set to @cpp 1 @ce.
* @see @ref compile(Flags)
*/
explicit MeshVisualizerGL2D(Flags flags);
@ -481,6 +512,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
* If @p flags don't contain @ref Flag::UniformBuffers,
* @p materialCount and @p drawCount is ignored and the constructor
* behaves the same as @ref MeshVisualizerGL2D(Flags).
* @see @ref compile(Flags, UnsignedInt, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@ -496,6 +528,16 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
explicit MeshVisualizerGL2D(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Finalize an asynchronous compilation
* @m_since_latest
*
* Takes an asynchronous compilation state returned by @ref compile()
* and forms a ready-to-use shader object. See @ref shaders-async for
* more information.
*/
explicit MeshVisualizerGL2D(CompileState&& state);
/**
* @brief Construct without creating the underlying OpenGL object
*
@ -510,20 +552,6 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
*/
explicit MeshVisualizerGL2D(NoCreateT) noexcept: Implementation::MeshVisualizerGLBase{NoCreate} {}
class CompileState;
explicit MeshVisualizerGL2D(CompileState&& cs);
static CompileState compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags);
#endif
/** @brief Copying is not allowed */
MeshVisualizerGL2D(const MeshVisualizerGL2D&) = delete;
@ -881,19 +909,26 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
#endif
private:
explicit MeshVisualizerGL2D(NoInitT) : Implementation::MeshVisualizerGLBase{NoInit} {}
/* Creates the GL shader program object but does nothing else.
Internal, used by compile(). */
explicit MeshVisualizerGL2D(NoInitT): Implementation::MeshVisualizerGLBase{NoInit} {}
Int _transformationProjectionMatrixUniform{9};
};
/**
@brief Asynchronous compilation state
@m_since_latest
Returned by @ref compile(). See @ref shaders-async for more information.
*/
class MeshVisualizerGL2D::CompileState: public MeshVisualizerGL2D {
private:
/* Everything deliberately private except for the inheritance */
friend class MeshVisualizerGL2D;
explicit CompileState(NoCreateT): MeshVisualizerGL2D{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(MeshVisualizerGL2D&& shader, GL::Shader&& vert, GL::Shader&& frag, Containers::Optional<GL::Shader>&& geom, Flags flags, GL::Version version):
MeshVisualizerGL2D{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _geom{std::move(geom)}, _flags{flags}, _version{version} {}
explicit CompileState(MeshVisualizerGL2D&& shader, GL::Shader&& vert, GL::Shader&& frag, Containers::Optional<GL::Shader>&& geom, Flags flags, GL::Version version): MeshVisualizerGL2D{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _geom{std::move(geom)}, _flags{flags}, _version{version} {}
GL::Shader _vert, _frag;
Containers::Optional<GL::Shader> _geom;
@ -1139,6 +1174,8 @@ similar for all shaders, see @ref shaders-usage-multidraw for an example.
*/
class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisualizerGLBase {
public:
class CompileState;
/**
* @brief Vertex position
*
@ -1653,6 +1690,35 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
/** @brief Flags */
typedef Containers::EnumSet<Flag> Flags;
/**
* @brief Compile asynchronously
* @m_since_latest
*
* Compared to @ref MeshVisualizerGL3D(Flags) can perform an
* asynchronous compilation and linking. See @ref shaders-async for
* more information.
* @see @ref MeshVisualizerGL3D(CompileState&&),
* @ref compile(Flags, UnsignedInt, UnsignedInt)
*/
/* No default value, consistently with MeshVisualizerGL3D(Flags) */
static CompileState compile(Flags flags);
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Compile for a multi-draw scenario asynchronously
* @m_since_latest
*
* Compared to @ref MeshVisualizerGL3D(Flags, UnsignedInt, UnsignedInt)
* can perform an asynchronous compilation and linking. See
* @ref shaders-async for more information.
* @see @ref MeshVisualizerGL3D(CompileState&&), @ref compile(Flags)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
static CompileState compile(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Constructor
* @param flags Flags
@ -1666,6 +1732,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref MeshVisualizerGL3D(Flags, UnsignedInt, UnsignedInt) with
* @p materialCount and @p drawCount set to @cpp 1 @ce.
* @see @ref compile(Flags)
*/
explicit MeshVisualizerGL3D(Flags flags);
@ -1702,8 +1769,8 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
* @ref MeshVisualizerDrawUniform3D::materialId.
*
* If @p flags don't contain @ref Flag::UniformBuffers,
* @p materialCount and @p drawCount is ignored and the constructor
* behaves the same as @ref MeshVisualizerGL3D(Flags).
* @p materialCount and @p drawCount is ignored and the constructo
* @see @ref compile(Flags, UnsignedInt, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@ -1734,20 +1801,15 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
*/
explicit MeshVisualizerGL3D(NoCreateT) noexcept: Implementation::MeshVisualizerGLBase{NoCreate} {}
class CompileState;
explicit MeshVisualizerGL3D(CompileState&& cs);
static CompileState compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags);
#endif
/**
* @brief Finalize an asynchronous compilation
* @m_since_latest
*
* Takes an asynchronous compilation state returned by @ref compile()
* and forms a ready-to-use shader object. See @ref shaders-async for
* more information.
*/
explicit MeshVisualizerGL3D(CompileState&& state);
/** @brief Copying is not allowed */
MeshVisualizerGL3D(const MeshVisualizerGL3D&) = delete;
@ -2377,7 +2439,9 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
#endif
private:
explicit MeshVisualizerGL3D(NoInitT) : Implementation::MeshVisualizerGLBase{NoInit} {}
/* Creates the GL shader program object but does nothing else.
Internal, used by compile(). */
explicit MeshVisualizerGL3D(NoInitT): Implementation::MeshVisualizerGLBase{NoInit} {}
Int _transformationMatrixUniform{9},
_projectionMatrixUniform{10};
@ -2388,14 +2452,19 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
#endif
};
class MeshVisualizerGL3D::CompileState : public MeshVisualizerGL3D {
private:
/**
@brief Asynchronous compilation state
@m_since_latest
Returned by @ref compile(). See @ref shaders-async for more information.
*/
class MeshVisualizerGL3D::CompileState: public MeshVisualizerGL3D {
/* Everything deliberately private except for the inheritance */
friend class MeshVisualizerGL3D;
explicit CompileState(NoCreateT) : MeshVisualizerGL3D{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
explicit CompileState(NoCreateT): MeshVisualizerGL3D{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(MeshVisualizerGL3D&& shader, GL::Shader&& vert, GL::Shader&& frag, Containers::Optional<GL::Shader>&& geom, Flags flags, GL::Version version) :
MeshVisualizerGL3D{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _geom{std::move(geom)}, _flags{flags}, _version{version} {}
explicit CompileState(MeshVisualizerGL3D&& shader, GL::Shader&& vert, GL::Shader&& frag, Containers::Optional<GL::Shader>&& geom, Flags flags, GL::Version version): MeshVisualizerGL3D{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _geom{std::move(geom)}, _flags{flags}, _version{version} {}
GL::Shader _vert, _frag;
Containers::Optional<GL::Shader> _geom;
@ -2403,7 +2472,6 @@ private:
GL::Version _version;
};
/** @debugoperatorclassenum{MeshVisualizerGL2D,MeshVisualizerGL2D::Flag} */
MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizerGL2D::Flag value);

13
src/Magnum/Shaders/PhongGL.cpp

@ -347,13 +347,13 @@ PhongGL::CompileState PhongGL::compile(const Flags flags, const UnsignedInt ligh
return CompileState{std::move(out), std::move(vert), std::move(frag), version};
}
PhongGL::PhongGL(CompileState&& cs): PhongGL{static_cast<PhongGL&&>(std::move(cs))} {
if (id() == 0) return;
PhongGL::PhongGL(CompileState&& state): PhongGL{static_cast<PhongGL&&>(std::move(state))} {
if(!id()) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
const GL::Version version = state._version;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
@ -463,15 +463,14 @@ PhongGL::PhongGL(CompileState&& cs): PhongGL{static_cast<PhongGL&&>(std::move(cs
static_cast<void>(version);
}
PhongGL::PhongGL(Flags flags, UnsignedInt lightCount): PhongGL{compile(flags, lightCount)} {}
PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount): PhongGL{compile(flags, lightCount)} {}
#ifndef MAGNUM_TARGET_GLES2
PhongGL::CompileState PhongGL::compile(Flags flags, UnsignedInt lightCount) {
PhongGL::CompileState PhongGL::compile(const Flags flags, const UnsignedInt lightCount) {
return compile(flags, lightCount, 1, 1);
}
PhongGL::PhongGL(Flags flags, UnsignedInt lightCount, UnsignedInt materialCount, UnsignedInt drawCount):
PhongGL{compile(flags, lightCount, materialCount, drawCount)} {}
PhongGL::PhongGL(const Flags flags, const UnsignedInt lightCount, const UnsignedInt materialCount, const UnsignedInt drawCount): PhongGL{compile(flags, lightCount, materialCount, drawCount)} {}
#endif
PhongGL& PhongGL::setAmbientColor(const Magnum::Color4& color) {

69
src/Magnum/Shaders/PhongGL.h

@ -297,6 +297,8 @@ Besides that, the usage is similar for all shaders, see
*/
class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
public:
class CompileState;
/**
* @brief Vertex position
*
@ -754,6 +756,34 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
*/
typedef Containers::EnumSet<Flag> Flags;
/**
* @brief Compile asynchronously
* @m_since_latest
*
* Compared to @ref PhongGL(Flags, UnsignedInt) can perform an
* asynchronous compilation and linking. See @ref shaders-async for
* more information.
* @see @ref PhongGL(CompileState&&),
* @ref compile(Flags, UnsignedInt, UnsignedInt, UnsignedInt)
*/
static CompileState compile(Flags flags = {}, UnsignedInt lightCount = 1);
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Compile for a multi-draw scenario asynchronously
* @m_since_latest
*
* Compared to @ref PhongGL(Flags, UnsignedInt, UnsignedInt, UnsignedInt)
* can perform an asynchronous compilation and linking. See
* @ref shaders-async for more information.
* @see @ref PhongGL(CompileState&&), @ref compile(Flags, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
static CompileState compile(Flags flags, UnsignedInt lightCount, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Constructor
* @param flags Flags
@ -763,6 +793,7 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref PhongGL(Flags, UnsignedInt, UnsignedInt, UnsignedInt) with
* @p materialCount and @p drawCount set to @cpp 1 @ce.
* @see @ref compile(Flags, UnsignedInt)
*/
explicit PhongGL(Flags flags = {}, UnsignedInt lightCount = 1);
@ -792,6 +823,7 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
* If @p flags don't contain @ref Flag::UniformBuffers,
* @p materialCount and @p drawCount is ignored and the constructor
* behaves the same as @ref PhongGL(Flags, UnsignedInt).
* @see @ref compile(Flags, UnsignedInt, UnsignedInt, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@ -808,6 +840,16 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
explicit PhongGL(Flags flags, UnsignedInt lightCount, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Finalize an asynchronous compilation
* @m_since_latest
*
* Takes an asynchronous compilation state returned by @ref compile()
* and forms a ready-to-use shader object. See @ref shaders-async for
* more information.
*/
explicit PhongGL(CompileState&& state);
/**
* @brief Construct without creating the underlying OpenGL object
*
@ -822,20 +864,6 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
*/
explicit PhongGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
class CompileState;
explicit PhongGL(CompileState&& cs);
static CompileState compile(Flags flags, UnsignedInt lightCount
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags, UnsignedInt lightCount);
#endif
/** @brief Copying is not allowed */
PhongGL(const PhongGL&) = delete;
@ -1759,6 +1787,8 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
#endif
private:
/* Creates the GL shader program object but does nothing else.
Internal, used by compile(). */
explicit PhongGL(NoInitT) {}
/* Prevent accidentally calling irrelevant functions */
@ -1801,14 +1831,19 @@ class MAGNUM_SHADERS_EXPORT PhongGL: public GL::AbstractShaderProgram {
#endif
};
/**
@brief Asynchronous compilation state
@m_since_latest
Returned by @ref compile(). See @ref shaders-async for more information.
*/
class PhongGL::CompileState: public PhongGL {
private:
/* Everything deliberately private except for the inheritance */
friend class PhongGL;
explicit CompileState(NoCreateT): PhongGL{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(PhongGL&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version):
PhongGL{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
explicit CompileState(PhongGL&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version): PhongGL{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
GL::Shader _vert, _frag;
GL::Version _version;

25
src/Magnum/Shaders/Test/DistanceFieldVectorGLTest.cpp

@ -31,8 +31,8 @@
#include <Corrade/PluginManager/Manager.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Format.h>
#include <Corrade/Utility/System.h>
#include <Corrade/Utility/Path.h>
#include <Corrade/Utility/System.h>
#ifdef CORRADE_TARGET_APPLE
#include <Corrade/Containers/Pair.h>
@ -388,13 +388,13 @@ template<UnsignedInt dimensions> void DistanceFieldVectorGLTest::construct() {
template<UnsignedInt dimensions> void DistanceFieldVectorGLTest::constructAsync() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
auto compileState = DistanceFieldVectorGL<dimensions>::compile(DistanceFieldVectorGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(compileState.flags(), DistanceFieldVectorGL2D::Flag::TextureTransformation);
typename DistanceFieldVectorGL<dimensions>::CompileState state = DistanceFieldVectorGL<dimensions>::compile(DistanceFieldVectorGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(state.flags(), DistanceFieldVectorGL2D::Flag::TextureTransformation);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
DistanceFieldVectorGL<dimensions> shader{std::move(compileState)};
DistanceFieldVectorGL<dimensions> shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), DistanceFieldVectorGL2D::Flag::TextureTransformation);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
@ -451,24 +451,23 @@ template<UnsignedInt dimensions> void DistanceFieldVectorGLTest::constructUnifor
template<UnsignedInt dimensions> void DistanceFieldVectorGLTest::constructUniformBuffersAsync() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::uniform_buffer_object>())
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
auto compileState = DistanceFieldVectorGL<dimensions>::compile(DistanceFieldVectorGL2D::Flag::UniformBuffers, 16, 4);
CORRADE_COMPARE(compileState.flags(), DistanceFieldVectorGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(compileState.materialCount(), 16);
CORRADE_COMPARE(compileState.drawCount(), 4);
typename DistanceFieldVectorGL<dimensions>::CompileState state = DistanceFieldVectorGL<dimensions>::compile(DistanceFieldVectorGL2D::Flag::UniformBuffers, 16, 48);
CORRADE_COMPARE(state.flags(), DistanceFieldVectorGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(state.materialCount(), 16);
CORRADE_COMPARE(state.drawCount(), 48);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
DistanceFieldVectorGL<dimensions> shader{std::move(compileState)};
DistanceFieldVectorGL<dimensions> shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), DistanceFieldVectorGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(shader.materialCount(), 16);
CORRADE_COMPARE(shader.drawCount(), 4);
CORRADE_COMPARE(shader.drawCount(), 48);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
{

27
src/Magnum/Shaders/Test/FlatGLTest.cpp

@ -31,8 +31,8 @@
#include <Corrade/PluginManager/Manager.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/System.h>
#include <Corrade/Utility/Path.h>
#include <Corrade/Utility/System.h>
#ifdef CORRADE_TARGET_APPLE
#include <Corrade/Containers/Pair.h>
@ -866,13 +866,14 @@ template<UnsignedInt dimensions> void FlatGLTest::construct() {
template<UnsignedInt dimensions> void FlatGLTest::constructAsync() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
auto compileState = FlatGL<dimensions>::compile(FlatGL2D::Flag::Textured|FlatGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(compileState.flags(), FlatGL2D::Flag::Textured|FlatGL2D::Flag::TextureTransformation);
while(!compileState.isLinkFinished())
typename FlatGL<dimensions>::CompileState state = FlatGL<dimensions>::compile(FlatGL2D::Flag::Textured|FlatGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(state.flags(), FlatGL2D::Flag::Textured|FlatGL2D::Flag::TextureTransformation);
while(!state.isLinkFinished())
Utility::System::sleep(100);
FlatGL<dimensions> shader{std::move(compileState)};
FlatGL<dimensions> shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), FlatGL2D::Flag::Textured|FlatGL2D::Flag::TextureTransformation);
CORRADE_VERIFY(shader.id());
@ -938,18 +939,18 @@ template<UnsignedInt dimensions> void FlatGLTest::constructUniformBuffersAsync()
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
auto compileState = FlatGL<dimensions>::compile(FlatGL2D::Flag::UniformBuffers|FlatGL2D::Flag::AlphaMask, 1, 1);
CORRADE_COMPARE(compileState.flags(), FlatGL2D::Flag::UniformBuffers|FlatGL2D::Flag::AlphaMask);
CORRADE_COMPARE(compileState.materialCount(), 1);
CORRADE_COMPARE(compileState.drawCount(), 1);
typename FlatGL<dimensions>::CompileState state = FlatGL<dimensions>::compile(FlatGL2D::Flag::UniformBuffers|FlatGL2D::Flag::AlphaMask, 8, 48);
CORRADE_COMPARE(state.flags(), FlatGL2D::Flag::UniformBuffers|FlatGL2D::Flag::AlphaMask);
CORRADE_COMPARE(state.materialCount(), 8);
CORRADE_COMPARE(state.drawCount(), 48);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
FlatGL<dimensions> shader{std::move(compileState)};
FlatGL<dimensions> shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), FlatGL2D::Flag::UniformBuffers|FlatGL2D::Flag::AlphaMask);
CORRADE_COMPARE(shader.materialCount(), 1);
CORRADE_COMPARE(shader.drawCount(), 1);
CORRADE_COMPARE(shader.materialCount(), 8);
CORRADE_COMPARE(shader.drawCount(), 48);
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)

46
src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp

@ -31,8 +31,8 @@
#include <Corrade/PluginManager/Manager.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/System.h>
#include <Corrade/Utility/Path.h>
#include <Corrade/Utility/System.h>
#ifdef CORRADE_TARGET_APPLE
#include <Corrade/Containers/Pair.h>
@ -1416,13 +1416,13 @@ void MeshVisualizerGLTest::construct2D() {
void MeshVisualizerGLTest::construct2DAsync() {
auto compileState = MeshVisualizerGL2D::compile(MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
CORRADE_COMPARE(compileState.flags(), MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
MeshVisualizerGL2D::CompileState state = MeshVisualizerGL2D::compile(MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
CORRADE_COMPARE(state.flags(), MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL2D shader{std::move(compileState)};
MeshVisualizerGL2D shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
@ -1521,15 +1521,15 @@ void MeshVisualizerGLTest::constructUniformBuffers2DAsync() {
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
auto compileState = MeshVisualizerGL2D::compile( MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader, 8, 55);
CORRADE_COMPARE(compileState.flags(), MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
CORRADE_COMPARE(compileState.materialCount(), 8);
CORRADE_COMPARE(compileState.drawCount(), 55);
MeshVisualizerGL2D::CompileState state = MeshVisualizerGL2D::compile( MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader, 8, 55);
CORRADE_COMPARE(state.flags(), MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
CORRADE_COMPARE(state.materialCount(), 8);
CORRADE_COMPARE(state.drawCount(), 55);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL2D shader{std::move(compileState)};
MeshVisualizerGL2D shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), MeshVisualizerGL2D::Flag::UniformBuffers|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader);
CORRADE_COMPARE(shader.materialCount(), 8);
CORRADE_COMPARE(shader.drawCount(), 55);
@ -1607,13 +1607,13 @@ void MeshVisualizerGLTest::construct3D() {
}
void MeshVisualizerGLTest::construct3DAsync() {
auto compileState = MeshVisualizerGL3D::compile(MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
CORRADE_COMPARE(compileState.flags(), MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
MeshVisualizerGL3D::CompileState state = MeshVisualizerGL3D::compile(MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
CORRADE_COMPARE(state.flags(), MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL3D shader{std::move(compileState)};
MeshVisualizerGL3D shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
@ -1711,18 +1711,18 @@ void MeshVisualizerGLTest::constructUniformBuffers3DAsync() {
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
auto compileState = MeshVisualizerGL3D::compile(MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader, 6, 28);
CORRADE_COMPARE(compileState.flags(), MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
CORRADE_COMPARE(compileState.materialCount(), 6);
CORRADE_COMPARE(compileState.drawCount(), 28);
MeshVisualizerGL3D::CompileState state = MeshVisualizerGL3D::compile(MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader, 6, 28);
CORRADE_COMPARE(state.flags(), MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
CORRADE_COMPARE(state.materialCount(), 6);
CORRADE_COMPARE(state.drawCount(), 28);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL3D shader{std::move(compileState)};
MeshVisualizerGL3D shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), MeshVisualizerGL3D::Flag::UniformBuffers|MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader);
CORRADE_COMPARE(compileState.materialCount(), 6);
CORRADE_COMPARE(compileState.drawCount(), 28);
CORRADE_COMPARE(state.materialCount(), 6);
CORRADE_COMPARE(state.drawCount(), 28);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
{

26
src/Magnum/Shaders/Test/PhongGLTest.cpp

@ -31,9 +31,9 @@
#include <Corrade/PluginManager/Manager.h>
#include <Corrade/TestSuite/Compare/Numeric.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/System.h>
#include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/Path.h>
#include <Corrade/Utility/System.h>
#ifdef CORRADE_TARGET_APPLE
#include <Corrade/Containers/Pair.h>
@ -1199,14 +1199,14 @@ void PhongGLTest::construct() {
}
void PhongGLTest::constructAsync() {
auto compileState = PhongGL::compile(PhongGL::Flag::SpecularTexture|PhongGL::Flag::InstancedTextureOffset, 3);
CORRADE_COMPARE(compileState.flags(), PhongGL::Flag::SpecularTexture|PhongGL::Flag::InstancedTextureOffset);
CORRADE_COMPARE(compileState.lightCount(), 3);
PhongGL::CompileState state = PhongGL::compile(PhongGL::Flag::SpecularTexture|PhongGL::Flag::InstancedTextureOffset, 3);
CORRADE_COMPARE(state.flags(), PhongGL::Flag::SpecularTexture|PhongGL::Flag::InstancedTextureOffset);
CORRADE_COMPARE(state.lightCount(), 3);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
PhongGL shader{std::move(compileState)};
PhongGL shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), PhongGL::Flag::SpecularTexture|PhongGL::Flag::InstancedTextureOffset);
CORRADE_COMPARE(shader.lightCount(), 3);
CORRADE_VERIFY(shader.isLinkFinished());
@ -1270,16 +1270,16 @@ void PhongGLTest::constructUniformBuffersAsync() {
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
auto compileState = PhongGL::compile(PhongGL::Flag::UniformBuffers|PhongGL::Flag::LightCulling, 8, 8, 24);
CORRADE_COMPARE(compileState.flags(), PhongGL::Flag::UniformBuffers|PhongGL::Flag::LightCulling);
CORRADE_COMPARE(compileState.lightCount(), 8);
CORRADE_COMPARE(compileState.materialCount(), 8);
CORRADE_COMPARE(compileState.drawCount(), 24);
PhongGL::CompileState state = PhongGL::compile(PhongGL::Flag::UniformBuffers|PhongGL::Flag::LightCulling, 8, 8, 24);
CORRADE_COMPARE(state.flags(), PhongGL::Flag::UniformBuffers|PhongGL::Flag::LightCulling);
CORRADE_COMPARE(state.lightCount(), 8);
CORRADE_COMPARE(state.materialCount(), 8);
CORRADE_COMPARE(state.drawCount(), 24);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
PhongGL shader{std::move(compileState)};
PhongGL shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), PhongGL::Flag::UniformBuffers|PhongGL::Flag::LightCulling);
CORRADE_COMPARE(shader.lightCount(), 8);
CORRADE_COMPARE(shader.materialCount(), 8);

26
src/Magnum/Shaders/Test/VectorGLTest.cpp

@ -31,8 +31,8 @@
#include <Corrade/PluginManager/Manager.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/System.h>
#include <Corrade/Utility/Path.h>
#include <Corrade/Utility/System.h>
#ifdef CORRADE_TARGET_APPLE
#include <Corrade/Containers/Pair.h>
@ -384,13 +384,13 @@ template<UnsignedInt dimensions> void VectorGLTest::construct() {
template<UnsignedInt dimensions> void VectorGLTest::constructAsync() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
auto compileState = VectorGL<dimensions>::compile(VectorGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(compileState.flags(), VectorGL2D::Flag::TextureTransformation);
typename VectorGL<dimensions>::CompileState state = VectorGL<dimensions>::compile(VectorGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(state.flags(), VectorGL2D::Flag::TextureTransformation);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
VectorGL<dimensions> shader{std::move(compileState)};
VectorGL<dimensions> shader{std::move(state)};
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_COMPARE(shader.flags(), VectorGL2D::Flag::TextureTransformation);
CORRADE_VERIFY(shader.id());
@ -452,19 +452,19 @@ template<UnsignedInt dimensions> void VectorGLTest::constructUniformBuffersAsync
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
auto compileState = VectorGL<dimensions>::compile(VectorGL2D::Flag::UniformBuffers|VectorGL2D::Flag::TextureTransformation, 1, 1);
CORRADE_COMPARE(compileState.flags(), VectorGL2D::Flag::UniformBuffers|VectorGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(compileState.materialCount(), 1);
CORRADE_COMPARE(compileState.drawCount(), 1);
typename VectorGL<dimensions>::CompileState state = VectorGL<dimensions>::compile(VectorGL2D::Flag::UniformBuffers|VectorGL2D::Flag::TextureTransformation, 15, 42);
CORRADE_COMPARE(state.flags(), VectorGL2D::Flag::UniformBuffers|VectorGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(state.materialCount(), 15);
CORRADE_COMPARE(state.drawCount(), 42);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
VectorGL<dimensions> shader{std::move(compileState)};
VectorGL<dimensions> shader{std::move(state)};
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_COMPARE(shader.flags(), VectorGL2D::Flag::UniformBuffers|VectorGL2D::Flag::TextureTransformation);
CORRADE_COMPARE(shader.materialCount(), 1);
CORRADE_COMPARE(shader.drawCount(), 1);
CORRADE_COMPARE(shader.materialCount(), 15);
CORRADE_COMPARE(shader.drawCount(), 42);
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)

18
src/Magnum/Shaders/Test/VertexColorGLTest.cpp

@ -29,8 +29,8 @@
#include <Corrade/PluginManager/Manager.h>
#include <Corrade/Utility/DebugStl.h>
#include <Corrade/Utility/Format.h>
#include <Corrade/Utility/System.h>
#include <Corrade/Utility/Path.h>
#include <Corrade/Utility/System.h>
#ifdef CORRADE_TARGET_APPLE
#include <Corrade/Containers/Pair.h>
@ -321,12 +321,12 @@ template<UnsignedInt dimensions> void VertexColorGLTest::construct() {
template<UnsignedInt dimensions> void VertexColorGLTest::constructAsync() {
setTestCaseTemplateName(Utility::format("{}", dimensions));
auto compileState = VertexColorGL<dimensions>::compile({});
typename VertexColorGL<dimensions>::CompileState state = VertexColorGL<dimensions>::compile({});
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
VertexColorGL<dimensions> shader{std::move(compileState)};
VertexColorGL<dimensions> shader{std::move(state)};
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
{
@ -387,14 +387,14 @@ template<UnsignedInt dimensions> void VertexColorGLTest::constructUniformBuffers
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
auto compileState = VertexColorGL<dimensions>::compile(VertexColorGL2D::Flag::UniformBuffers, 63);
CORRADE_COMPARE(compileState.flags(), VertexColorGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(compileState.drawCount(), 63);
typename VertexColorGL<dimensions>::CompileState state = VertexColorGL<dimensions>::compile(VertexColorGL2D::Flag::UniformBuffers, 63);
CORRADE_COMPARE(state.flags(), VertexColorGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(state.drawCount(), 63);
while(!compileState.isLinkFinished())
while(!state.isLinkFinished())
Utility::System::sleep(100);
VertexColorGL<dimensions> shader{std::move(compileState)};
VertexColorGL<dimensions> shader{std::move(state)};
CORRADE_COMPARE(shader.flags(), VertexColorGL2D::Flag::UniformBuffers);
CORRADE_COMPARE(shader.drawCount(), 63);
CORRADE_VERIFY(shader.isLinkFinished());

14
src/Magnum/Shaders/VectorGL.cpp

@ -164,14 +164,13 @@ template<UnsignedInt dimensions> typename VectorGL<dimensions>::CompileState Vec
return CompileState{std::move(out), std::move(vert), std::move(frag), version};
}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(CompileState&& cs): VectorGL{static_cast<VectorGL&&>(std::move(cs))} {
if (id() == 0) return;
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(CompileState&& state): VectorGL{static_cast<VectorGL&&>(std::move(state))} {
if(!id()) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
const GL::Version version = state._version;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
@ -227,15 +226,14 @@ template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(CompileState&& c
static_cast<void>(version);
}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(Flags flags): VectorGL{compile(flags)} {}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flags): VectorGL{compile(flags)} {}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> typename VectorGL<dimensions>::CompileState VectorGL<dimensions>::compile(Flags flags) {
template<UnsignedInt dimensions> typename VectorGL<dimensions>::CompileState VectorGL<dimensions>::compile(const Flags flags) {
return compile(flags, 1, 1);
}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount):
VectorGL{compile(flags, materialCount, drawCount)} {}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(const Flags flags, const UnsignedInt materialCount, const UnsignedInt drawCount): VectorGL{compile(flags, materialCount, drawCount)} {}
#endif
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(NoInitT) {}

70
src/Magnum/Shaders/VectorGL.h

@ -116,6 +116,8 @@ example.
*/
template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL::AbstractShaderProgram {
public:
class CompileState;
/**
* @brief Vertex position
*
@ -213,6 +215,34 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
typedef Implementation::VectorGLFlags Flags;
#endif
/**
* @brief Compile asynchronously
* @m_since_latest
*
* Compared to @ref VectorGL(Flags) can perform an asynchronous
* compilation and linking. See @ref shaders-async for more
* information.
* @see @ref VectorGL(CompileState&&),
* @ref compile(Flags, UnsignedInt, UnsignedInt)
*/
static CompileState compile(Flags flags = {});
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Compile for a multi-draw scenario asynchronously
* @m_since_latest
*
* Compared to @ref VectorGL(Flags, UnsignedInt, UnsignedInt) can
* perform an asynchronous compilation and linking. See
* @ref shaders-async for more information.
* @see @ref VectorGL(CompileState&&), @ref compile(Flags)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
static CompileState compile(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Constructor
* @param flags Flags
@ -221,6 +251,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref VectorGL(Flags, UnsignedInt, UnsignedInt) with @p materialCount
* and @p drawCount set to @cpp 1 @ce.
* @see @ref compile(Flags)
*/
explicit VectorGL(Flags flags = {});
@ -244,6 +275,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
*
* If @p flags don't contain @ref Flag::UniformBuffers, @p drawCount is
* ignored and the constructor behaves the same as @ref VectorGL(Flags).
* @see @ref compile(Flags, UnsignedInt, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@ -260,6 +292,16 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
explicit VectorGL(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount);
#endif
/**
* @brief Finalize an asynchronous compilation
* @m_since_latest
*
* Takes an asynchronous compilation state returned by @ref compile()
* and forms a ready-to-use shader object. See @ref shaders-async for
* more information.
*/
explicit VectorGL(CompileState&& state);
/**
* @brief Construct without creating the underlying OpenGL object
*
@ -274,20 +316,6 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
*/
explicit VectorGL(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
class CompileState;
explicit VectorGL(CompileState&& cs);
static CompileState compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags);
#endif
/** @brief Copying is not allowed */
VectorGL(const VectorGL<dimensions>&) = delete;
@ -569,7 +597,8 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
#endif
private:
/* Creates the GL shader program object but nothing else. Internal, used by compile(). */
/* Creates the GL shader program object but does nothing else.
Internal, used by compile(). */
explicit VectorGL(NoInitT);
/* Prevent accidentally calling irrelevant functions */
@ -595,14 +624,19 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VectorGL: public GL
#endif
};
/**
@brief Asynchronous compilation state
@m_since_latest
Returned by @ref compile(). See @ref shaders-async for more information.
*/
template<UnsignedInt dimensions> class VectorGL<dimensions>::CompileState: public VectorGL<dimensions> {
private:
/* Everything deliberately private except for the inheritance */
friend class VectorGL;
explicit CompileState(NoCreateT): VectorGL{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(VectorGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version):
VectorGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
explicit CompileState(VectorGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version): VectorGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
GL::Shader _vert, _frag;
GL::Version _version;

13
src/Magnum/Shaders/VertexColorGL.cpp

@ -142,13 +142,13 @@ template<UnsignedInt dimensions> typename VertexColorGL<dimensions>::CompileStat
return CompileState{std::move(out), std::move(vert), std::move(frag), version};
}
template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(CompileState&& cs): VertexColorGL{static_cast<VertexColorGL&&>(std::move(cs))} {
if (id() == 0) return;
template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(CompileState&& state): VertexColorGL{static_cast<VertexColorGL&&>(std::move(state))} {
if(!id()) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
const GL::Version version = state._version;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
@ -190,15 +190,14 @@ template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(Compil
static_cast<void>(version);
}
template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(Flags flags): VertexColorGL{compile(flags)} {}
template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(const Flags flags): VertexColorGL{compile(flags)} {}
#ifndef MAGNUM_TARGET_GLES2
template<UnsignedInt dimensions> typename VertexColorGL<dimensions>::CompileState VertexColorGL<dimensions>::compile(Flags flags) {
template<UnsignedInt dimensions> typename VertexColorGL<dimensions>::CompileState VertexColorGL<dimensions>::compile(const Flags flags) {
return compile(flags, 1);
}
template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(Flags flags, UnsignedInt drawCount):
VertexColorGL{compile(flags, drawCount)} {}
template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(const Flags flags, const UnsignedInt drawCount): VertexColorGL{compile(flags, drawCount)} {}
#endif
template<UnsignedInt dimensions> VertexColorGL<dimensions>::VertexColorGL(NoInitT) {}

69
src/Magnum/Shaders/VertexColorGL.h

@ -111,6 +111,8 @@ similar for all shaders, see @ref shaders-usage-multidraw for an example.
*/
template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: public GL::AbstractShaderProgram {
public:
class CompileState;
/**
* @brief Vertex position
*
@ -208,6 +210,34 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: publ
typedef Implementation::VertexColorGLFlags Flags;
#endif
/**
* @brief Compile asynchronously
* @m_since_latest
*
* Compared to @ref VertexColorGL(Flags) can perform an asynchronous
* compilation and linking. See @ref shaders-async for more
* information.
* @see @ref VertexColorGL(CompileState&&),
* @ref compile(Flags, UnsignedInt)
*/
static CompileState compile(Flags flags = {});
#ifndef MAGNUM_TARGET_GLES2
/**
* @brief Compile for a multi-draw scenario asynchronously
* @m_since_latest
*
* Compared to @ref VertexColorGL(Flags, UnsignedInt) can perform an
* asynchronous compilation and linking. See @ref shaders-async for
* more information.
* @see @ref VertexColorGL(CompileState&&), @ref compile(Flags)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
*/
static CompileState compile(Flags flags, UnsignedInt drawCount);
#endif
/**
* @brief Constructor
* @param flags Flags
@ -216,6 +246,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: publ
* scenario (without @ref Flag::UniformBuffers set), it's equivalent to
* @ref VertexColorGL(Flags, UnsignedInt) with @p drawCount set to
* @cpp 1 @ce.
* @see @ref compile(Flags)
*/
explicit VertexColorGL(Flags flags = {});
@ -235,6 +266,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: publ
* If @p flags don't contain @ref Flag::UniformBuffers, @p drawCount is
* ignored and the constructor behaves the same as
* @ref VertexColorGL(Flags).
* @see @ref compile(Flags, UnsignedInt)
* @requires_gl31 Extension @gl_extension{ARB,uniform_buffer_object}
* @requires_gles30 Uniform buffers are not available in OpenGL ES 2.0.
* @requires_webgl20 Uniform buffers are not available in WebGL 1.0.
@ -251,6 +283,16 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: publ
explicit VertexColorGL(Flags flags, UnsignedInt drawCount);
#endif
/**
* @brief Finalize an asynchronous compilation
* @m_since_latest
*
* Takes an asynchronous compilation state returned by @ref compile()
* and forms a ready-to-use shader object. See @ref shaders-async for
* more information.
*/
explicit VertexColorGL(CompileState&& state);
/**
* @brief Construct without creating the underlying OpenGL object
*
@ -265,20 +307,6 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: publ
*/
explicit VertexColorGL(NoCreateT) noexcept: AbstractShaderProgram{NoCreate} {}
class CompileState;
explicit VertexColorGL(CompileState&& cs);
static CompileState compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt drawCount
#endif
);
#ifndef MAGNUM_TARGET_GLES2
static CompileState compile(Flags flags);
#endif
/** @brief Copying is not allowed */
VertexColorGL(const VertexColorGL<dimensions>&) = delete;
@ -421,6 +449,8 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: publ
#endif
private:
/* Creates the GL shader program object but does nothing else.
Internal, used by compile(). */
explicit VertexColorGL(NoInitT);
/* Prevent accidentally calling irrelevant functions */
@ -443,14 +473,19 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT VertexColorGL: publ
#endif
};
/**
@brief Asynchronous compilation state
@m_since_latest
Returned by @ref compile(). See @ref shaders-async for more information.
*/
template<UnsignedInt dimensions> class VertexColorGL<dimensions>::CompileState: public VertexColorGL<dimensions> {
private:
/* Everything deliberately private except for the inheritance */
friend class VertexColorGL;
explicit CompileState(NoCreateT): VertexColorGL{NoCreate}, _vert{NoCreate}, _frag{NoCreate} {}
CompileState(VertexColorGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version):
VertexColorGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
explicit CompileState(VertexColorGL<dimensions>&& shader, GL::Shader&& vert, GL::Shader&& frag, GL::Version version): VertexColorGL<dimensions>{std::move(shader)}, _vert{std::move(vert)}, _frag{std::move(frag)}, _version{version} {}
GL::Shader _vert, _frag;
GL::Version _version;

Loading…
Cancel
Save