Browse Source

Split the OpenGL layer out, pt 11: generic MeshPrimitive and MeshIndexType.

Similarly to pixel formats, there is now generic Magnum::MeshPrimitive
and Magnum::MeshIndexType, which is convertible to GL::MeshPrimitive and
GL::MeshIndexType using GL::meshPrimitive() and GL::meshIndexType(). In
addition, the following is done:

 * The original GL::Mesh::IndexType is now GL::MeshIndexType, original
   name is now just a typedef.
 * GL::Mesh::indexSize() is deprecated in favor of
   Magnum::meshIndexTypeSize() and GL::Mesh::indexTypeSize().
 * New GL::Mesh::indexType() and GL::MeshView::mesh() getters (not sure
   why they were omitted)
 * GL::Mesh::indexType(), GL::Mesh::indexTypeSize(),
   GL::MeshView::setIndexRange() now expect that the mesh is indexed
   (useful property in my opinion, also avoids getting random results).
 * The extra MeshPrimitive::LinesAdjacency etc. are still present for
   backwards compatibility, but marked as deprecated. Use
   GL::MeshPrimitive values instead.
pull/233/head
Vladimír Vondruš 8 years ago
parent
commit
b3fa6e538a
  1. 39
      doc/changelog.dox
  2. 3
      src/Magnum/CMakeLists.txt
  3. 2
      src/Magnum/GL/CMakeLists.txt
  4. 1
      src/Magnum/GL/GL.h
  5. 238
      src/Magnum/GL/Mesh.cpp
  6. 186
      src/Magnum/GL/Mesh.h
  7. 3
      src/Magnum/GL/MeshView.cpp
  8. 12
      src/Magnum/GL/MeshView.h
  9. 2
      src/Magnum/GL/Test/CMakeLists.txt
  10. 71
      src/Magnum/GL/Test/MeshGLTest.cpp
  11. 106
      src/Magnum/GL/Test/MeshTest.cpp
  12. 5
      src/Magnum/Magnum.h
  13. 165
      src/Magnum/Mesh.cpp
  14. 206
      src/Magnum/Mesh.h
  15. 2
      src/Magnum/Test/CMakeLists.txt
  16. 98
      src/Magnum/Test/MeshTest.cpp
  17. 2
      src/MagnumPlugins/ObjImporter/Test/Test.cpp

39
doc/changelog.dox

@ -55,6 +55,9 @@ See also:
@ref isCompressedPixelFormatImplementationSpecific() utilities now used by @ref isCompressedPixelFormatImplementationSpecific() utilities now used by
@ref Image / @ref CompressedImage and @ref ImageView / @ref Image / @ref CompressedImage and @ref ImageView /
@ref CompressedImageView instead of the GL-specific formats @ref CompressedImageView instead of the GL-specific formats
- New @ref MeshPrimitive and @ref MeshIndexType enums containing generic
API-independent mesh primitive types and index types, together with
@ref meshIndexTypeSize() utilities
@subsubsection changelog-latest-new-math Math library @subsubsection changelog-latest-new-math Math library
@ -68,7 +71,13 @@ See also:
@ref GL::hasCompressedPixelFormat(), @ref compressedPixelFormat() utilities @ref GL::hasCompressedPixelFormat(), @ref compressedPixelFormat() utilities
for converting generic @ref PixelFormat / @ref CompressedPixelFormat to for converting generic @ref PixelFormat / @ref CompressedPixelFormat to
GL-specific @ref GL::PixelFormat, @ref GL::PixelType and GL-specific @ref GL::PixelFormat, @ref GL::PixelType and
@ref GL::CompressedPixelFormat values @ref GL::CompressedPixelFormat values. The @ref BufferImage and
@ref CompressedBufferImage classes now have overloads accepting both types.
- New @ref GL::meshPrimitive() and @ref GL::meshIndexType() utilities for
converting generic @ref MeshPrimitive and @ref MeshIndexType to GL-specific
@ref GL::MeshPrimitive and @ref GL::MeshIndexType values. The @ref Mesh
class now has overloads accepting both types.
- New @ref Mesh::indexType() and @ref MeshView::mesh() getters
- Initial support for OpenGL ES 3.2 and OpenGL 4.6 - Initial support for OpenGL ES 3.2 and OpenGL 4.6
- New OpenGL extension support: - New OpenGL extension support:
- @extension{ARB,texture_filter_anisotropic} - @extension{ARB,texture_filter_anisotropic}
@ -106,6 +115,12 @@ See also:
a compatibility code path is implemented, the @ref GL library expects that a compatibility code path is implemented, the @ref GL library expects that
all parameters are at their defaults. all parameters are at their defaults.
@subsubsection changelog-latest-changes-gl GL library
- The @ref GL::Mesh::indexTypeSize() and @ref GL::MeshView::setIndexRange()
now expect that the mesh is indexed (instead of silently not doing
anything)
@subsection changelog-latest-buildsystem Build system @subsection changelog-latest-buildsystem Build system
- All plugin interfaces now implement - All plugin interfaces now implement
@ -166,6 +181,14 @@ See also:
- `setData()` functions in the @ref Image and @ref CompressedImage classes - `setData()` functions in the @ref Image and @ref CompressedImage classes
are deprecated because they don't offer anything extra over simple are deprecated because they don't offer anything extra over simple
move-assignment of a new instance. move-assignment of a new instance.
- The @ref MeshPrimitive enum now contains generic API-independent values.
The additional GL-specific types are present there, but marked as
deprecated. Use the GL-specific @ref GL::MeshPrimitive enum instead.
- THe `GL::Mesh::IndexType` enum and the `Mesh::indexSize(MeshIndexType)`
function is deprecated, use @ref Magnum::MeshIndexType /
@ref GL::MeshIndexType and @ref meshIndexTypeSize() instead
- The `GL::Mesh::indexSize()` function is deprecated, use
@ref GL::Mesh::indexTypeSize() instead
- Class @cpp Primitives::Capsule2D @ce and @cpp Primitives::Capsule3D @ce is - Class @cpp Primitives::Capsule2D @ce and @cpp Primitives::Capsule3D @ce is
deprecated, use @ref Primitives::capsule2DWireframe(), deprecated, use @ref Primitives::capsule2DWireframe(),
@ref Primitives::capsule3DSolid() and @ref Primitives::capsule3DWireframe() @ref Primitives::capsule3DSolid() and @ref Primitives::capsule3DWireframe()
@ -249,6 +272,20 @@ See also:
@ref Magnum::CompressedPixelFormat may break. In all other cases, @ref Magnum::CompressedPixelFormat may break. In all other cases,
@ref CompressedImage::format() "CompressedImage*::format()" @ref CompressedImage::format() "CompressedImage*::format()"
returns @ref Magnum::CompressedPixelFormat. returns @ref Magnum::CompressedPixelFormat.
- `MeshPrimitive` has been moved verbatim to @ref GL::MeshPrimitive and
there's a new @ref Magnum::MeshPrimitive enum for generic primitive types.
It contains (deprecated) additional @ref GL::MeshPrimitive values for
covering most of backwards compatibility, but code that relies on these
two types being the same (or have values that match GL enums) may break.
In particular, @ref GL::Mesh::primitive() now returns
@ref GL::MeshPrimitive instead of @ref Magnum::MeshPrimitive, code
depending on the return type being implicitly convertible to
@ref Magnum::MeshPrimitive may break. IN all other cases,
@ref Trade::MeshData2D::primitive() "Trade::MeshData*D::primitive()" etc.
returns @ref Magnum::MeshPrimitive.
- Configuration value reader/writers are now for only
@ref Magnum::MeshPrimitive and @ref Magnum::MeshIndexType, not for
@ref GL::MeshPrimitive or @ref GL::MeshIndexType
- The @ref Image::pixelSize(), @ref ImageView::pixelSize(), - The @ref Image::pixelSize(), @ref ImageView::pixelSize(),
@ref Trade::ImageData::pixelSize() and @ref BufferImage::pixelSize() @ref Trade::ImageData::pixelSize() and @ref BufferImage::pixelSize()
functions now return @ref UnsignedInt instead of @cpp std::size_t @ce. functions now return @ref UnsignedInt instead of @cpp std::size_t @ce.

3
src/Magnum/CMakeLists.txt

@ -28,6 +28,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake
# Files shared between main library and unit test library # Files shared between main library and unit test library
set(Magnum_SRCS set(Magnum_SRCS
Mesh.cpp
PixelStorage.cpp PixelStorage.cpp
Resource.cpp Resource.cpp
Timeline.cpp) Timeline.cpp)
@ -44,6 +45,7 @@ set(Magnum_HEADERS
Image.h Image.h
ImageView.h ImageView.h
Magnum.h Magnum.h
Mesh.h
PixelFormat.h PixelFormat.h
PixelStorage.h PixelStorage.h
Resource.h Resource.h
@ -68,7 +70,6 @@ if(WITH_GL AND BUILD_DEPRECATED)
DefaultFramebuffer.h DefaultFramebuffer.h
Extensions.h Extensions.h
Framebuffer.h Framebuffer.h
Mesh.h
MeshView.h MeshView.h
OpenGL.h OpenGL.h
Renderbuffer.h Renderbuffer.h

2
src/Magnum/GL/CMakeLists.txt

@ -34,7 +34,6 @@ set(MagnumGL_SRCS
Context.cpp Context.cpp
DefaultFramebuffer.cpp DefaultFramebuffer.cpp
Framebuffer.cpp Framebuffer.cpp
Mesh.cpp
MeshView.cpp MeshView.cpp
OpenGL.cpp OpenGL.cpp
Renderbuffer.cpp Renderbuffer.cpp
@ -57,6 +56,7 @@ set(MagnumGL_SRCS
Implementation/maxTextureSize.cpp) Implementation/maxTextureSize.cpp)
set(MagnumGL_GracefulAssert_SRCS set(MagnumGL_GracefulAssert_SRCS
Mesh.cpp
PixelFormat.cpp) PixelFormat.cpp)
set(MagnumGL_HEADERS set(MagnumGL_HEADERS

1
src/Magnum/GL/GL.h

@ -91,6 +91,7 @@ enum class ImageAccess: GLenum;
#endif #endif
enum class MeshPrimitive: GLenum; enum class MeshPrimitive: GLenum;
enum class MeshIndexType: GLenum;
class Mesh; class Mesh;
class MeshView; class MeshView;

238
src/Magnum/GL/Mesh.cpp

@ -27,6 +27,7 @@
#include <Corrade/Utility/Debug.h> #include <Corrade/Utility/Debug.h>
#include "Magnum/Mesh.h"
#include "Magnum/GL/AbstractShaderProgram.h" #include "Magnum/GL/AbstractShaderProgram.h"
#include "Magnum/GL/Buffer.h" #include "Magnum/GL/Buffer.h"
#include "Magnum/GL/Context.h" #include "Magnum/GL/Context.h"
@ -43,6 +44,92 @@
namespace Magnum { namespace GL { namespace Magnum { namespace GL {
namespace {
constexpr MeshPrimitive PrimitiveMapping[]{
MeshPrimitive::Points,
MeshPrimitive::Lines,
MeshPrimitive::LineLoop,
MeshPrimitive::LineStrip,
MeshPrimitive::Triangles,
MeshPrimitive::TriangleStrip,
MeshPrimitive::TriangleFan
};
constexpr MeshIndexType IndexTypeMapping[]{
MeshIndexType::UnsignedByte,
MeshIndexType::UnsignedShort,
MeshIndexType::UnsignedInt
};
}
MeshPrimitive meshPrimitive(const Magnum::MeshPrimitive primitive) {
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
CORRADE_IGNORE_DEPRECATED_PUSH
if(primitive == Magnum::MeshPrimitive::LinesAdjacency ||
primitive == Magnum::MeshPrimitive::LineStripAdjacency ||
primitive == Magnum::MeshPrimitive::TrianglesAdjacency ||
primitive == Magnum::MeshPrimitive::TriangleStripAdjacency ||
primitive == Magnum::MeshPrimitive::Patches)
return MeshPrimitive(UnsignedInt(primitive));
CORRADE_IGNORE_DEPRECATED_POP
#endif
CORRADE_ASSERT(UnsignedInt(primitive) < Containers::arraySize(PrimitiveMapping),
"GL::meshPrimitive(): invalid primitive" << primitive, {});
return PrimitiveMapping[UnsignedInt(primitive)];
}
MeshIndexType meshIndexType(const Magnum::MeshIndexType type) {
CORRADE_ASSERT(UnsignedInt(type) < Containers::arraySize(IndexTypeMapping),
"GL::meshIndexType(): invalid type" << type, {});
return IndexTypeMapping[UnsignedInt(type)];
}
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug& operator<<(Debug& debug, MeshPrimitive value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case MeshPrimitive::value: return debug << "GL::MeshPrimitive::" #value;
_c(Points)
_c(Lines)
_c(LineLoop)
_c(LineStrip)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(LineStripAdjacency)
_c(LinesAdjacency)
#endif
_c(Triangles)
_c(TriangleStrip)
_c(TriangleFan)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(TrianglesAdjacency)
_c(TriangleStripAdjacency)
_c(Patches)
#endif
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "GL::MeshPrimitive(" << Debug::nospace << reinterpret_cast<void*>(GLenum(value)) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, MeshIndexType value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case MeshIndexType::value: return debug << "GL::MeshIndexType::" #value;
_c(UnsignedByte)
_c(UnsignedShort)
_c(UnsignedInt)
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "GL::MeshIndexType(" << Debug::nospace << reinterpret_cast<void*>(GLenum(value)) << Debug::nospace << ")";
}
#endif
struct Mesh::AttributeLayout { struct Mesh::AttributeLayout {
explicit AttributeLayout(const Buffer& buffer, GLuint location, GLint size, GLenum type, DynamicAttribute::Kind kind, GLintptr offset, GLsizei stride, GLuint divisor) noexcept: buffer{Buffer::wrap(buffer.id())}, location{location}, size{size}, type{type}, kind{kind}, offset{offset}, stride{stride}, divisor{divisor} {} explicit AttributeLayout(const Buffer& buffer, GLuint location, GLint size, GLenum type, DynamicAttribute::Kind kind, GLintptr offset, GLsizei stride, GLuint divisor) noexcept: buffer{Buffer::wrap(buffer.id())}, location{location}, size{size}, type{type}, kind{kind}, offset{offset}, stride{stride}, divisor{divisor} {}
@ -110,15 +197,11 @@ Int Mesh::maxElementsVertices() {
} }
#endif #endif
std::size_t Mesh::indexSize(IndexType type) { #ifdef MAGNUM_BUILD_DEPRECATED
switch(type) { std::size_t Mesh::indexSize(Magnum::MeshIndexType type) {
case IndexType::UnsignedByte: return 1; return meshIndexTypeSize(type);
case IndexType::UnsignedShort: return 2;
case IndexType::UnsignedInt: return 4;
}
CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
} }
#endif
Mesh::Mesh(const MeshPrimitive primitive): _primitive{primitive}, _flags{ObjectFlag::DeleteOnDestruction}, _count{0}, _baseVertex{0}, _instanceCount{1}, Mesh::Mesh(const MeshPrimitive primitive): _primitive{primitive}, _flags{ObjectFlag::DeleteOnDestruction}, _count{0}, _baseVertex{0}, _instanceCount{1},
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -127,7 +210,7 @@ Mesh::Mesh(const MeshPrimitive primitive): _primitive{primitive}, _flags{ObjectF
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
_indexStart(0), _indexEnd(0), _indexStart(0), _indexEnd(0),
#endif #endif
_indexOffset(0), _indexType(IndexType::UnsignedInt), _indexBuffer(nullptr) _indexOffset(0), _indexType(MeshIndexType::UnsignedInt), _indexBuffer(nullptr)
{ {
(this->*Context::current().state().mesh->createImplementation)(); (this->*Context::current().state().mesh->createImplementation)();
} }
@ -139,7 +222,7 @@ Mesh::Mesh(NoCreateT) noexcept: _id{0}, _primitive{MeshPrimitive::Triangles}, _f
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
_indexStart(0), _indexEnd(0), _indexStart(0), _indexEnd(0),
#endif #endif
_indexOffset(0), _indexType(IndexType::UnsignedInt), _indexBuffer(nullptr) {} _indexOffset(0), _indexType(MeshIndexType::UnsignedInt), _indexBuffer(nullptr) {}
Mesh::~Mesh() { Mesh::~Mesh() {
/* Moved out or not deleting on destruction, nothing to do */ /* Moved out or not deleting on destruction, nothing to do */
@ -222,6 +305,23 @@ Mesh& Mesh::setLabelInternal(const Containers::ArrayView<const char> label) {
} }
#endif #endif
MeshIndexType Mesh::indexType() const {
CORRADE_ASSERT(_indexBuffer, "Mesh::indexType(): mesh is not indexed", {});
return _indexType;
}
UnsignedInt Mesh::indexTypeSize() const {
CORRADE_ASSERT(_indexBuffer, "Mesh::indexTypeSize(): mesh is not indexed", {});
switch(_indexType) {
case MeshIndexType::UnsignedByte: return 1;
case MeshIndexType::UnsignedShort: return 2;
case MeshIndexType::UnsignedInt: return 4;
}
CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
}
Mesh& Mesh::addVertexBufferInstanced(Buffer& buffer, const UnsignedInt divisor, const GLintptr offset, const GLsizei stride, const DynamicAttribute& attribute) { Mesh& Mesh::addVertexBufferInstanced(Buffer& buffer, const UnsignedInt divisor, const GLintptr offset, const GLsizei stride, const DynamicAttribute& attribute) {
AttributeLayout l{buffer, AttributeLayout l{buffer,
attribute.location(), attribute.location(),
@ -235,7 +335,7 @@ Mesh& Mesh::addVertexBufferInstanced(Buffer& buffer, const UnsignedInt divisor,
return *this; return *this;
} }
Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end) { Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type, UnsignedInt start, UnsignedInt end) {
#ifdef MAGNUM_TARGET_WEBGL #ifdef MAGNUM_TARGET_WEBGL
CORRADE_ASSERT(buffer.targetHint() == Buffer::TargetHint::ElementArray, CORRADE_ASSERT(buffer.targetHint() == Buffer::TargetHint::ElementArray,
"GL::Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::ElementArray << "but got" << buffer.targetHint(), *this); "GL::Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::ElementArray << "but got" << buffer.targetHint(), *this);
@ -629,120 +729,4 @@ void Mesh::drawElementsInstancedImplementationNV(const GLsizei count, const GLin
#endif #endif
#endif #endif
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug& operator<<(Debug& debug, MeshPrimitive value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case MeshPrimitive::value: return debug << "GL::MeshPrimitive::" #value;
_c(Points)
_c(LineStrip)
_c(LineLoop)
_c(Lines)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(LineStripAdjacency)
_c(LinesAdjacency)
#endif
_c(TriangleStrip)
_c(TriangleFan)
_c(Triangles)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(TriangleStripAdjacency)
_c(TrianglesAdjacency)
_c(Patches)
#endif
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "GL::MeshPrimitive(" << Debug::nospace << reinterpret_cast<void*>(GLenum(value)) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, Mesh::IndexType value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case Mesh::IndexType::value: return debug << "GL::Mesh::IndexType::" #value;
_c(UnsignedByte)
_c(UnsignedShort)
_c(UnsignedInt)
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "GL::Mesh::IndexType(" << Debug::nospace << reinterpret_cast<void*>(GLenum(value)) << Debug::nospace << ")";
}
#endif
}}
namespace Corrade { namespace Utility {
std::string ConfigurationValue<Magnum::GL::MeshPrimitive>::toString(Magnum::GL::MeshPrimitive value, ConfigurationValueFlags) {
switch(value) {
#define _c(value) case Magnum::GL::MeshPrimitive::value: return #value;
_c(Points)
_c(LineStrip)
_c(LineLoop)
_c(Lines)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(LineStripAdjacency)
_c(LinesAdjacency)
#endif
_c(TriangleStrip)
_c(TriangleFan)
_c(Triangles)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(TriangleStripAdjacency)
_c(TrianglesAdjacency)
_c(Patches)
#endif
#undef _c
}
return {};
}
Magnum::GL::MeshPrimitive ConfigurationValue<Magnum::GL::MeshPrimitive>::fromString(const std::string& stringValue, ConfigurationValueFlags) {
#define _c(value) if(stringValue == #value) return Magnum::GL::MeshPrimitive::value;
_c(LineStrip)
_c(LineLoop)
_c(Lines)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(LineStripAdjacency)
_c(LinesAdjacency)
#endif
_c(TriangleStrip)
_c(TriangleFan)
_c(Triangles)
#if !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
_c(TriangleStripAdjacency)
_c(TrianglesAdjacency)
_c(Patches)
#endif
#undef _c
return Magnum::GL::MeshPrimitive::Points;
}
std::string ConfigurationValue<Magnum::GL::Mesh::IndexType>::toString(Magnum::GL::Mesh::IndexType value, ConfigurationValueFlags) {
switch(value) {
#define _c(value) case Magnum::GL::Mesh::IndexType::value: return #value;
_c(UnsignedByte)
_c(UnsignedShort)
_c(UnsignedInt)
#undef _c
}
return {};
}
Magnum::GL::Mesh::IndexType ConfigurationValue<Magnum::GL::Mesh::IndexType>::fromString(const std::string& stringValue, ConfigurationValueFlags) {
#define _c(value) if(stringValue == #value) return Magnum::GL::Mesh::IndexType::value;
_c(UnsignedByte)
_c(UnsignedShort)
_c(UnsignedInt)
#undef _c
return Magnum::GL::Mesh::IndexType::UnsignedInt;
}
}} }}

186
src/Magnum/GL/Mesh.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class @ref Magnum::GL::Mesh * @brief Class @ref Magnum::GL::Mesh, enum @ref Magnum::GL::MeshPrimitive, @ref Magnum::GL::MeshIndexType, function @ref Magnum::GL::meshPrimitive(), @ref Magnum::GL::meshIndexType()
*/ */
#include <vector> #include <vector>
@ -41,11 +41,12 @@
namespace Magnum { namespace GL { namespace Magnum { namespace GL {
/** /**
* @brief Mesh primitive type @brief Mesh primitive type
*
* @see @ref Mesh::primitive(), @ref Mesh::setPrimitive() @see @ref Magnum::MeshPrimitive, @ref meshPrimitive(), @ref Mesh::primitive(),
* @m_enum_values_as_keywords @ref Mesh::setPrimitive()
*/ @m_enum_values_as_keywords
*/
enum class MeshPrimitive: GLenum { enum class MeshPrimitive: GLenum {
/** Single points. */ /** Single points. */
Points = GL_POINTS, Points = GL_POINTS,
@ -135,6 +136,41 @@ enum class MeshPrimitive: GLenum {
#endif #endif
}; };
/**
@brief Convert generic mesh primitive to OpenGL mesh primitive
@see @ref meshIndexType()
*/
MAGNUM_GL_EXPORT MeshPrimitive meshPrimitive(Magnum::MeshPrimitive);
/**
@brief Index type
@see @ref Magnum::MeshIndexType, @ref meshIndexType(),
@ref meshIndexTypeSize(), @ref Mesh::setIndexBuffer()
@m_enum_values_as_keywords
*/
enum class MeshIndexType: GLenum {
UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */
UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */
/**
* Unsigned int
* @requires_gles30 Extension @extension{OES,element_index_uint}
* in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{OES,element_index_uint}
* in WebGL 1.0.
*/
UnsignedInt = GL_UNSIGNED_INT
};
/**
@brief Convert generic mesh index type to OpenGL mesh index type
@see @ref meshPrimitive(), @ref meshIndexTypeSize()
*/
MAGNUM_GL_EXPORT MeshIndexType meshIndexType(Magnum::MeshIndexType);
namespace Implementation { struct MeshState; } namespace Implementation { struct MeshState; }
/** /**
@ -240,25 +276,13 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
friend Implementation::MeshState; friend Implementation::MeshState;
public: public:
/** #ifdef MAGNUM_BUILD_DEPRECATED
* @brief Index type /** @brief @copybrief MeshIndexType
* * @deprecated Use @ref Magnum::MeshIndexType or @ref GL::MeshIndexType
* @see @ref setIndexBuffer(), @ref indexSize() * instead.
* @m_enum_values_as_keywords
*/ */
enum class IndexType: GLenum { typedef CORRADE_DEPRECATED("use MeshIndexType instead") Magnum::MeshIndexType IndexType;
UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */ #endif
UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */
/**
* Unsigned int
* @requires_gles30 Extension @extension{OES,element_index_uint}
* in OpenGL ES 2.0.
* @requires_webgl20 Extension @webgl_extension{OES,element_index_uint}
* in WebGL 1.0.
*/
UnsignedInt = GL_UNSIGNED_INT
};
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
/** /**
@ -308,12 +332,12 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
static Int maxElementsVertices(); static Int maxElementsVertices();
#endif #endif
/** #ifdef MAGNUM_BUILD_DEPRECATED
* @brief Size of given index type /** @brief @copybrief meshIndexTypeSize()
* * @deprecated Use @ref meshIndexTypeSize() instead.
* @see @ref indexSize() const
*/ */
static std::size_t indexSize(IndexType type); static CORRADE_DEPRECATED("use meshIndexTypeSize() instead") std::size_t indexSize(Magnum::MeshIndexType type);
#endif
/** /**
* @brief Wrap existing OpenGL vertex array object * @brief Wrap existing OpenGL vertex array object
@ -357,6 +381,9 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
*/ */
explicit Mesh(MeshPrimitive primitive = MeshPrimitive::Triangles); explicit Mesh(MeshPrimitive primitive = MeshPrimitive::Triangles);
/** @overload */
explicit Mesh(Magnum::MeshPrimitive primitive): Mesh{meshPrimitive(primitive)} {}
/** /**
* @brief Construct without creating the underlying OpenGL object * @brief Construct without creating the underlying OpenGL object
* *
@ -466,11 +493,28 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
bool isIndexed() const { return _indexBuffer; } bool isIndexed() const { return _indexBuffer; }
/** /**
* @brief Index size * @brief Index type
*
* Expects that the mesh is indexed.
* @see @ref isIndexed()
*/
MeshIndexType indexType() const;
/**
* @brief Index type size
* *
* @see @ref indexSize(IndexType) * Expects that the mesh is indexed.
* @see @ref isIndexed(), @ref meshIndexTypeSize(Magnum::MeshIndexType)
*/ */
std::size_t indexSize() const { return indexSize(_indexType); } UnsignedInt indexTypeSize() const;
#ifdef MAGNUM_BUILD_DEPRECATED
/**
* @brief Index size
* @deprecated Use @ref indexTypeSize() instead.
*/
CORRADE_DEPRECATED("use indexTypeSize() instead") std::size_t indexSize() const { return indexTypeSize(); }
#endif
/** @brief Primitive type */ /** @brief Primitive type */
MeshPrimitive primitive() const { return _primitive; } MeshPrimitive primitive() const { return _primitive; }
@ -486,6 +530,11 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
return *this; return *this;
} }
/** @overload */
Mesh& setPrimitive(Magnum::MeshPrimitive primitive) {
return setPrimitive(meshPrimitive(primitive));
}
/** @brief Vertex/index count */ /** @brief Vertex/index count */
Int count() const { return _count; } Int count() const { return _count; }
@ -710,9 +759,9 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
* The smaller range is specified with @p start and @p end the less * The smaller range is specified with @p start and @p end the less
* memory operations are needed (and possibly some optimizations), * memory operations are needed (and possibly some optimizations),
* improving draw performance. Specifying @cpp 0 @ce for both * improving draw performance. Specifying @cpp 0 @ce for both
* parameters behaves the same as @ref setIndexBuffer(Buffer&, GLintptr, IndexType). * parameters behaves the same as @ref setIndexBuffer(Buffer&, GLintptr, MeshIndexType).
* On OpenGL ES 2.0 this function behaves always as * On OpenGL ES 2.0 this function behaves always as
* @ref setIndexBuffer(Buffer&, GLintptr, IndexType), as this * @ref setIndexBuffer(Buffer&, GLintptr, MeshIndexType), as this
* functionality is not available there. * functionality is not available there.
* *
* If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL * If @extension{ARB,vertex_array_object} (part of OpenGL 3.0), OpenGL
@ -726,7 +775,12 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
* @ref maxElementsVertices(), @ref setCount(), @ref isIndexed(), * @ref maxElementsVertices(), @ref setCount(), @ref isIndexed(),
* @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} * @fn_gl{BindVertexArray}, @fn_gl{BindBuffer}
*/ */
Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, UnsignedInt start, UnsignedInt end); Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type, UnsignedInt start, UnsignedInt end);
/** @overload */
Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type, UnsignedInt start, UnsignedInt end) {
return setIndexBuffer(buffer, offset, meshIndexType(type), start, end);
}
/** /**
* @brief Set index buffer * @brief Set index buffer
@ -735,14 +789,19 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
* @param type Index data type * @param type Index data type
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Alternative to @ref setIndexBuffer(Buffer&, GLintptr, IndexType, UnsignedInt, UnsignedInt) * Alternative to @ref setIndexBuffer(Buffer&, GLintptr, MeshIndexType, UnsignedInt, UnsignedInt)
* with unspecified index limits, see its documentation for more * with unspecified index limits, see its documentation for more
* information. Prefer to set index limits for better performance. * information. Prefer to set index limits for better performance.
*/ */
Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type) { Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type) {
return setIndexBuffer(buffer, offset, type, 0, 0); return setIndexBuffer(buffer, offset, type, 0, 0);
} }
/** @overload */
Mesh& setIndexBuffer(Buffer& buffer, GLintptr offset, Magnum::MeshIndexType type) {
return setIndexBuffer(buffer, offset, meshIndexType(type));
}
/** /**
* @brief Draw the mesh * @brief Draw the mesh
* @param shader Shader to use for drawing * @param shader Shader to use for drawing
@ -979,7 +1038,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
UnsignedInt _indexStart, _indexEnd; UnsignedInt _indexStart, _indexEnd;
#endif #endif
GLintptr _indexOffset; GLintptr _indexOffset;
IndexType _indexType; MeshIndexType _indexType;
Buffer* _indexBuffer; Buffer* _indexBuffer;
std::vector<AttributeLayout> _attributes; std::vector<AttributeLayout> _attributes;
@ -988,8 +1047,8 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
/** @debugoperatorenum{MeshPrimitive} */ /** @debugoperatorenum{MeshPrimitive} */
MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, MeshPrimitive value); MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, MeshPrimitive value);
/** @debugoperatorclassenum{Mesh,Mesh::IndexType} */ /** @debugoperatorenum{MeshIndexType} */
MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, Mesh::IndexType value); MAGNUM_GL_EXPORT Debug& operator<<(Debug& debug, MeshIndexType value);
inline GLuint Mesh::release() { inline GLuint Mesh::release() {
const GLuint id = _id; const GLuint id = _id;
@ -1002,11 +1061,6 @@ inline GLuint Mesh::release() {
#ifdef MAGNUM_BUILD_DEPRECATED #ifdef MAGNUM_BUILD_DEPRECATED
/* Note: needs to be prefixed with Magnum:: otherwise Doxygen can't find it */ /* Note: needs to be prefixed with Magnum:: otherwise Doxygen can't find it */
/** @brief @copybrief GL::MeshPrimitive
* @deprecated Use @ref GL::MeshPrimitive instead.
*/
typedef CORRADE_DEPRECATED("use GL::MeshPrimitive instead") Magnum::GL::MeshPrimitive MeshPrimitive;
/** @brief @copybrief GL::Mesh /** @brief @copybrief GL::Mesh
* @deprecated Use @ref GL::Mesh instead. * @deprecated Use @ref GL::Mesh instead.
*/ */
@ -1015,46 +1069,4 @@ typedef CORRADE_DEPRECATED("use GL::Mesh instead") Magnum::GL::Mesh Mesh;
} }
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::MeshPrimitive} */
template<> struct MAGNUM_GL_EXPORT ConfigurationValue<Magnum::GL::MeshPrimitive> {
ConfigurationValue() = delete;
/**
* @brief Writes enum value as string
*
* If the value is invalid, returns empty string.
*/
static std::string toString(Magnum::GL::MeshPrimitive value, ConfigurationValueFlags);
/**
* @brief Reads enum value as string
*
* If the value is invalid, returns @ref Magnum::MeshPrimitive::Points "MeshPrimitive::Points".
*/
static Magnum::GL::MeshPrimitive fromString(const std::string& stringValue, ConfigurationValueFlags);
};
/** @configurationvalue{Magnum::Mesh::IndexType} */
template<> struct MAGNUM_GL_EXPORT ConfigurationValue<Magnum::GL::Mesh::IndexType> {
ConfigurationValue() = delete;
/**
* @brief Write enum value as string
*
* If the value is invalid, returns empty string.
*/
static std::string toString(Magnum::GL::Mesh::IndexType value, ConfigurationValueFlags);
/**
* @brief Read enum value as string
*
* If the value is invalid, returns @ref Magnum::Mesh::IndexType::UnsignedInt "Mesh::IndexType::UnsignedInt".
*/
static Magnum::GL::Mesh::IndexType fromString(const std::string& stringValue, ConfigurationValueFlags);
};
}}
#endif #endif

3
src/Magnum/GL/MeshView.cpp

@ -140,7 +140,8 @@ void MeshView::multiDrawImplementationFallback(std::initializer_list<std::refere
#endif #endif
MeshView& MeshView::setIndexRange(Int first) { MeshView& MeshView::setIndexRange(Int first) {
_indexOffset = _original.get()._indexOffset + first*_original.get().indexSize(); CORRADE_ASSERT(_original.get()._indexBuffer, "MeshView::setIndexRange(): mesh is not indexed", *this);
_indexOffset = _original.get()._indexOffset + first*_original.get().indexTypeSize();
return *this; return *this;
} }

12
src/Magnum/GL/MeshView.h

@ -113,6 +113,10 @@ class MAGNUM_GL_EXPORT MeshView {
/** @brief Movement is not allowed */ /** @brief Movement is not allowed */
MeshView& operator=(MeshView&& other) = delete; MeshView& operator=(MeshView&& other) = delete;
/** @brief Original mesh */
Mesh& mesh() { return _original; }
const Mesh& mesh() const { return _original; } /**< @overload */
/** @brief Vertex/index count */ /** @brief Vertex/index count */
Int count() const { return _count; } Int count() const { return _count; }
@ -161,7 +165,9 @@ class MAGNUM_GL_EXPORT MeshView {
* @ref setIndexRange(Int), as index range functionality is not * @ref setIndexRange(Int), as index range functionality is not
* available there. Ignored when calling * available there. Ignored when calling
* @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt).
* @see @ref setCount() *
* Expects that the original mesh is indexed.
* @see @ref setCount(), @ref mesh(), @ref Mesh::isIndexed()
*/ */
/* MinGW/MSVC needs inline also here to avoid linkage conflicts */ /* MinGW/MSVC needs inline also here to avoid linkage conflicts */
inline MeshView& setIndexRange(Int first, UnsignedInt start, UnsignedInt end); inline MeshView& setIndexRange(Int first, UnsignedInt start, UnsignedInt end);
@ -174,7 +180,9 @@ class MAGNUM_GL_EXPORT MeshView {
* Prefer to use @ref setIndexRange(Int, UnsignedInt, UnsignedInt) for * Prefer to use @ref setIndexRange(Int, UnsignedInt, UnsignedInt) for
* better performance. Ignored when calling * better performance. Ignored when calling
* @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt). * @ref draw(AbstractShaderProgram&, TransformFeedback&, UnsignedInt).
* @see @ref setCount() *
* Expects that the original mesh is indexed.
* @see @ref setCount(), @ref mesh(), @ref Mesh::isIndexed()
*/ */
MeshView& setIndexRange(Int first); MeshView& setIndexRange(Int first);

2
src/Magnum/GL/Test/CMakeLists.txt

@ -30,7 +30,7 @@ corrade_add_test(GLContextTest ContextTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLCubeMapTextureTest CubeMapTextureTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLCubeMapTextureTest CubeMapTextureTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLDefaultFramebufferTest DefaultFramebufferTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLDefaultFramebufferTest DefaultFramebufferTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLFramebufferTest FramebufferTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLFramebufferTest FramebufferTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLMeshTest MeshTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLMeshTest MeshTest.cpp LIBRARIES MagnumGLTestLib)
corrade_add_test(GLPixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumGLTestLib) corrade_add_test(GLPixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumGLTestLib)
corrade_add_test(GLRendererTest RendererTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLRendererTest RendererTest.cpp LIBRARIES MagnumGL)
corrade_add_test(GLRenderbufferTest RenderbufferTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLRenderbufferTest RenderbufferTest.cpp LIBRARIES MagnumGL)

71
src/Magnum/GL/Test/MeshGLTest.cpp

@ -41,7 +41,7 @@
#include "Magnum/Math/Matrix.h" #include "Magnum/Math/Matrix.h"
#include "Magnum/Math/Vector4.h" #include "Magnum/Math/Vector4.h"
namespace Magnum { namespace Test { namespace Magnum { namespace GL { namespace Test {
/* Tests also the MeshView class. */ /* Tests also the MeshView class. */
@ -53,6 +53,8 @@ struct MeshGLTest: OpenGLTester {
void constructMove(); void constructMove();
void wrap(); void wrap();
template<class T> void primitive();
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
void label(); void label();
#endif #endif
@ -112,8 +114,8 @@ struct MeshGLTest: OpenGLTester {
void addVertexBufferMultiple(); void addVertexBufferMultiple();
void addVertexBufferMultipleGaps(); void addVertexBufferMultipleGaps();
void setIndexBuffer(); template<class T> void setIndexBuffer();
void setIndexBufferRange(); template<class T> void setIndexBufferRange();
void setIndexBufferUnsignedInt(); void setIndexBufferUnsignedInt();
void unbindVAOWhenSettingIndexBufferData(); void unbindVAOWhenSettingIndexBufferData();
@ -152,6 +154,9 @@ MeshGLTest::MeshGLTest() {
&MeshGLTest::constructMove, &MeshGLTest::constructMove,
&MeshGLTest::wrap, &MeshGLTest::wrap,
&MeshGLTest::primitive<GL::MeshPrimitive>,
&MeshGLTest::primitive<Magnum::MeshPrimitive>,
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
&MeshGLTest::label &MeshGLTest::label
#endif #endif
@ -214,8 +219,10 @@ MeshGLTest::MeshGLTest() {
addTests({&MeshGLTest::addVertexBufferMultiple, addTests({&MeshGLTest::addVertexBufferMultiple,
&MeshGLTest::addVertexBufferMultipleGaps, &MeshGLTest::addVertexBufferMultipleGaps,
&MeshGLTest::setIndexBuffer, &MeshGLTest::setIndexBuffer<GL::MeshIndexType>,
&MeshGLTest::setIndexBufferRange, &MeshGLTest::setIndexBuffer<Magnum::MeshIndexType>,
&MeshGLTest::setIndexBufferRange<GL::MeshIndexType>,
&MeshGLTest::setIndexBufferRange<Magnum::MeshIndexType>,
&MeshGLTest::setIndexBufferUnsignedInt, &MeshGLTest::setIndexBufferUnsignedInt,
&MeshGLTest::unbindVAOWhenSettingIndexBufferData, &MeshGLTest::unbindVAOWhenSettingIndexBufferData,
@ -347,6 +354,21 @@ void MeshGLTest::wrap() {
#endif #endif
} }
template<class T> void MeshGLTest::primitive() {
setTestCaseName(std::is_same<T, MeshPrimitive>::value ?
"setPrimitive<GL::MeshPrimitive>" :
"setPrimitive<Magnum::MeshPrimitive>");
{
Mesh mesh{T::LineLoop};
CORRADE_COMPARE(mesh.primitive(), MeshPrimitive::LineLoop);
} {
Mesh mesh;
mesh.setPrimitive(T::TriangleFan);
CORRADE_COMPARE(mesh.primitive(), MeshPrimitive::TriangleFan);
}
}
#ifndef MAGNUM_TARGET_WEBGL #ifndef MAGNUM_TARGET_WEBGL
void MeshGLTest::label() { void MeshGLTest::label() {
/* No-Op version is tested in AbstractObjectGLTest */ /* No-Op version is tested in AbstractObjectGLTest */
@ -542,15 +564,18 @@ Checker::Checker(AbstractShaderProgram&& shader, RenderbufferFormat format, Mesh
.setCount(2); .setCount(2);
/* Skip first vertex so we test also offsets */ /* Skip first vertex so we test also offsets */
MeshView(mesh) MeshView view{mesh};
.setCount(1) view.setCount(1)
.setBaseVertex(mesh.baseVertex()) .setBaseVertex(mesh.baseVertex())
.setInstanceCount(mesh.instanceCount()) .setInstanceCount(mesh.instanceCount())
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
.setBaseInstance(mesh.baseInstance()) .setBaseInstance(mesh.baseInstance())
#endif #endif
.setIndexRange(1) ;
.draw(shader);
if(view.mesh().isIndexed()) view.setIndexRange(1);
view.draw(shader);
} }
template<class T> T Checker::get(PixelFormat format, PixelType type) { template<class T> T Checker::get(PixelFormat format, PixelType type) {
@ -1635,20 +1660,26 @@ namespace {
constexpr Color4ub indexedResult(64 + 15 + 97, 17 + 164 + 28, 56 + 17, 255); constexpr Color4ub indexedResult(64 + 15 + 97, 17 + 164 + 28, 56 + 17, 255);
} }
void MeshGLTest::setIndexBuffer() { template<class T> void MeshGLTest::setIndexBuffer() {
setTestCaseName(std::is_same<T, MeshIndexType>::value ?
"setIndexBuffer<GL::MeshIndexType>" :
"setIndexBuffer<Magnum::MeshIndexType>");
Buffer vertices; Buffer vertices;
vertices.setData(indexedVertexData, BufferUsage::StaticDraw); vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
constexpr UnsignedShort indexData[] = { 2, 1, 0 }; constexpr UnsignedByte indexData[] = { 2, 1, 0 };
Buffer indices{Buffer::TargetHint::ElementArray}; Buffer indices{Buffer::TargetHint::ElementArray};
indices.setData(indexData, BufferUsage::StaticDraw); indices.setData(indexData, BufferUsage::StaticDraw);
Mesh mesh; Mesh mesh;
mesh.addVertexBuffer(vertices, 1*4, MultipleShader::Position(), mesh.addVertexBuffer(vertices, 1*4, MultipleShader::Position(),
MultipleShader::Normal(), MultipleShader::TextureCoordinates()) MultipleShader::Normal(), MultipleShader::TextureCoordinates())
.setIndexBuffer(indices, 2, Mesh::IndexType::UnsignedShort); .setIndexBuffer(indices, 2, T::UnsignedByte);
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(mesh.indexType(), MeshIndexType::UnsignedByte);
CORRADE_COMPARE(mesh.indexTypeSize(), 1);
const auto value = Checker(MultipleShader{}, const auto value = Checker(MultipleShader{},
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -1662,7 +1693,11 @@ void MeshGLTest::setIndexBuffer() {
CORRADE_COMPARE(value, indexedResult); CORRADE_COMPARE(value, indexedResult);
} }
void MeshGLTest::setIndexBufferRange() { template<class T> void MeshGLTest::setIndexBufferRange() {
setTestCaseName(std::is_same<T, MeshIndexType>::value ?
"setIndexBufferRange<GL::MeshIndexType>" :
"setIndexBufferRange<Magnum::MeshIndexType>");
Buffer vertices; Buffer vertices;
vertices.setData(indexedVertexData, BufferUsage::StaticDraw); vertices.setData(indexedVertexData, BufferUsage::StaticDraw);
@ -1673,9 +1708,11 @@ void MeshGLTest::setIndexBufferRange() {
Mesh mesh; Mesh mesh;
mesh.addVertexBuffer(vertices, 1*4, MultipleShader::Position(), mesh.addVertexBuffer(vertices, 1*4, MultipleShader::Position(),
MultipleShader::Normal(), MultipleShader::TextureCoordinates()) MultipleShader::Normal(), MultipleShader::TextureCoordinates())
.setIndexBuffer(indices, 2, Mesh::IndexType::UnsignedShort, 0, 1); .setIndexBuffer(indices, 2, T::UnsignedShort, 0, 1);
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(mesh.indexType(), GL::MeshIndexType::UnsignedShort);
CORRADE_COMPARE(mesh.indexTypeSize(), 2);
const auto value = Checker(MultipleShader{}, const auto value = Checker(MultipleShader{},
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -1708,6 +1745,8 @@ void MeshGLTest::setIndexBufferUnsignedInt() {
.setIndexBuffer(indices, 4, Mesh::IndexType::UnsignedInt); .setIndexBuffer(indices, 4, Mesh::IndexType::UnsignedInt);
MAGNUM_VERIFY_NO_ERROR(); MAGNUM_VERIFY_NO_ERROR();
CORRADE_COMPARE(mesh.indexType(), GL::MeshIndexType::UnsignedInt);
CORRADE_COMPARE(mesh.indexTypeSize(), 4);
const auto value = Checker(MultipleShader{}, const auto value = Checker(MultipleShader{},
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -2326,6 +2365,6 @@ void MeshGLTest::multiDrawBaseVertex() {
} }
#endif #endif
}} }}}
CORRADE_TEST_MAIN(Magnum::Test::MeshGLTest) CORRADE_TEST_MAIN(Magnum::GL::Test::MeshGLTest)

106
src/Magnum/GL/Test/MeshTest.cpp

@ -28,31 +28,48 @@
#include <Corrade/Utility/Configuration.h> #include <Corrade/Utility/Configuration.h>
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
#include "Magnum/GL/Mesh.h"
namespace Magnum { namespace Test { namespace Magnum { namespace GL { namespace Test {
struct MeshTest: TestSuite::Tester { struct MeshTest: TestSuite::Tester {
explicit MeshTest(); explicit MeshTest();
void constructNoCreate(); void constructNoCreate();
void indexSize(); #ifdef MAGNUM_BUILD_DEPRECATED
void indexSizeDeprecated();
#endif
void mapPrimitive();
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
void mapPrimitiveDeprecated();
#endif
void mapPrimitiveInvalid();
void mapIndexType();
void mapIndexTypeInvalid();
void debugPrimitive(); void debugPrimitive();
void debugIndexType(); void debugIndexType();
void configurationPrimitive();
void configurationIndexType();
}; };
MeshTest::MeshTest() { MeshTest::MeshTest() {
addTests({&MeshTest::constructNoCreate, addTests({&MeshTest::constructNoCreate,
&MeshTest::indexSize, #ifdef MAGNUM_BUILD_DEPRECATED
&MeshTest::indexSizeDeprecated,
#endif
&MeshTest::mapPrimitive,
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
&MeshTest::mapPrimitiveDeprecated,
#endif
&MeshTest::mapPrimitiveInvalid,
&MeshTest::mapIndexType,
&MeshTest::mapIndexTypeInvalid,
&MeshTest::debugPrimitive, &MeshTest::debugPrimitive,
&MeshTest::debugIndexType, &MeshTest::debugIndexType});
&MeshTest::configurationPrimitive,
&MeshTest::configurationIndexType});
} }
void MeshTest::constructNoCreate() { void MeshTest::constructNoCreate() {
@ -64,40 +81,71 @@ void MeshTest::constructNoCreate() {
CORRADE_VERIFY(true); CORRADE_VERIFY(true);
} }
void MeshTest::indexSize() { #ifdef MAGNUM_BUILD_DEPRECATED
void MeshTest::indexSizeDeprecated() {
CORRADE_IGNORE_DEPRECATED_PUSH
CORRADE_COMPARE(Mesh::indexSize(Mesh::IndexType::UnsignedByte), 1); CORRADE_COMPARE(Mesh::indexSize(Mesh::IndexType::UnsignedByte), 1);
CORRADE_COMPARE(Mesh::indexSize(Mesh::IndexType::UnsignedShort), 2); CORRADE_COMPARE(Mesh::indexSize(Mesh::IndexType::UnsignedShort), 2);
CORRADE_COMPARE(Mesh::indexSize(Mesh::IndexType::UnsignedInt), 4); CORRADE_COMPARE(Mesh::indexSize(Mesh::IndexType::UnsignedInt), 4);
CORRADE_IGNORE_DEPRECATED_POP
}
#endif
void MeshTest::mapPrimitive() {
CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::Points), MeshPrimitive::Points);
CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::Lines), MeshPrimitive::Lines);
CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::LineLoop), MeshPrimitive::LineLoop);
CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::LineStrip), MeshPrimitive::LineStrip);
CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::Triangles), MeshPrimitive::Triangles);
CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::TriangleStrip), MeshPrimitive::TriangleStrip);
CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::TriangleFan), MeshPrimitive::TriangleFan);
} }
void MeshTest::debugPrimitive() { #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
std::ostringstream o; void MeshTest::mapPrimitiveDeprecated() {
Debug(&o) << MeshPrimitive::TriangleFan << MeshPrimitive(0xdead); CORRADE_IGNORE_DEPRECATED_PUSH
CORRADE_COMPARE(o.str(), "GL::MeshPrimitive::TriangleFan GL::MeshPrimitive(0xdead)\n"); CORRADE_COMPARE(meshPrimitive(Magnum::MeshPrimitive::TriangleStripAdjacency),
MeshPrimitive::TriangleStripAdjacency);
CORRADE_IGNORE_DEPRECATED_POP
} }
#endif
void MeshTest::debugIndexType() { void MeshTest::mapPrimitiveInvalid() {
std::ostringstream o; std::ostringstream out;
Debug(&o) << Mesh::IndexType::UnsignedShort << Mesh::IndexType(0xdead); Error redirectError{&out};
CORRADE_COMPARE(o.str(), "GL::Mesh::IndexType::UnsignedShort GL::Mesh::IndexType(0xdead)\n");
meshPrimitive(Magnum::MeshPrimitive(0x123));
CORRADE_COMPARE(out.str(),
"GL::meshPrimitive(): invalid primitive MeshPrimitive(0x123)\n");
} }
void MeshTest::configurationPrimitive() { void MeshTest::mapIndexType() {
Utility::Configuration c; CORRADE_COMPARE(meshIndexType(Magnum::MeshIndexType::UnsignedByte), MeshIndexType::UnsignedByte);
CORRADE_COMPARE(meshIndexType(Magnum::MeshIndexType::UnsignedShort), MeshIndexType::UnsignedShort);
CORRADE_COMPARE(meshIndexType(Magnum::MeshIndexType::UnsignedInt), MeshIndexType::UnsignedInt);
}
void MeshTest::mapIndexTypeInvalid() {
std::ostringstream out;
Error redirectError{&out};
c.setValue("primitive", MeshPrimitive::LineStrip); meshIndexType(Magnum::MeshIndexType(0x123));
CORRADE_COMPARE(c.value("primitive"), "LineStrip"); CORRADE_COMPARE(out.str(),
CORRADE_COMPARE(c.value<MeshPrimitive>("primitive"), MeshPrimitive::LineStrip); "GL::meshIndexType(): invalid type MeshIndexType(0x123)\n");
} }
void MeshTest::configurationIndexType() { void MeshTest::debugPrimitive() {
Utility::Configuration c; std::ostringstream o;
Debug(&o) << MeshPrimitive::TriangleFan << MeshPrimitive(0xdead);
CORRADE_COMPARE(o.str(), "GL::MeshPrimitive::TriangleFan GL::MeshPrimitive(0xdead)\n");
}
c.setValue("type", Mesh::IndexType::UnsignedByte); void MeshTest::debugIndexType() {
CORRADE_COMPARE(c.value("type"), "UnsignedByte"); std::ostringstream o;
CORRADE_COMPARE(c.value<Mesh::IndexType>("type"), Mesh::IndexType::UnsignedByte); Debug(&o) << MeshIndexType::UnsignedShort << MeshIndexType(0xdead);
CORRADE_COMPARE(o.str(), "GL::MeshIndexType::UnsignedShort GL::MeshIndexType(0xdead)\n");
} }
}} }}}
CORRADE_TEST_MAIN(Magnum::Test::MeshTest) CORRADE_TEST_MAIN(Magnum::GL::Test::MeshTest)

5
src/Magnum/Magnum.h

@ -698,6 +698,9 @@ typedef CompressedImageView<1> CompressedImageView1D;
typedef CompressedImageView<2> CompressedImageView2D; typedef CompressedImageView<2> CompressedImageView2D;
typedef CompressedImageView<3> CompressedImageView3D; typedef CompressedImageView<3> CompressedImageView3D;
enum class MeshPrimitive: UnsignedInt;
enum class MeshIndexType: UnsignedInt;
enum class PixelFormat: UnsignedInt; enum class PixelFormat: UnsignedInt;
enum class CompressedPixelFormat: UnsignedInt; enum class CompressedPixelFormat: UnsignedInt;
@ -760,8 +763,6 @@ typedef CORRADE_DEPRECATED("use GL::ImageAccess instead") GL::ImageAccess ImageA
typedef CORRADE_DEPRECATED("use GL::ImageFormat instead") GL::ImageFormat ImageFormat; typedef CORRADE_DEPRECATED("use GL::ImageFormat instead") GL::ImageFormat ImageFormat;
#endif #endif
typedef CORRADE_DEPRECATED("use GL::MeshPrimitive instead") GL::MeshPrimitive MeshPrimitive;
typedef CORRADE_DEPRECATED("use GL::Mesh instead") GL::Mesh Mesh; typedef CORRADE_DEPRECATED("use GL::Mesh instead") GL::Mesh Mesh;
typedef CORRADE_DEPRECATED("use GL::MeshView instead") GL::MeshView MeshView; typedef CORRADE_DEPRECATED("use GL::MeshView instead") GL::MeshView MeshView;

165
src/Magnum/Mesh.cpp

@ -0,0 +1,165 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include "Mesh.h"
#include <Corrade/Utility/Assert.h>
#include <Corrade/Utility/Debug.h>
namespace Magnum {
UnsignedInt meshIndexTypeSize(MeshIndexType type) {
switch(type) {
case MeshIndexType::UnsignedByte: return 1;
case MeshIndexType::UnsignedShort: return 2;
case MeshIndexType::UnsignedInt: return 4;
}
CORRADE_ASSERT_UNREACHABLE(); /* LCOV_EXCL_LINE */
}
#ifndef DOXYGEN_GENERATING_OUTPUT
Debug& operator<<(Debug& debug, MeshPrimitive value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case MeshPrimitive::value: return debug << "MeshPrimitive::" #value;
_c(Points)
_c(Lines)
_c(LineLoop)
_c(LineStrip)
_c(Triangles)
_c(TriangleStrip)
_c(TriangleFan)
#undef _c
/* Here mainly to suppress compiler warnings about unhandled cases and
also to check that there are no accidentally conflicting values. */
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
CORRADE_IGNORE_DEPRECATED_PUSH
#define _c(value) case MeshPrimitive::value: return debug << "GL::MeshPrimitive::" #value;
_c(LinesAdjacency)
_c(LineStripAdjacency)
_c(TrianglesAdjacency)
_c(TriangleStripAdjacency)
_c(Patches)
#undef _c
CORRADE_IGNORE_DEPRECATED_POP
#endif
/* LCOV_EXCL_STOP */
}
return debug << "MeshPrimitive(" << Debug::nospace << reinterpret_cast<void*>(GLenum(value)) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, MeshIndexType value) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case MeshIndexType::value: return debug << "MeshIndexType::" #value;
_c(UnsignedByte)
_c(UnsignedShort)
_c(UnsignedInt)
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "MeshIndexType(" << Debug::nospace << reinterpret_cast<void*>(GLenum(value)) << Debug::nospace << ")";
}
#endif
}
namespace Corrade { namespace Utility {
std::string ConfigurationValue<Magnum::MeshPrimitive>::toString(Magnum::MeshPrimitive value, ConfigurationValueFlags) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case Magnum::MeshPrimitive::value: return #value;
_c(Points)
_c(Lines)
_c(LineLoop)
_c(LineStrip)
_c(Triangles)
_c(TriangleStrip)
_c(TriangleFan)
#undef _c
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
CORRADE_IGNORE_DEPRECATED_PUSH
case Magnum::MeshPrimitive::LinesAdjacency:
case Magnum::MeshPrimitive::LineStripAdjacency:
case Magnum::MeshPrimitive::TrianglesAdjacency:
case Magnum::MeshPrimitive::TriangleStripAdjacency:
case Magnum::MeshPrimitive::Patches:
return {};
CORRADE_IGNORE_DEPRECATED_POP
#endif
/* LCOV_EXCL_STOP */
}
return {};
}
Magnum::MeshPrimitive ConfigurationValue<Magnum::MeshPrimitive>::fromString(const std::string& stringValue, ConfigurationValueFlags) {
/* LCOV_EXCL_START */
#define _c(value) if(stringValue == #value) return Magnum::MeshPrimitive::value;
_c(LineStrip)
_c(LineLoop)
_c(Lines)
_c(Triangles)
_c(TriangleStrip)
_c(TriangleFan)
#undef _c
/* LCOV_EXCL_STOP */
return Magnum::MeshPrimitive::Points;
}
std::string ConfigurationValue<Magnum::MeshIndexType>::toString(Magnum::MeshIndexType value, ConfigurationValueFlags) {
switch(value) {
/* LCOV_EXCL_START */
#define _c(value) case Magnum::MeshIndexType::value: return #value;
_c(UnsignedByte)
_c(UnsignedShort)
_c(UnsignedInt)
#undef _c
/* LCOV_EXCL_STOP */
}
return {};
}
Magnum::MeshIndexType ConfigurationValue<Magnum::MeshIndexType>::fromString(const std::string& stringValue, ConfigurationValueFlags) {
/* LCOV_EXCL_START */
#define _c(value) if(stringValue == #value) return Magnum::MeshIndexType::value;
_c(UnsignedByte)
_c(UnsignedShort)
_c(UnsignedInt)
#undef _c
/* LCOV_EXCL_STOP */
return Magnum::MeshIndexType::UnsignedInt;
}
}}

206
src/Magnum/Mesh.h

@ -26,16 +26,212 @@
*/ */
/** @file /** @file
* @deprecated Use @ref Magnum/GL/Mesh.h instead. * @brief Enum @ref Magnum::MeshPrimitive, @ref Magnum::MeshIndexType, function @ref Magnum::meshIndexTypeSize()
*/ */
#include "Magnum/configure.h" #include <string>
#include "Magnum/Magnum.h"
#include "Magnum/visibility.h"
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) #if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL)
#include "Magnum/GL/Mesh.h" #include "Magnum/GL/Mesh.h"
CORRADE_DEPRECATED_FILE("use Magnum/GL/Mesh.h instead")
#else
#error use Magnum/GL/Mesh.h instead
#endif #endif
namespace Magnum {
/**
@brief Mesh primitive type
In case of OpenGL, corresponds to @ref GL::MeshPrimitive and is convertible to
it using @ref GL::meshPrimitive(). See documentation of each value for more
information about the mapping.
*/
enum class MeshPrimitive: UnsignedInt {
/**
* Single points.
*
* Corresponds to @ref GL::MeshPrimitive::Points.
*/
Points,
/**
* Each pair of vertices defines a single line, lines aren't
* connected together.
*
* Corresponds to @ref GL::MeshPrimitive::Lines.
*/
Lines,
/**
* Line strip, last and first vertex are connected together.
*
* Corresponds to @ref GL::MeshPrimitive::LineLoop.
*/
LineLoop,
/**
* First two vertices define first line segment, each following
* vertex defines another segment.
*
* Corresponds to @ref GL::MeshPrimitive::LineStrip.
*/
LineStrip,
/**
* Each three vertices define one triangle.
*
* Corresponds to @ref GL::MeshPrimitive::Triangles.
*/
Triangles,
/**
* First three vertices define first triangle, each following
* vertex defines another triangle.
*
* Corresponds to @ref GL::MeshPrimitive::TriangleStrip.
*/
TriangleStrip,
/**
* First vertex is center, each following vertex is connected to
* previous and center vertex.
*
* Corresponds to @ref GL::MeshPrimitive::TriangleFan.
*/
TriangleFan,
#if defined(MAGNUM_BUILD_DEPRECATED) && defined(MAGNUM_TARGET_GL) && !defined(MAGNUM_TARGET_GLES2) && !defined(MAGNUM_TARGET_WEBGL)
/**
* Lines with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles32 Extension @extension{ANDROID,extension_pack_es31a} /
* @extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
LinesAdjacency CORRADE_DEPRECATED_ENUM("use GL::MeshPrimitive::Patches instead") = UnsignedInt(GL::MeshPrimitive::LinesAdjacency),
/**
* Line strip with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles32 Extension @extension{ANDROID,extension_pack_es31a} /
* @extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
LineStripAdjacency CORRADE_DEPRECATED_ENUM("use GL::MeshPrimitive::Patches instead") = UnsignedInt(GL::MeshPrimitive::LineStripAdjacency),
/**
* Triangles with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles32 Extension @extension{ANDROID,extension_pack_es31a} /
* @extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
TrianglesAdjacency CORRADE_DEPRECATED_ENUM("use GL::MeshPrimitive::Patches instead") = UnsignedInt(GL::MeshPrimitive::TrianglesAdjacency),
/**
* Triangle strip with adjacency information.
* @requires_gl32 Extension @extension{ARB,geometry_shader4}
* @requires_gles30 Not defined in OpenGL ES 2.0.
* @requires_gles32 Extension @extension{ANDROID,extension_pack_es31a} /
* @extension{EXT,geometry_shader}
* @requires_gles Geometry shaders are not available in WebGL.
*/
TriangleStripAdjacency CORRADE_DEPRECATED_ENUM("use GL::MeshPrimitive::Patches instead") = UnsignedInt(GL::MeshPrimitive::TriangleStripAdjacency),
/**
* Patches.
* @deprecated Use @ref GL::MeshPrimitive::Patches instead
*/
Patches CORRADE_DEPRECATED_ENUM("use GL::MeshPrimitive::Patches instead") = UnsignedInt(GL::MeshPrimitive::Patches)
#endif
};
/** @debugoperatorenum{MeshPrimitive} */
MAGNUM_EXPORT Debug& operator<<(Debug& debug, MeshPrimitive value);
/**
@brief Mesh primitive type
In case of OpenGL, corresponds to @ref GL::MeshIndexType and is convertible to
it using @ref GL::meshIndexType(). See documentation of each value for more
information about the mapping.
@see @ref meshIndexTypeSize()
*/
enum class MeshIndexType: UnsignedInt {
/**
* Unsigned byte
*
* Corresponds to @ref GL::MeshIndexType::UnsignedByte.
*/
UnsignedByte,
/**
* Unsigned short
*
* Corresponds to @ref GL::MeshIndexType::UnsignedShort.
*/
UnsignedShort,
/**
* Unsigned int
*
* Corresponds to @ref GL::MeshIndexType::UnsignedInt.
*/
UnsignedInt
};
/** @brief Size of given mesh index type */
MAGNUM_EXPORT UnsignedInt meshIndexTypeSize(MeshIndexType type);
/** @debugoperatorenum{MeshIndexType} */
MAGNUM_EXPORT Debug& operator<<(Debug& debug, MeshIndexType value);
}
namespace Corrade { namespace Utility {
/** @configurationvalue{Magnum::MeshPrimitive} */
template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::MeshPrimitive> {
ConfigurationValue() = delete;
/**
* @brief Writes enum value as string
*
* If the value is invalid, returns empty string.
*/
static std::string toString(Magnum::MeshPrimitive value, ConfigurationValueFlags);
/**
* @brief Reads enum value as string
*
* If the value is invalid, returns @ref Magnum::MeshPrimitive::Points "MeshPrimitive::Points".
*/
static Magnum::MeshPrimitive fromString(const std::string& stringValue, ConfigurationValueFlags);
};
/** @configurationvalue{Magnum::MeshIndexType} */
template<> struct MAGNUM_EXPORT ConfigurationValue<Magnum::MeshIndexType> {
ConfigurationValue() = delete;
/**
* @brief Write enum value as string
*
* If the value is invalid, returns empty string.
*/
static std::string toString(Magnum::MeshIndexType value, ConfigurationValueFlags);
/**
* @brief Read enum value as string
*
* If the value is invalid, returns @ref Magnum::MeshIndexType::UnsignedInt "MeshIndexType::UnsignedInt".
*/
static Magnum::MeshIndexType fromString(const std::string& stringValue, ConfigurationValueFlags);
};
}}
#endif #endif

2
src/Magnum/Test/CMakeLists.txt

@ -26,6 +26,7 @@
corrade_add_test(ArrayTest ArrayTest.cpp LIBRARIES Magnum) corrade_add_test(ArrayTest ArrayTest.cpp LIBRARIES Magnum)
corrade_add_test(ImageTest ImageTest.cpp LIBRARIES MagnumTestLib) corrade_add_test(ImageTest ImageTest.cpp LIBRARIES MagnumTestLib)
corrade_add_test(ImageViewTest ImageViewTest.cpp LIBRARIES MagnumTestLib) corrade_add_test(ImageViewTest ImageViewTest.cpp LIBRARIES MagnumTestLib)
corrade_add_test(MeshTest MeshTest.cpp LIBRARIES Magnum)
corrade_add_test(PixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumTestLib) corrade_add_test(PixelFormatTest PixelFormatTest.cpp LIBRARIES MagnumTestLib)
target_compile_definitions(PixelFormatTest PRIVATE "CORRADE_GRACEFUL_ASSERT") target_compile_definitions(PixelFormatTest PRIVATE "CORRADE_GRACEFUL_ASSERT")
corrade_add_test(PixelStorageTest PixelStorageTest.cpp LIBRARIES Magnum) corrade_add_test(PixelStorageTest PixelStorageTest.cpp LIBRARIES Magnum)
@ -45,6 +46,7 @@ set_target_properties(
ArrayTest ArrayTest
ImageTest ImageTest
ImageViewTest ImageViewTest
MeshTest
PixelFormatTest PixelFormatTest
PixelStorageTest PixelStorageTest
ResourceManagerTest ResourceManagerTest

98
src/Magnum/Test/MeshTest.cpp

@ -0,0 +1,98 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
Vladimír Vondruš <mosra@centrum.cz>
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included
in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
*/
#include <sstream>
#include <Corrade/TestSuite/Tester.h>
#include <Corrade/Utility/Configuration.h>
#include "Magnum/Mesh.h"
namespace Magnum { namespace Test {
struct MeshTest: TestSuite::Tester {
explicit MeshTest();
void indexTypeSize();
void debugPrimitive();
void debugIndexType();
void configurationPrimitive();
void configurationIndexType();
};
MeshTest::MeshTest() {
addTests({&MeshTest::indexTypeSize,
&MeshTest::debugPrimitive,
&MeshTest::debugIndexType,
&MeshTest::configurationPrimitive,
&MeshTest::configurationIndexType});
}
void MeshTest::indexTypeSize() {
CORRADE_COMPARE(meshIndexTypeSize(MeshIndexType::UnsignedByte), 1);
CORRADE_COMPARE(meshIndexTypeSize(MeshIndexType::UnsignedShort), 2);
CORRADE_COMPARE(meshIndexTypeSize(MeshIndexType::UnsignedInt), 4);
}
void MeshTest::debugPrimitive() {
std::ostringstream o;
Debug(&o) << MeshPrimitive::TriangleFan << MeshPrimitive(0xdead);
CORRADE_COMPARE(o.str(), "MeshPrimitive::TriangleFan MeshPrimitive(0xdead)\n");
}
void MeshTest::debugIndexType() {
std::ostringstream o;
Debug(&o) << MeshIndexType::UnsignedShort << MeshIndexType(0xdead);
CORRADE_COMPARE(o.str(), "MeshIndexType::UnsignedShort MeshIndexType(0xdead)\n");
}
void MeshTest::configurationPrimitive() {
Utility::Configuration c;
c.setValue("primitive", MeshPrimitive::LineStrip);
CORRADE_COMPARE(c.value("primitive"), "LineStrip");
CORRADE_COMPARE(c.value<MeshPrimitive>("primitive"), MeshPrimitive::LineStrip);
c.setValue("invalid", MeshPrimitive(0xdead));
CORRADE_COMPARE(c.value("invalid"), "");
CORRADE_COMPARE(c.value<MeshPrimitive>("invalid"), MeshPrimitive::Points);
}
void MeshTest::configurationIndexType() {
Utility::Configuration c;
c.setValue("type", MeshIndexType::UnsignedShort);
CORRADE_COMPARE(c.value("type"), "UnsignedShort");
CORRADE_COMPARE(c.value<MeshIndexType>("type"), MeshIndexType::UnsignedShort);
c.setValue("invalid", MeshIndexType(0xdead));
CORRADE_COMPARE(c.value("invalid"), "");
CORRADE_COMPARE(c.value<MeshIndexType>("invalid"), MeshIndexType::UnsignedInt);
}
}}
CORRADE_TEST_MAIN(Magnum::Test::MeshTest)

2
src/MagnumPlugins/ObjImporter/Test/Test.cpp

@ -214,7 +214,7 @@ void ObjImporterTest::mixedPrimitives() {
std::ostringstream out; std::ostringstream out;
Error redirectError{&out}; Error redirectError{&out};
CORRADE_VERIFY(!importer->mesh3D(0)); CORRADE_VERIFY(!importer->mesh3D(0));
CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): mixed primitive GL::MeshPrimitive::Points and GL::MeshPrimitive::Lines\n"); CORRADE_COMPARE(out.str(), "Trade::ObjImporter::mesh3D(): mixed primitive MeshPrimitive::Points and MeshPrimitive::Lines\n");
} }
void ObjImporterTest::positionsOnly() { void ObjImporterTest::positionsOnly() {

Loading…
Cancel
Save