Browse Source

MeshVisualizerGL3D & tests

pull/576/head
Vladislav Oleshko 4 years ago
parent
commit
e1ec1a6794
  1. 307
      src/Magnum/Shaders/MeshVisualizerGL.cpp
  2. 79
      src/Magnum/Shaders/MeshVisualizerGL.h
  3. 339
      src/Magnum/Shaders/Test/MeshVisualizerGLTest.cpp
  4. 1
      src/Magnum/Shaders/VectorGL.cpp

307
src/Magnum/Shaders/MeshVisualizerGL.cpp

@ -26,7 +26,6 @@
#include "MeshVisualizerGL.h"
#include <Corrade/Containers/EnumSet.hpp>
#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/Reference.h>
#include <Corrade/Utility/FormatStl.h>
#include <Corrade/Utility/Resource.h>
@ -72,17 +71,7 @@ namespace {
namespace Implementation {
MeshVisualizerGLBase::MeshVisualizerGLBase(FlagsBase flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
):
_flags{flags}
#ifndef MAGNUM_TARGET_GLES2
, _materialCount{materialCount},
_drawCount{drawCount}
#endif
{
void MeshVisualizerGLBase::assertExtensions(const FlagsBase flags) {
#ifndef MAGNUM_TARGET_GLES2
#ifndef CORRADE_NO_ASSERT
Int countMutuallyExclusive = 0;
@ -120,7 +109,7 @@ MeshVisualizerGLBase::MeshVisualizerGLBase(FlagsBase flags
#endif
#ifndef MAGNUM_TARGET_GLES2
if(_flags & FlagBase::Wireframe && !(_flags & FlagBase::NoGeometryShader)) {
if(flags & FlagBase::Wireframe && !(flags & FlagBase::NoGeometryShader)) {
#ifndef MAGNUM_TARGET_GLES
MAGNUM_ASSERT_GL_VERSION_SUPPORTED(GL::Version::GL320);
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::ARB::geometry_shader4);
@ -129,12 +118,12 @@ MeshVisualizerGLBase::MeshVisualizerGLBase(FlagsBase flags
#endif
}
#else
if(_flags & FlagBase::Wireframe)
if(flags & FlagBase::Wireframe)
MAGNUM_ASSERT_GL_EXTENSION_SUPPORTED(GL::Extensions::OES::standard_derivatives);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(_flags & FlagBase::PrimitiveId && !(_flags >= FlagBase::PrimitiveIdFromVertexId)) {
if(flags & FlagBase::PrimitiveId && !(flags >= FlagBase::PrimitiveIdFromVertexId)) {
#ifndef MAGNUM_TARGET_GLES
MAGNUM_ASSERT_GL_VERSION_SUPPORTED(GL::Version::GL320);
#else
@ -150,18 +139,23 @@ MeshVisualizerGLBase::MeshVisualizerGLBase(FlagsBase flags
#endif
}
GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs) const {
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
#endif
) {
GL::Context& context = GL::Context::current();
#ifndef MAGNUM_TARGET_GLES
const GL::Version version = context.supportedVersion({GL::Version::GL320, GL::Version::GL310, GL::Version::GL300, GL::Version::GL210});
/* Extended in MeshVisualizerGL3D for TBN visualization */
CORRADE_INTERNAL_ASSERT(!(_flags & FlagBase::Wireframe) || _flags & FlagBase::NoGeometryShader || version >= GL::Version::GL320);
CORRADE_INTERNAL_ASSERT(!(flags & FlagBase::Wireframe) || flags & FlagBase::NoGeometryShader || version >= GL::Version::GL320);
#elif !defined(MAGNUM_TARGET_WEBGL)
/* ES 3.2 needed for gl_PrimitiveID */
const GL::Version version = context.supportedVersion({GL::Version::GLES320, GL::Version::GLES310, GL::Version::GLES300, GL::Version::GLES200});
/* Extended in MeshVisualizerGL3D for TBN visualization */
CORRADE_INTERNAL_ASSERT(!(_flags & FlagBase::Wireframe) || _flags & FlagBase::NoGeometryShader || version >= GL::Version::GLES310);
CORRADE_INTERNAL_ASSERT(!(flags & FlagBase::Wireframe) || flags & FlagBase::NoGeometryShader || version >= GL::Version::GLES310);
#else
const GL::Version version = context.supportedVersion({GL::Version::GLES300, GL::Version::GLES200});
#endif
@ -169,18 +163,18 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra
vert = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Vertex);
frag = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Fragment);
vert.addSource(_flags & FlagBase::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
vert.addSource(flags & FlagBase::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(_flags >= FlagBase::ObjectIdTexture ? "#define TEXTURED\n" : "")
.addSource(_flags & FlagBase::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
.addSource(_flags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(flags >= FlagBase::ObjectIdTexture ? "#define TEXTURED\n" : "")
.addSource(flags & FlagBase::TextureTransformation ? "#define TEXTURE_TRANSFORMATION\n" : "")
.addSource(flags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
#endif
.addSource(_flags & FlagBase::InstancedTransformation ? "#define INSTANCED_TRANSFORMATION\n" : "")
.addSource(flags & FlagBase::InstancedTransformation ? "#define INSTANCED_TRANSFORMATION\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(_flags >= FlagBase::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags >= FlagBase::PrimitiveIdFromVertexId ? "#define PRIMITIVE_ID_FROM_VERTEX_ID\n" : "")
.addSource(flags >= FlagBase::InstancedTextureOffset ? "#define INSTANCED_TEXTURE_OFFSET\n" : "")
.addSource(flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(flags >= FlagBase::PrimitiveIdFromVertexId ? "#define PRIMITIVE_ID_FROM_VERTEX_ID\n" : "")
#endif
#ifdef MAGNUM_TARGET_WEBGL
.addSource("#define SUBSCRIPTING_WORKAROUND\n")
@ -190,38 +184,38 @@ GL::Version MeshVisualizerGLBase::setupShaders(GL::Shader& vert, GL::Shader& fra
#endif
;
#ifndef MAGNUM_TARGET_GLES2
if(_flags >= FlagBase::UniformBuffers) {
if(flags >= FlagBase::UniformBuffers) {
vert.addSource(Utility::formatString(
"#define UNIFORM_BUFFERS\n"
"#define DRAW_COUNT {}\n"
"#define MATERIAL_COUNT {}\n",
_drawCount,
_materialCount));
vert.addSource(_flags >= FlagBase::MultiDraw ? "#define MULTI_DRAW\n" : "");
drawCount,
materialCount));
vert.addSource(flags >= FlagBase::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
frag.addSource(_flags & FlagBase::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
frag.addSource(flags & FlagBase::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(_flags & FlagBase::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(_flags >= FlagBase::ObjectIdTexture ? "#define OBJECT_ID_TEXTURE\n" : "")
.addSource(_flags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
.addSource(flags & FlagBase::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(flags >= FlagBase::ObjectIdTexture ? "#define OBJECT_ID_TEXTURE\n" : "")
.addSource(flags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(flags & FlagBase::PrimitiveId ?
(flags >= FlagBase::PrimitiveIdFromVertexId ?
"#define PRIMITIVE_ID_FROM_VERTEX_ID\n" :
"#define PRIMITIVE_ID\n") : "")
#endif
;
#ifndef MAGNUM_TARGET_GLES2
if(_flags >= FlagBase::UniformBuffers) {
if(flags >= FlagBase::UniformBuffers) {
frag.addSource(Utility::formatString(
"#define UNIFORM_BUFFERS\n"
"#define DRAW_COUNT {}\n"
"#define MATERIAL_COUNT {}\n",
_drawCount,
_materialCount));
frag.addSource(_flags >= FlagBase::MultiDraw ? "#define MULTI_DRAW\n" : "");
drawCount,
materialCount));
frag.addSource(flags >= FlagBase::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
@ -382,21 +376,20 @@ MeshVisualizerGLBase& MeshVisualizerGLBase::bindObjectIdTexture(GL::Texture2DArr
}
MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
MeshVisualizerGL2D::CompileState MeshVisualizerGL2D::compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
): Implementation::MeshVisualizerGLBase{Implementation::MeshVisualizerGLBase::FlagBase(UnsignedInt(flags))
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
} {
) {
FlagsBase baseFlags = Implementation::MeshVisualizerGLBase::FlagBase(UnsignedInt(flags));
assertExtensions(baseFlags);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL2D: at least one visualization feature has to be enabled", );
"Shaders::MeshVisualizerGL2D: at least one visualization feature has to be enabled", CompileState{NoCreate});
#else
CORRADE_ASSERT(flags & (Flag::Wireframe & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL2D: at least Flag::Wireframe has to be enabled", );
"Shaders::MeshVisualizerGL2D: at least Flag::Wireframe has to be enabled", CompileState{NoCreate});
#endif
/* Has to be here and not in the base class in order to have it exit the
@ -404,9 +397,9 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
otherwise */
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || materialCount,
"Shaders::MeshVisualizerGL2D: material count can't be zero", );
"Shaders::MeshVisualizerGL2D: material count can't be zero", CompileState{NoCreate});
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || drawCount,
"Shaders::MeshVisualizerGL2D: draw count can't be zero", );
"Shaders::MeshVisualizerGL2D: draw count can't be zero", CompileState{NoCreate});
#endif
#ifndef MAGNUM_TARGET_GLES
@ -416,7 +409,12 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
Utility::Resource rs{"MagnumShadersGL"};
GL::Shader vert{NoCreate};
GL::Shader frag{NoCreate};
const GL::Version version = setupShaders(vert, frag, rs);
const GL::Version version = setupShaders(vert, frag, rs, baseFlags
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
);
Containers::Optional<GL::Shader> geom;
vert.addSource("#define TWO_DIMENSIONS\n")
/* Pass NO_GEOMETRY_SHADER not only when NoGeometryShader but also when
@ -439,19 +437,19 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
frag.addSource(rs.getString("generic.glsl"))
.addSource(rs.getString("MeshVisualizer.frag"));
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
Containers::Optional<GL::Shader> geom;
if(flags & Flag::Wireframe && !(flags & Flag::NoGeometryShader)) {
geom = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Geometry);
(*geom)
.addSource("#define WIREFRAME_RENDERING\n#define MAX_VERTICES 3\n")
.addSource(_flags >= FlagBase::ObjectIdTexture ? "#define TEXTURED\n" : "")
.addSource(_flags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(_flags & FlagBase::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
.addSource(baseFlags >= FlagBase::ObjectIdTexture ? "#define TEXTURED\n" : "")
.addSource(baseFlags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(baseFlags & FlagBase::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(baseFlags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(baseFlags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(baseFlags & FlagBase::PrimitiveId ?
(baseFlags >= FlagBase::PrimitiveIdFromVertexId ?
"#define PRIMITIVE_ID_FROM_VERTEX_ID\n" :
"#define PRIMITIVE_ID\n") : "");
#ifndef MAGNUM_TARGET_GLES2
@ -461,8 +459,8 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
"#define UNIFORM_BUFFERS\n"
"#define DRAW_COUNT {}\n"
"#define MATERIAL_COUNT {}\n",
_drawCount,
_materialCount));
drawCount,
materialCount));
geom->addSource(flags >= Flag::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
@ -472,48 +470,75 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
static_cast<void>(version);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(geom) CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, *geom, frag}));
else
#endif
CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag}));
vert.submitCompile();
frag.submitCompile();
if (geom) geom->submitCompile();
attachShaders({vert, frag});
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(geom) attachShader(*geom);
MeshVisualizerGL2D out{NoInit};
out._flags = baseFlags;
#ifndef MAGNUM_TARGET_GLES2
out._materialCount = materialCount;
out._drawCount = drawCount;
#endif
out.attachShaders({vert, frag});
if (geom) out.attachShader(*geom);
/* ES3 has this done in the shader directly */
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version))
#endif
{
bindAttributeLocation(Position::Location, "position");
out.bindAttributeLocation(Position::Location, "position");
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::ObjectIdTexture)
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
out.bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
if(flags >= Flag::InstancedObjectId)
bindAttributeLocation(ObjectId::Location, "instanceObjectId");
out.bindAttributeLocation(ObjectId::Location, "instanceObjectId");
#endif
if(flags & Flag::InstancedTransformation)
bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix");
out.bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix");
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::InstancedTextureOffset)
bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset");
out.bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset");
#endif
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
#ifndef MAGNUM_TARGET_GLES
if(!context.isVersionSupported(GL::Version::GL310))
#endif
{
bindAttributeLocation(VertexIndex::Location, "vertexIndex");
out.bindAttributeLocation(VertexIndex::Location, "vertexIndex");
}
#endif
}
#endif
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
out.submitLink();
return CompileState{std::move(out), std::move(vert), std::move(frag), std::move(geom), flags, version};
}
MeshVisualizerGL2D::MeshVisualizerGL2D(Flags flags) : MeshVisualizerGL2D{compile(flags)} {}
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizer2D::CompileState MeshVisualizer2D::compile(Flags flags) {
return compile(flags, 1, 1);
}
MeshVisualizerGL2D::MeshVisualizerGL2D(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount)
: MeshVisualizerGL2D{compile(flags, materialCount, drawCount)} {}
#endif
MeshVisualizer2D::MeshVisualizerGL2D(CompileState&& cs)
: MeshVisualizerGL2D{static_cast<MeshVisualizerGL2D&&>(std::move(cs))} {
if (id() == 0) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
Flags flags = cs._flags;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
@ -610,10 +635,6 @@ MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags
#endif
}
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGL2D::MeshVisualizerGL2D(const Flags flags): MeshVisualizerGL2D{flags, 1, 1} {}
#endif
MeshVisualizerGL2D& MeshVisualizerGL2D::setViewportSize(const Vector2& size) {
/* Not asserting here, since the relation to wireframe is a bit vague.
Also it's an ugly hack that should be removed, ideally. */
@ -674,25 +695,24 @@ MeshVisualizerGL2D& MeshVisualizerGL2D::bindDrawBuffer(GL::Buffer& buffer, const
}
#endif
MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(Flags flags
#ifndef MAGNUM_TARGET_GLES2
, const UnsignedInt materialCount, const UnsignedInt drawCount
#endif
): Implementation::MeshVisualizerGLBase{Implementation::MeshVisualizerGLBase::FlagBase(UnsignedInt(flags))
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
} {
) {
FlagsBase baseFlags = Implementation::MeshVisualizerGLBase::FlagBase(UnsignedInt(flags));
assertExtensions(baseFlags);
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", );
"Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", CompileState{NoCreate});
CORRADE_ASSERT(!(flags & Flag::NoGeometryShader && flags & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection)),
"Shaders::MeshVisualizerGL3D: geometry shader has to be enabled when rendering TBN direction", );
"Shaders::MeshVisualizerGL3D: geometry shader has to be enabled when rendering TBN direction", CompileState{NoCreate});
CORRADE_ASSERT(!(flags & Flag::BitangentDirection && flags & Flag::BitangentFromTangentDirection),
"Shaders::MeshVisualizerGL3D: Flag::BitangentDirection and Flag::BitangentFromTangentDirection are mutually exclusive", );
"Shaders::MeshVisualizerGL3D: Flag::BitangentDirection and Flag::BitangentFromTangentDirection are mutually exclusive", CompileState{NoCreate});
#elif !defined(MAGNUM_TARGET_GLES2)
CORRADE_ASSERT(flags & ((Flag::Wireframe|Flag::ObjectId|Flag::VertexId|Flag::PrimitiveIdFromVertexId) & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", );
"Shaders::MeshVisualizerGL3D: at least one visualization feature has to be enabled", CompileState{NoCreate});
#else
CORRADE_ASSERT(flags & (Flag::Wireframe & ~Flag::NoGeometryShader),
"Shaders::MeshVisualizerGL3D: at least Flag::Wireframe has to be enabled", );
@ -700,7 +720,7 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
CORRADE_ASSERT(!(flags >= Flag::InstancedObjectId) || !(flags & Flag::BitangentDirection),
"Shaders::MeshVisualizerGL3D: Bitangent attribute binding conflicts with the ObjectId attribute, use a Tangent4 attribute with instanced object ID rendering instead", );
"Shaders::MeshVisualizerGL3D: Bitangent attribute binding conflicts with the ObjectId attribute, use a Tangent4 attribute with instanced object ID rendering instead", CompileState{NoCreate});
#endif
/* Has to be here and not in the base class in order to have it exit the
@ -708,9 +728,9 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
otherwise */
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || materialCount,
"Shaders::MeshVisualizerGL3D: material count can't be zero", );
"Shaders::MeshVisualizerGL3D: material count can't be zero", CompileState{NoCreate});
CORRADE_ASSERT(!(flags >= Flag::UniformBuffers) || drawCount,
"Shaders::MeshVisualizerGL3D: draw count can't be zero", );
"Shaders::MeshVisualizerGL3D: draw count can't be zero", CompileState{NoCreate});
#endif
#ifndef MAGNUM_TARGET_GLES
@ -720,7 +740,12 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
Utility::Resource rs{"MagnumShadersGL"};
GL::Shader vert{NoCreate};
GL::Shader frag{NoCreate};
const GL::Version version = setupShaders(vert, frag, rs);
const GL::Version version = setupShaders(vert, frag, rs, baseFlags
#ifndef MAGNUM_TARGET_GLES2
, materialCount, drawCount
#endif
);
Containers::Optional<GL::Shader> geom;
/* Expands the check done for wireframe in MeshVisualizerBase with TBN */
#ifndef MAGNUM_TARGET_GLES
@ -768,7 +793,6 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
.addSource(rs.getString("MeshVisualizer.frag"));
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
Containers::Optional<GL::Shader> geom;
if(flags & (Flag::Wireframe|Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection) && !(flags & Flag::NoGeometryShader)) {
Int maxVertices = 0;
if(flags & Flag::Wireframe) maxVertices += 3;
@ -781,13 +805,13 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
(*geom)
.addSource(Utility::formatString("#define MAX_VERTICES {}\n", maxVertices))
.addSource(flags & Flag::Wireframe ? "#define WIREFRAME_RENDERING\n" : "")
.addSource(_flags >= FlagBase::ObjectIdTexture ? "#define TEXTURED\n" : "")
.addSource(_flags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(_flags & FlagBase::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(_flags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(_flags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(_flags & FlagBase::PrimitiveId ?
(_flags >= FlagBase::PrimitiveIdFromVertexId ?
.addSource(baseFlags >= FlagBase::ObjectIdTexture ? "#define TEXTURED\n" : "")
.addSource(baseFlags & FlagBase::TextureArrays ? "#define TEXTURE_ARRAYS\n" : "")
.addSource(baseFlags & FlagBase::ObjectId ? "#define OBJECT_ID\n" : "")
.addSource(baseFlags >= FlagBase::InstancedObjectId ? "#define INSTANCED_OBJECT_ID\n" : "")
.addSource(baseFlags & FlagBase::VertexId ? "#define VERTEX_ID\n" : "")
.addSource(baseFlags & FlagBase::PrimitiveId ?
(baseFlags >= FlagBase::PrimitiveIdFromVertexId ?
"#define PRIMITIVE_ID_FROM_VERTEX_ID\n" :
"#define PRIMITIVE_ID\n") : "")
.addSource(flags & Flag::TangentDirection ? "#define TANGENT_DIRECTION\n" : "")
@ -800,8 +824,8 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
"#define UNIFORM_BUFFERS\n"
"#define DRAW_COUNT {}\n"
"#define MATERIAL_COUNT {}\n",
_drawCount,
_materialCount));
drawCount,
materialCount));
geom->addSource(flags >= Flag::MultiDraw ? "#define MULTI_DRAW\n" : "");
}
#endif
@ -811,50 +835,53 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
static_cast<void>(version);
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(geom) CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, *geom, frag}));
else
#endif
CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag}));
vert.submitCompile();
frag.submitCompile();
if (geom) geom->submitCompile();
attachShaders({vert, frag});
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(geom) attachShader(*geom);
MeshVisualizerGL3D out{NoInit};
out._flags = baseFlags;
#ifndef MAGNUM_TARGET_GLES2
out._materialCount = materialCount;
out._drawCount = drawCount;
#endif
out.attachShaders({vert, frag});
if (geom) out.attachShader(*geom);
/* ES3 has this done in the shader directly */
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_attrib_location>(version))
#endif
{
bindAttributeLocation(Position::Location, "position");
out.bindAttributeLocation(Position::Location, "position");
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::ObjectIdTexture)
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
out.bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
if(flags >= Flag::InstancedObjectId)
bindAttributeLocation(ObjectId::Location, "instanceObjectId");
out.bindAttributeLocation(ObjectId::Location, "instanceObjectId");
#endif
if(flags & Flag::InstancedTransformation) {
bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix");
out.bindAttributeLocation(TransformationMatrix::Location, "instancedTransformationMatrix");
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(flags & (Flag::TangentDirection|Flag::BitangentFromTangentDirection|Flag::BitangentDirection|Flag::NormalDirection))
bindAttributeLocation(NormalMatrix::Location, "instancedNormalMatrix");
out.bindAttributeLocation(NormalMatrix::Location, "instancedNormalMatrix");
#endif
}
#ifndef MAGNUM_TARGET_GLES2
if(flags >= Flag::InstancedTextureOffset)
bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset");
out.bindAttributeLocation(TextureOffset::Location, "instancedTextureOffset");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(flags & Flag::TangentDirection ||
flags & Flag::BitangentFromTangentDirection)
bindAttributeLocation(Tangent4::Location, "tangent");
out.bindAttributeLocation(Tangent4::Location, "tangent");
if(flags & Flag::BitangentDirection)
bindAttributeLocation(Bitangent::Location, "bitangent");
out.bindAttributeLocation(Bitangent::Location, "bitangent");
if(flags & Flag::NormalDirection ||
flags & Flag::BitangentFromTangentDirection)
bindAttributeLocation(Normal::Location, "normal");
out.bindAttributeLocation(Normal::Location, "normal");
#endif
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
@ -862,13 +889,37 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
if(!context.isVersionSupported(GL::Version::GL310))
#endif
{
bindAttributeLocation(VertexIndex::Location, "vertexIndex");
out.bindAttributeLocation(VertexIndex::Location, "vertexIndex");
}
#endif
}
#endif
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
out.submitLink();
return CompileState{std::move(out), std::move(vert), std::move(frag), std::move(geom), flags, version};
}
MeshVisualizerGL3D::MeshVisualizerGL3D(Flags flags) : MeshVisualizerGL3D{compile(flags)} {}
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGL3D::CompileState MeshVisualizerGL3D::compile(Flags flags) {
return compile(flags, 1, 1);
}
MeshVisualizerGL3D::MeshVisualizerGL3D(Flags flags, UnsignedInt materialCount, UnsignedInt drawCount)
: MeshVisualizerGL3D{compile(flags, materialCount, drawCount)} {}
#endif
MeshVisualizerGL3D::MeshVisualizerGL3D(CompileState&& cs)
: MeshVisualizerGL3D{static_cast<MeshVisualizerGL3D&&>(std::move(cs))} {
if (id() == 0) return;
CORRADE_INTERNAL_ASSERT_OUTPUT(checkLink());
const GL::Context& context = GL::Context::current();
const GL::Version version = cs._version;
Flags flags = cs._flags;
#ifndef MAGNUM_TARGET_GLES
if(!context.isExtensionSupported<GL::Extensions::ARB::explicit_uniform_location>(version))
@ -998,10 +1049,6 @@ MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags
#endif
}
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGL3D::MeshVisualizerGL3D(const Flags flags): MeshVisualizerGL3D{flags, 1, 1} {}
#endif
MeshVisualizerGL3D& MeshVisualizerGL3D::setTransformationMatrix(const Matrix4& matrix) {
#ifndef MAGNUM_TARGET_GLES2
CORRADE_ASSERT(!(flags() >= Flag::UniformBuffers),

79
src/Magnum/Shaders/MeshVisualizerGL.h

@ -32,8 +32,10 @@
#include <Corrade/Utility/Utility.h>
#include <Corrade/Containers/Optional.h>
#include "Magnum/DimensionTraits.h"
#include "Magnum/GL/AbstractShaderProgram.h"
#include "Magnum/GL/Shader.h"
#include "Magnum/Shaders/GenericGL.h"
#include "Magnum/Shaders/visibility.h"
@ -69,14 +71,17 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGLBase: public GL::AbstractShaderProgr
CORRADE_ENUMSET_FRIEND_OPERATORS(FlagsBase)
explicit MeshVisualizerGLBase(FlagsBase flags
explicit MeshVisualizerGLBase(NoInitT) {}
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
#ifndef MAGNUM_TARGET_GLES2
, UnsignedInt materialCount, UnsignedInt drawCount
#endif
);
explicit MeshVisualizerGLBase(NoCreateT) noexcept: GL::AbstractShaderProgram{NoCreate} {}
MAGNUM_SHADERS_LOCAL GL::Version setupShaders(GL::Shader& vert, GL::Shader& frag, const Utility::Resource& rs) const;
#ifndef MAGNUM_TARGET_GLES2
MeshVisualizerGLBase& setTextureMatrix(const Matrix3& matrix);
@ -505,6 +510,20 @@ 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;
@ -862,9 +881,26 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL2D: public Implementation::MeshVisua
#endif
private:
explicit MeshVisualizerGL2D(NoInitT) : Implementation::MeshVisualizerGLBase{NoInit} {}
Int _transformationProjectionMatrixUniform{9};
};
class MeshVisualizerGL2D::CompileState : public MeshVisualizerGL2D {
private:
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} {}
GL::Shader _vert, _frag;
Containers::Optional<GL::Shader> _geom;
Flags _flags;
GL::Version _version;
};
/**
@brief 3D mesh visualization OpenGL shader
@m_since_latest
@ -1639,7 +1675,7 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
* @m_deprecated_since{2020,06} Use @ref MeshVisualizerGL3D(Flags)
* instead.
*/
explicit CORRADE_DEPRECATED("use MeshVisualizerGL3D(Flags) instead") MeshVisualizerGL3D(): MeshVisualizerGL3D{{}} {}
explicit CORRADE_DEPRECATED("use MeshVisualizerGL3D(Flags) instead") MeshVisualizerGL3D(): MeshVisualizerGL3D{Flags{}} {}
#endif
#ifndef MAGNUM_TARGET_GLES2
@ -1698,6 +1734,21 @@ 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 Copying is not allowed */
MeshVisualizerGL3D(const MeshVisualizerGL3D&) = delete;
@ -2326,6 +2377,8 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
#endif
private:
explicit MeshVisualizerGL3D(NoInitT) : Implementation::MeshVisualizerGLBase{NoInit} {}
Int _transformationMatrixUniform{9},
_projectionMatrixUniform{10};
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
@ -2335,6 +2388,22 @@ class MAGNUM_SHADERS_EXPORT MeshVisualizerGL3D: public Implementation::MeshVisua
#endif
};
class MeshVisualizerGL3D::CompileState : public MeshVisualizerGL3D {
private:
friend class MeshVisualizerGL3D;
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} {}
GL::Shader _vert, _frag;
Containers::Optional<GL::Shader> _geom;
Flags _flags;
GL::Version _version;
};
/** @debugoperatorclassenum{MeshVisualizerGL2D,MeshVisualizerGL2D::Flag} */
MAGNUM_SHADERS_EXPORT Debug& operator<<(Debug& debug, MeshVisualizerGL2D::Flag value);

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

@ -31,6 +31,7 @@
#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>
#ifdef CORRADE_TARGET_APPLE
@ -88,12 +89,16 @@ struct MeshVisualizerGLTest: GL::OpenGLTester {
explicit MeshVisualizerGLTest();
void construct2D();
void construct2DAsync();
#ifndef MAGNUM_TARGET_GLES2
void constructUniformBuffers2D();
void constructUniformBuffers2DAsync();
#endif
void construct3D();
void construct3DAsync();
#ifndef MAGNUM_TARGET_GLES2
void constructUniformBuffers3D();
void constructUniformBuffers3DAsync();
#endif
void construct2DInvalid();
@ -1055,17 +1060,23 @@ MeshVisualizerGLTest::MeshVisualizerGLTest() {
addInstancedTests({&MeshVisualizerGLTest::construct2D},
Containers::arraySize(ConstructData2D));
addTests({&MeshVisualizerGLTest::construct2DAsync});
#ifndef MAGNUM_TARGET_GLES2
addInstancedTests({&MeshVisualizerGLTest::constructUniformBuffers2D},
Containers::arraySize(ConstructUniformBuffersData2D));
addTests({&MeshVisualizerGLTest::constructUniformBuffers2DAsync});
#endif
addInstancedTests({&MeshVisualizerGLTest::construct3D},
Containers::arraySize(ConstructData3D));
addTests({&MeshVisualizerGLTest::construct3DAsync});
#ifndef MAGNUM_TARGET_GLES2
addInstancedTests({&MeshVisualizerGLTest::constructUniformBuffers3D},
Containers::arraySize(ConstructUniformBuffersData3D));
addTests({&MeshVisualizerGLTest::constructUniformBuffers3DAsync});
#endif
addInstancedTests({&MeshVisualizerGLTest::construct2DInvalid},
@ -1403,6 +1414,78 @@ void MeshVisualizerGLTest::construct2D() {
MAGNUM_VERIFY_NO_GL_ERROR();
}
void MeshVisualizerGLTest::construct2DAsync() {
constexpr struct {
const char* name;
MeshVisualizerGL2D::Flags flags;
} data {
"wireframe w/o GS", MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader
};
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
if((data.flags & MeshVisualizerGL2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(data.flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL300)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES300)
#endif
) CORRADE_SKIP("gl_VertexID not supported.");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(data.flags & MeshVisualizerGL2D::Flag::PrimitiveId && !(data.flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId) &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL320)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES320)
#endif
) CORRADE_SKIP("gl_PrimitiveID not supported.");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if((data.flags & MeshVisualizerGL2D::Flag::Wireframe) && !(data.flags & MeshVisualizerGL2D::Flag::NoGeometryShader)) {
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::geometry_shader4>())
CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported.");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::geometry_shader>())
CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported.");
#endif
#ifdef MAGNUM_TARGET_GLES
if(GL::Context::current().isExtensionSupported<GL::Extensions::NV::shader_noperspective_interpolation>())
CORRADE_INFO("Using" << GL::Extensions::NV::shader_noperspective_interpolation::string());
#endif
}
#endif
auto compileState = MeshVisualizerGL2D::compile(data.flags);
CORRADE_COMPARE(compileState.flags(), data.flags);
while(!compileState.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL2D shader{std::move(compileState)};
CORRADE_COMPARE(shader.flags(), data.flags);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)
CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly.");
#endif
CORRADE_VERIFY(shader.validate().first);
}
MAGNUM_VERIFY_NO_GL_ERROR();
}
#ifndef MAGNUM_TARGET_GLES2
void MeshVisualizerGLTest::constructUniformBuffers2D() {
auto&& data = ConstructUniformBuffersData2D[testCaseInstanceId()];
@ -1480,6 +1563,99 @@ void MeshVisualizerGLTest::constructUniformBuffers2D() {
MAGNUM_VERIFY_NO_GL_ERROR();
}
void MeshVisualizerGLTest::constructUniformBuffers2DAsync() {
constexpr struct {
const char* name;
MeshVisualizerGL2D::Flags flags;
UnsignedInt materialCount, drawCount;
} data {
"multidraw with wireframe w/o GS and vertex ID", MeshVisualizerGL2D::Flag::MultiDraw|MeshVisualizerGL2D::Flag::Wireframe|MeshVisualizerGL2D::Flag::NoGeometryShader|MeshVisualizerGL2D::Flag::VertexId, 8, 55
};
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
if((data.flags & MeshVisualizerGL2D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
#ifndef MAGNUM_TARGET_WEBGL
if(data.flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL300)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES300)
#endif
) CORRADE_SKIP("gl_VertexID not supported.");
#endif
#ifndef MAGNUM_TARGET_WEBGL
if(data.flags & MeshVisualizerGL2D::Flag::PrimitiveId && !(data.flags >= MeshVisualizerGL2D::Flag::PrimitiveIdFromVertexId) &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL320)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES320)
#endif
) CORRADE_SKIP("gl_PrimitiveID not supported.");
#endif
#ifndef MAGNUM_TARGET_WEBGL
if((data.flags & MeshVisualizerGL2D::Flag::Wireframe) && !(data.flags & MeshVisualizerGL2D::Flag::NoGeometryShader)) {
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::geometry_shader4>())
CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported.");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::geometry_shader>())
CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported.");
#endif
#ifdef MAGNUM_TARGET_GLES
if(GL::Context::current().isExtensionSupported<GL::Extensions::NV::shader_noperspective_interpolation>())
CORRADE_INFO("Using" << GL::Extensions::NV::shader_noperspective_interpolation::string());
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
if(data.flags & MeshVisualizerGL2D::Flag::UniformBuffers && !GL::Context::current().isExtensionSupported<GL::Extensions::ARB::uniform_buffer_object>())
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
if(data.flags >= MeshVisualizerGL2D::Flag::MultiDraw) {
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::shader_draw_parameters>())
CORRADE_SKIP(GL::Extensions::ARB::shader_draw_parameters::string() << "is not supported.");
#elif !defined(MAGNUM_TARGET_WEBGL)
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ANGLE::multi_draw>())
CORRADE_SKIP(GL::Extensions::ANGLE::multi_draw::string() << "is not supported.");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::WEBGL::multi_draw>())
CORRADE_SKIP(GL::Extensions::WEBGL::multi_draw::string() << "is not supported.");
#endif
}
auto compileState = MeshVisualizerGL2D::compile(data.flags, data.materialCount, data.drawCount);
CORRADE_COMPARE(compileState.flags(), data.flags);
CORRADE_COMPARE(compileState.materialCount(), data.materialCount);
CORRADE_COMPARE(compileState.drawCount(), data.drawCount);
while(!compileState.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL2D shader{std::move(compileState)};
CORRADE_COMPARE(shader.flags(), data.flags);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)
CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly.");
#endif
CORRADE_VERIFY(shader.validate().first);
}
MAGNUM_VERIFY_NO_GL_ERROR();
}
#endif
void MeshVisualizerGLTest::construct3D() {
@ -1541,6 +1717,77 @@ void MeshVisualizerGLTest::construct3D() {
MAGNUM_VERIFY_NO_GL_ERROR();
}
void MeshVisualizerGLTest::construct3DAsync() {
constexpr struct {
const char* name;
MeshVisualizerGL3D::Flags flags;
} data {
"object ID texture array", MeshVisualizerGL3D::Flag::ObjectIdTexture|MeshVisualizerGL3D::Flag::TextureArrays
};
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
if((data.flags & MeshVisualizerGL3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(data.flags >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL300)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES300)
#endif
) CORRADE_SKIP("gl_VertexID not supported.");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(data.flags & MeshVisualizerGL3D::Flag::PrimitiveId && !(data.flags >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId) &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL320)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES320)
#endif
) CORRADE_SKIP("gl_PrimitiveID not supported.");
#endif
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
if(((data.flags & MeshVisualizerGL3D::Flag::Wireframe) && !(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader)) || (data.flags & (MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::BitangentDirection|MeshVisualizerGL3D::Flag::BitangentFromTangentDirection|MeshVisualizerGL3D::Flag::NormalDirection))) {
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::geometry_shader4>())
CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported.");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::geometry_shader>())
CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported.");
#endif
#ifdef MAGNUM_TARGET_GLES
if(GL::Context::current().isExtensionSupported<GL::Extensions::NV::shader_noperspective_interpolation>())
CORRADE_INFO("Using" << GL::Extensions::NV::shader_noperspective_interpolation::string());
#endif
}
#endif
auto compileState = MeshVisualizerGL3D::compile(data.flags);
CORRADE_COMPARE(compileState.flags(), data.flags);
while(!compileState.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL3D shader{data.flags};
CORRADE_COMPARE(shader.flags(), data.flags);
CORRADE_VERIFY(compileState.isLinkFinished());
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)
CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly.");
#endif
CORRADE_VERIFY(shader.validate().first);
}
MAGNUM_VERIFY_NO_GL_ERROR();
}
#ifndef MAGNUM_TARGET_GLES2
void MeshVisualizerGLTest::constructUniformBuffers3D() {
auto&& data = ConstructUniformBuffersData3D[testCaseInstanceId()];
@ -1618,6 +1865,98 @@ void MeshVisualizerGLTest::constructUniformBuffers3D() {
MAGNUM_VERIFY_NO_GL_ERROR();
}
void MeshVisualizerGLTest::constructUniformBuffers3DAsync() {
constexpr struct {
const char* name;
MeshVisualizerGL3D::Flags flags;
UnsignedInt materialCount, drawCount;
} data {
"multidraw with wireframe w/o GS and vertex ID", MeshVisualizerGL3D::Flag::MultiDraw|MeshVisualizerGL3D::Flag::Wireframe|MeshVisualizerGL3D::Flag::NoGeometryShader|MeshVisualizerGL3D::Flag::VertexId, 6, 28
};
setTestCaseDescription(data.name);
#ifndef MAGNUM_TARGET_GLES
if((data.flags & MeshVisualizerGL3D::Flag::InstancedObjectId) && !GL::Context::current().isExtensionSupported<GL::Extensions::EXT::gpu_shader4>())
CORRADE_SKIP(GL::Extensions::EXT::gpu_shader4::string() << "is not supported.");
#endif
#ifndef MAGNUM_TARGET_WEBGL
if(data.flags >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL300)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES300)
#endif
) CORRADE_SKIP("gl_VertexID not supported.");
#endif
#ifndef MAGNUM_TARGET_WEBGL
if(data.flags & MeshVisualizerGL3D::Flag::PrimitiveId && !(data.flags >= MeshVisualizerGL3D::Flag::PrimitiveIdFromVertexId) &&
#ifndef MAGNUM_TARGET_GLES
!GL::Context::current().isVersionSupported(GL::Version::GL320)
#else
!GL::Context::current().isVersionSupported(GL::Version::GLES320)
#endif
) CORRADE_SKIP("gl_PrimitiveID not supported.");
#endif
#ifndef MAGNUM_TARGET_WEBGL
if(((data.flags & MeshVisualizerGL3D::Flag::Wireframe) && !(data.flags & MeshVisualizerGL3D::Flag::NoGeometryShader)) || (data.flags & (MeshVisualizerGL3D::Flag::TangentDirection|MeshVisualizerGL3D::Flag::BitangentDirection|MeshVisualizerGL3D::Flag::BitangentFromTangentDirection|MeshVisualizerGL3D::Flag::NormalDirection))) {
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::geometry_shader4>())
CORRADE_SKIP(GL::Extensions::ARB::geometry_shader4::string() << "is not supported.");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::EXT::geometry_shader>())
CORRADE_SKIP(GL::Extensions::EXT::geometry_shader::string() << "is not supported.");
#endif
#ifdef MAGNUM_TARGET_GLES
if(GL::Context::current().isExtensionSupported<GL::Extensions::NV::shader_noperspective_interpolation>())
CORRADE_INFO("Using" << GL::Extensions::NV::shader_noperspective_interpolation::string());
#endif
}
#endif
#ifndef MAGNUM_TARGET_GLES
if(data.flags & MeshVisualizerGL3D::Flag::UniformBuffers && !GL::Context::current().isExtensionSupported<GL::Extensions::ARB::uniform_buffer_object>())
CORRADE_SKIP(GL::Extensions::ARB::uniform_buffer_object::string() << "is not supported.");
#endif
if(data.flags >= MeshVisualizerGL3D::Flag::MultiDraw) {
#ifndef MAGNUM_TARGET_GLES
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::shader_draw_parameters>())
CORRADE_SKIP(GL::Extensions::ARB::shader_draw_parameters::string() << "is not supported.");
#elif !defined(MAGNUM_TARGET_WEBGL)
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ANGLE::multi_draw>())
CORRADE_SKIP(GL::Extensions::ANGLE::multi_draw::string() << "is not supported.");
#else
if(!GL::Context::current().isExtensionSupported<GL::Extensions::WEBGL::multi_draw>())
CORRADE_SKIP(GL::Extensions::WEBGL::multi_draw::string() << "is not supported.");
#endif
}
auto compileState = MeshVisualizerGL3D::compile(data.flags, data.materialCount, data.drawCount);
CORRADE_COMPARE(compileState.flags(), data.flags);
CORRADE_COMPARE(compileState.materialCount(), data.materialCount);
CORRADE_COMPARE(compileState.drawCount(), data.drawCount);
while(!compileState.isLinkFinished())
Utility::System::sleep(100);
MeshVisualizerGL3D shader{std::move(compileState)};
CORRADE_COMPARE(shader.flags(), data.flags);
CORRADE_VERIFY(shader.isLinkFinished());
CORRADE_VERIFY(shader.id());
{
#if defined(CORRADE_TARGET_APPLE) && !defined(MAGNUM_TARGET_GLES)
CORRADE_EXPECT_FAIL("macOS drivers need insane amount of state to validate properly.");
#endif
CORRADE_VERIFY(shader.validate().first);
}
MAGNUM_VERIFY_NO_GL_ERROR();
}
#endif
void MeshVisualizerGLTest::construct2DInvalid() {

1
src/Magnum/Shaders/VectorGL.cpp

@ -162,7 +162,6 @@ template<UnsignedInt dimensions> typename VectorGL<dimensions>::CompileState Vec
out.submitLink();
return CompileState{std::move(out), std::move(vert), std::move(frag), version};
}
template<UnsignedInt dimensions> VectorGL<dimensions>::VectorGL(CompileState&& cs)

Loading…
Cancel
Save