From 598b456eb75cf26b89d4f78746d14ea4e41b8602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 18 May 2014 18:37:25 +0200 Subject: [PATCH] Implemented ARB_vertex_type_10f_11f_11f_rev (GL 4.4). Please don't look into AbstractShaderProgram::Attribute implementation. Your life will never be the same afterwards. --- doc/opengl-support.dox | 2 +- src/Magnum/AbstractShaderProgram.cpp | 46 ++++++++++++++++++++++++++++ src/Magnum/AbstractShaderProgram.h | 44 ++++++++++++++++++++++++++ src/Magnum/Test/MeshGLTest.cpp | 21 +++++++++++++ 4 files changed, 112 insertions(+), 1 deletion(-) diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index 1acebb414..78f4e3d4c 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -205,7 +205,7 @@ following: @extension{ARB,query_buffer_object} | | @extension{ARB,texture_mirror_clamp_to_edge} | done @extension{ARB,texture_stencil8} | done -@extension{ARB,vertex_type_10f_11f_11f_rev} | | +@extension{ARB,vertex_type_10f_11f_11f_rev} | done @subsection opengl-support-extensions OpenGL extensions diff --git a/src/Magnum/AbstractShaderProgram.cpp b/src/Magnum/AbstractShaderProgram.cpp index 572fc72ba..2daf03574 100644 --- a/src/Magnum/AbstractShaderProgram.cpp +++ b/src/Magnum/AbstractShaderProgram.cpp @@ -1219,6 +1219,31 @@ UnsignedInt DoubleAttribute::size(GLint components, DataType dataType) { } #endif +UnsignedInt Attribute>::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + #ifndef MAGNUM_TARGET_GLES + case DataType::Double: + return 8*components; + case DataType::UnsignedInt10f11f11fRev: + CORRADE_INTERNAL_ASSERT(components == 3); + return 4; + #endif + } + + CORRADE_ASSERT_UNREACHABLE(); +} + UnsignedInt Attribute>::size(GLint components, DataType dataType) { #ifndef MAGNUM_TARGET_GLES if(components == GL_BGRA) components = 4; @@ -1395,6 +1420,27 @@ Debug operator<<(Debug debug, DoubleAttribute::DataType value) { } #endif +Debug operator<<(Debug debug, Attribute>::DataType value) { + switch(value) { + #define _c(value) case Attribute>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(HalfFloat) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + _c(UnsignedInt10f11f11fRev) + #endif + #undef _c + } + + return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; +} + Debug operator<<(Debug debug, Attribute>::DataType value) { switch(value) { #define _c(value) case Attribute>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h index bf000e90d..8f56feb1b 100644 --- a/src/Magnum/AbstractShaderProgram.h +++ b/src/Magnum/AbstractShaderProgram.h @@ -1063,6 +1063,15 @@ template class AbstractShaderProgram::Attribute { * @requires_gl Only floats are available in OpenGL ES. */ Double = GL_DOUBLE, + + /** + * Unsigned 10.11.11 packed float. Only for three-component float + * vector attribute type. + * @requires_gl44 %Extension @extension{ARB,vertex_type_10f_11f_11f_rev} + * @requires_gl Packed float attributes are not available in OpenGL + * ES. + */ + UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV, #endif /* GL_FIXED not supported */ @@ -1329,6 +1338,41 @@ struct DoubleAttribute { Debug MAGNUM_EXPORT operator<<(Debug debug, DoubleAttribute::DataType value); #endif +/* Floating-point three-component vector has additional data type compared to + classic floats */ +template<> struct Attribute>: SizedAttribute<1, 3> { + typedef Float ScalarType; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + #ifndef MAGNUM_TARGET_GLES2 + HalfFloat = GL_HALF_FLOAT, + #else + HalfFloat = GL_HALF_FLOAT_OES, + #endif + Float = GL_FLOAT + + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE, + UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV + #endif + }; + constexpr static DataType DefaultDataType = DataType::Float; + + typedef FloatAttribute::DataOption DataOption; + typedef FloatAttribute::DataOptions DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); + /* Floating-point four-component vector is absolutely special case */ template<> struct Attribute> { typedef Float ScalarType; diff --git a/src/Magnum/Test/MeshGLTest.cpp b/src/Magnum/Test/MeshGLTest.cpp index 5fbefcfaf..bd7c49837 100644 --- a/src/Magnum/Test/MeshGLTest.cpp +++ b/src/Magnum/Test/MeshGLTest.cpp @@ -88,6 +88,7 @@ class MeshGLTest: public AbstractOpenGLTester { void addVertexBufferFloatWithHalfFloat(); #ifndef MAGNUM_TARGET_GLES void addVertexBufferFloatWithDouble(); + void addVertexBufferVector3WithUnsignedInt10f11f11fRev(); #endif #ifndef MAGNUM_TARGET_GLES2 void addVertexBufferVector4WithUnsignedInt2101010Rev(); @@ -177,6 +178,7 @@ MeshGLTest::MeshGLTest() { &MeshGLTest::addVertexBufferFloatWithHalfFloat, #ifndef MAGNUM_TARGET_GLES &MeshGLTest::addVertexBufferFloatWithDouble, + &MeshGLTest::addVertexBufferVector3WithUnsignedInt10f11f11fRev, #endif #ifndef MAGNUM_TARGET_GLES2 &MeshGLTest::addVertexBufferVector4WithUnsignedInt2101010Rev, @@ -923,6 +925,25 @@ void MeshGLTest::addVertexBufferFloatWithDouble() { MAGNUM_VERIFY_NO_ERROR(); CORRADE_COMPARE(value, 186); } + +void MeshGLTest::addVertexBufferVector3WithUnsignedInt10f11f11fRev() { + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + CORRADE_SKIP(Extensions::GL::ARB::vertex_type_10f_11f_11f_rev::string() + std::string(" is not available.")); + #endif + + typedef AbstractShaderProgram::Attribute<0, Vector3> Attribute; + + Buffer buffer; + buffer.setData({nullptr, 12}, BufferUsage::StaticDraw); + + Mesh mesh; + mesh.setBaseVertex(1) + .addVertexBuffer(buffer, 4, Attribute(Attribute::DataType::UnsignedInt10f11f11fRev)); + + MAGNUM_VERIFY_NO_ERROR(); + /* Won't test the actual values */ +} #endif #ifndef MAGNUM_TARGET_GLES2