Browse Source

Shaders: vertex color support in Phong and Flat.

pull/364/head
Vladimír Vondruš 7 years ago
parent
commit
5617cb5199
  1. 1
      doc/changelog.dox
  2. 11
      src/Magnum/Shaders/Flat.cpp
  3. 7
      src/Magnum/Shaders/Flat.frag
  4. 33
      src/Magnum/Shaders/Flat.h
  5. 14
      src/Magnum/Shaders/Flat2D.vert
  6. 14
      src/Magnum/Shaders/Flat3D.vert
  7. 20
      src/Magnum/Shaders/Phong.cpp
  8. 7
      src/Magnum/Shaders/Phong.frag
  9. 45
      src/Magnum/Shaders/Phong.h
  10. 14
      src/Magnum/Shaders/Phong.vert
  11. 5
      src/Magnum/Shaders/Test/CMakeLists.txt
  12. 123
      src/Magnum/Shaders/Test/FlatGLTest.cpp
  13. BIN
      src/Magnum/Shaders/Test/FlatTestFiles/vertexColor2D.tga
  14. BIN
      src/Magnum/Shaders/Test/FlatTestFiles/vertexColor3D.tga
  15. 72
      src/Magnum/Shaders/Test/PhongGLTest.cpp
  16. BIN
      src/Magnum/Shaders/Test/PhongTestFiles/vertexColor.tga
  17. 5
      src/Magnum/Shaders/VertexColor.h

1
doc/changelog.dox

@ -231,6 +231,7 @@ See also:
- Normal texture support in @ref Shaders::Phong
- Added @ref Shaders::Generic3D::Tangent generic vertex attribute definition
- Object ID output in @ref Shaders::Flat and @ref Shaders::Phong
- Vertex color support in @ref Shaders::Flat and @ref Shaders::Phong
@subsubsection changelog-latest-new-text Text library

11
src/Magnum/Shaders/Flat.cpp

@ -64,10 +64,12 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): _fla
GL::Shader frag = Implementation::createCompatibilityShader(rs, version, GL::Shader::Type::Fragment);
vert.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(rs.get("generic.glsl"))
.addSource(rs.get(vertexShaderName<dimensions>()));
frag.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
.addSource(flags & Flag::AlphaMask ? "#define ALPHA_MASK\n" : "")
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "")
#endif
@ -86,7 +88,10 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): _fla
#endif
{
bindAttributeLocation(Position::Location, "position");
if(flags & Flag::Textured) bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
if(flags & Flag::Textured)
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
if(flags & Flag::VertexColor)
bindAttributeLocation(Color3::Location, "vertexColor"); /* Color4 is the same */
#ifndef MAGNUM_TARGET_GLES2
if(flags & Flag::ObjectId) {
bindFragmentDataLocation(ColorOutput, "color");
@ -120,7 +125,7 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): _fla
/* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES
setTransformationProjectionMatrix({});
setColor(Color4{1.0f});
setColor(Magnum::Color4{1.0f});
if(flags & Flag::AlphaMask) setAlphaMask(0.5f);
/* Object ID is zero by default */
#endif
@ -160,6 +165,7 @@ Debug& operator<<(Debug& debug, const FlatFlag value) {
#define _c(v) case FlatFlag::v: return debug << "Shaders::Flat::Flag::" #v;
_c(Textured)
_c(AlphaMask)
_c(VertexColor)
#ifndef MAGNUM_TARGET_GLES2
_c(ObjectId)
#endif
@ -174,6 +180,7 @@ Debug& operator<<(Debug& debug, const FlatFlags value) {
return Containers::enumSetDebugOutput(debug, value, "Shaders::Flat::Flags{}", {
FlatFlag::Textured,
FlatFlag::AlphaMask,
FlatFlag::VertexColor,
#ifndef MAGNUM_TARGET_GLES2
FlatFlag::ObjectId
#endif

7
src/Magnum/Shaders/Flat.frag

@ -68,6 +68,10 @@ uniform highp uint objectId; /* defaults to zero */
in mediump vec2 interpolatedTextureCoordinates;
#endif
#ifdef VERTEX_COLOR
in lowp vec4 interpolatedVertexColor;
#endif
#ifdef NEW_GLSL
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_OUTPUT_ATTRIBUTE_LOCATION)
@ -87,6 +91,9 @@ void main() {
#ifdef TEXTURED
texture(textureData, interpolatedTextureCoordinates)*
#endif
#ifdef VERTEX_COLOR
interpolatedVertexColor*
#endif
color;
#ifdef ALPHA_MASK

33
src/Magnum/Shaders/Flat.h

@ -43,8 +43,9 @@ namespace Implementation {
enum class FlatFlag: UnsignedByte {
Textured = 1 << 0,
AlphaMask = 1 << 1,
VertexColor = 1 << 2,
#ifndef MAGNUM_TARGET_GLES2
ObjectId = 1 << 2
ObjectId = 1 << 3
#endif
};
typedef Containers::EnumSet<FlatFlag> FlatFlags;
@ -71,6 +72,8 @@ For coloring the texture based on intensity you can use the @ref Vector shader.
The 3D version of this shader is equivalent to @ref Phong with zero lights,
however this implementation is much simpler and thus likely also faster. See
@ref Shaders-Phong-zero-lights "its documentation" for more information.
Conversely, enabling @ref Flag::VertexColor and using a default color with no
texturing makes this shader equivalent to @ref VertexColor.
@section Shaders-Flat-usage Example usage
@ -139,6 +142,24 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab
*/
typedef typename Generic<dimensions>::TextureCoordinates TextureCoordinates;
/**
* @brief Three-component vertex color
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use
* either this or the @ref Color4 attribute. Used only if
* @ref Flag::VertexColor is set.
*/
typedef typename Generic<dimensions>::Color3 Color3;
/**
* @brief Four-component vertex color
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use
* either this or the @ref Color3 attribute. Used only if
* @ref Flag::VertexColor is set.
*/
typedef typename Generic<dimensions>::Color4 Color4;
enum: UnsignedInt {
/**
* Color shader output. Present always, expects three- or
@ -187,6 +208,12 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab
*/
AlphaMask = 1 << 1,
/**
* Multiply diffuse color with a vertex color. Requires either
* the @ref Color3 or @ref Color4 attribute to be present.
*/
VertexColor = 1 << 2,
#ifndef MAGNUM_TARGET_GLES2
/**
* Enable object ID output. See @ref Shaders-Flat-usage-object-id
@ -195,7 +222,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab
* attachments, which are not available in OpenGL ES 2.0 or
* WebGL 1.0.
*/
ObjectId = 1 << 2
ObjectId = 1 << 3
#endif
};
@ -265,7 +292,7 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public GL::Ab
* texture.
* @see @ref bindTexture()
*/
Flat<dimensions>& setColor(const Color4& color){
Flat<dimensions>& setColor(const Magnum::Color4& color) {
setUniform(_colorUniform, color);
return *this;
}

14
src/Magnum/Shaders/Flat2D.vert

@ -51,6 +51,15 @@ in mediump vec2 textureCoordinates;
out mediump vec2 interpolatedTextureCoordinates;
#endif
#ifdef VERTEX_COLOR
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_ATTRIBUTE_LOCATION)
#endif
in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor;
#endif
void main() {
gl_Position.xywz = vec4(transformationProjectionMatrix*vec3(position, 1.0), 0.0);
@ -58,4 +67,9 @@ void main() {
/* Texture coordinates, if needed */
interpolatedTextureCoordinates = textureCoordinates;
#endif
#ifdef VERTEX_COLOR
/* Vertex colors, if enabled */
interpolatedVertexColor = vertexColor;
#endif
}

14
src/Magnum/Shaders/Flat3D.vert

@ -51,6 +51,15 @@ in mediump vec2 textureCoordinates;
out mediump vec2 interpolatedTextureCoordinates;
#endif
#ifdef VERTEX_COLOR
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_ATTRIBUTE_LOCATION)
#endif
in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor;
#endif
void main() {
gl_Position = transformationProjectionMatrix*position;
@ -58,4 +67,9 @@ void main() {
/* Texture coordinates, if needed */
interpolatedTextureCoordinates = textureCoordinates;
#endif
#ifdef VERTEX_COLOR
/* Vertex colors, if enabled */
interpolatedVertexColor = vertexColor;
#endif
}

20
src/Magnum/Shaders/Phong.cpp

@ -92,6 +92,7 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
vert.addSource(flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture|Flag::NormalTexture) ? "#define TEXTURED\n" : "")
.addSource(flags & Flag::NormalTexture ? "#define NORMAL_TEXTURE\n" : "")
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(Utility::formatString("#define LIGHT_COUNT {}\n", lightCount))
.addSource(rs.get("generic.glsl"))
.addSource(rs.get("Phong.vert"));
@ -99,6 +100,7 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
.addSource(flags & Flag::DiffuseTexture ? "#define DIFFUSE_TEXTURE\n" : "")
.addSource(flags & Flag::SpecularTexture ? "#define SPECULAR_TEXTURE\n" : "")
.addSource(flags & Flag::NormalTexture ? "#define NORMAL_TEXTURE\n" : "")
.addSource(flags & Flag::VertexColor ? "#define VERTEX_COLOR\n" : "")
.addSource(flags & Flag::AlphaMask ? "#define ALPHA_MASK\n" : "")
#ifndef MAGNUM_TARGET_GLES2
.addSource(flags & Flag::ObjectId ? "#define OBJECT_ID\n" : "")
@ -128,6 +130,8 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
bindAttributeLocation(Normal::Location, "normal");
if((flags & Flag::NormalTexture) && lightCount)
bindAttributeLocation(Tangent::Location, "tangent");
if(flags & Flag::VertexColor)
bindAttributeLocation(Color3::Location, "vertexColor"); /* Color4 is the same */
if(flags & (Flag::AmbientTexture|Flag::DiffuseTexture|Flag::SpecularTexture))
bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
#ifndef MAGNUM_TARGET_GLES2
@ -177,17 +181,17 @@ Phong::Phong(const Flags flags, const UnsignedInt lightCount): _flags{flags}, _l
/* Set defaults in OpenGL ES (for desktop they are set in shader code itself) */
#ifdef MAGNUM_TARGET_GLES
/* Default to fully opaque white so we can see the textures */
if(flags & Flag::AmbientTexture) setAmbientColor(Color4{1.0f});
else setAmbientColor(Color4{0.0f});
if(flags & Flag::AmbientTexture) setAmbientColor(Magnum::Color4{1.0f});
else setAmbientColor(Magnum::Color4{0.0f});
setTransformationMatrix({});
setProjectionMatrix({});
if(lightCount) {
setDiffuseColor(Color4{1.0f});
setSpecularColor(Color4{1.0f});
setDiffuseColor(Magnum::Color4{1.0f});
setSpecularColor(Magnum::Color4{1.0f});
setShininess(80.0f);
if(flags & Flag::AlphaMask) setAlphaMask(0.5f);
/* Object ID is zero by default */
setLightColors(Containers::Array<Color4>{Containers::DirectInit, lightCount, Color4{1.0f}});
setLightColors(Containers::Array<Magnum::Color4>{Containers::DirectInit, lightCount, Magnum::Color4{1.0f}});
/* Light position is zero by default */
setNormalMatrix({});
}
@ -259,14 +263,14 @@ Phong& Phong::setLightPosition(UnsignedInt id, const Vector3& position) {
return *this;
}
Phong& Phong::setLightColors(const Containers::ArrayView<const Color4> colors) {
Phong& Phong::setLightColors(const Containers::ArrayView<const Magnum::Color4> colors) {
CORRADE_ASSERT(_lightCount == colors.size(),
"Shaders::Phong::setLightColors(): expected" << _lightCount << "items but got" << colors.size(), *this);
if(_lightCount) setUniform(_lightColorsUniform, colors);
return *this;
}
Phong& Phong::setLightColor(UnsignedInt id, const Color4& color) {
Phong& Phong::setLightColor(UnsignedInt id, const Magnum::Color4& color) {
CORRADE_ASSERT(id < _lightCount,
"Shaders::Phong::setLightColor(): light ID" << id << "is out of bounds for" << _lightCount << "lights", *this);
setUniform(_lightColorsUniform + id, color);
@ -282,6 +286,7 @@ Debug& operator<<(Debug& debug, const Phong::Flag value) {
_c(SpecularTexture)
_c(NormalTexture)
_c(AlphaMask)
_c(VertexColor)
#ifndef MAGNUM_TARGET_GLES2
_c(ObjectId)
#endif
@ -299,6 +304,7 @@ Debug& operator<<(Debug& debug, const Phong::Flags value) {
Phong::Flag::SpecularTexture,
Phong::Flag::NormalTexture,
Phong::Flag::AlphaMask,
Phong::Flag::VertexColor,
#ifndef MAGNUM_TARGET_GLES2
Phong::Flag::ObjectId
#endif

7
src/Magnum/Shaders/Phong.frag

@ -149,6 +149,10 @@ in highp vec3 cameraDirection;
in mediump vec2 interpolatedTextureCoords;
#endif
#ifdef VERTEX_COLOR
in lowp vec4 interpolatedVertexColor;
#endif
#ifdef NEW_GLSL
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_OUTPUT_ATTRIBUTE_LOCATION)
@ -174,6 +178,9 @@ void main() {
#ifdef DIFFUSE_TEXTURE
texture(diffuseTexture, interpolatedTextureCoords)*
#endif
#ifdef VERTEX_COLOR
interpolatedVertexColor*
#endif
diffuseColor;
lowp const vec4 finalSpecularColor =
#ifdef SPECULAR_TEXTURE

45
src/Magnum/Shaders/Phong.h

@ -115,6 +115,7 @@ Creating this shader with zero lights makes its output equivalent to the
(if @ref Flag::AmbientTexture is enabled) are taken into account, which
correspond to @ref Flat::setColor() and @ref Flat::bindTexture(). This is
useful to reduce complexity in apps that render models with pre-baked lights.
In addition, enabling @ref Flag::VertexColor and using a default ambient color with no texturing makes this shader equivalent to @ref VertexColor.
@see @ref shaders
*/
@ -155,6 +156,24 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
*/
typedef Generic3D::TextureCoordinates TextureCoordinates;
/**
* @brief Three-component vertex color
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Color3. Use
* either this or the @ref Color4 attribute. Used only if
* @ref Flag::VertexColor is set.
*/
typedef Generic3D::Color3 Color3;
/**
* @brief Four-component vertex color
*
* @ref shaders-generic "Generic attribute", @ref Magnum::Color4. Use
* either this or the @ref Color3 attribute. Used only if
* @ref Flag::VertexColor is set.
*/
typedef Generic3D::Color4 Color4;
enum: UnsignedInt {
/**
* Color shader output. @ref shaders-generic "Generic output",
@ -221,6 +240,12 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
*/
AlphaMask = 1 << 3,
/**
* Multiply diffuse color with a vertex color. Requires either
* the @ref Color3 or @ref Color4 attribute to be present.
*/
VertexColor = 1 << 5,
#ifndef MAGNUM_TARGET_GLES2
/**
* Enable object ID output. See @ref Shaders-Phong-usage-object-id
@ -229,7 +254,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* attachments, which are not available in OpenGL ES 2.0 or
* WebGL 1.0.
*/
ObjectId = 1 << 5
ObjectId = 1 << 6
#endif
};
@ -286,7 +311,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* ambient texture, otherwise default value is @cpp 0x00000000_rgbaf @ce.
* @see @ref bindAmbientTexture()
*/
Phong& setAmbientColor(const Color4& color) {
Phong& setAmbientColor(const Magnum::Color4& color) {
setUniform(_ambientColorUniform, color);
return *this;
}
@ -319,7 +344,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* to the output in that case.
* @see @ref bindDiffuseTexture()
*/
Phong& setDiffuseColor(const Color4& color) {
Phong& setDiffuseColor(const Magnum::Color4& color) {
if(_lightCount) setUniform(_diffuseColorUniform, color);
return *this;
}
@ -368,7 +393,7 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* output in that case.
* @see @ref bindSpecularTexture()
*/
Phong& setSpecularColor(const Color4& color) {
Phong& setSpecularColor(const Magnum::Color4& color) {
if(_lightCount) setUniform(_specularColorUniform, color);
return *this;
}
@ -550,10 +575,10 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
* Initial values are @cpp 0xffffffff_rgbaf @ce. Expects that the size
* of the @p colors array is the same as @ref lightCount().
*/
Phong& setLightColors(Containers::ArrayView<const Color4> colors);
Phong& setLightColors(Containers::ArrayView<const Magnum::Color4> colors);
/** @overload */
Phong& setLightColors(std::initializer_list<Color4> colors) {
Phong& setLightColors(std::initializer_list<Magnum::Color4> colors) {
return setLightColors({colors.begin(), colors.size()});
}
@ -563,9 +588,9 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
*
* Unlike @ref setLightColors() updates just a single light color.
* Expects that @p id is less than @ref lightCount().
* @see @ref setLightColor(const Color4&)
* @see @ref setLightColor(const Magnum::Color4&)
*/
Phong& setLightColor(UnsignedInt id, const Color4& color);
Phong& setLightColor(UnsignedInt id, const Magnum::Color4& color);
/**
* @brief Set light color
@ -573,9 +598,9 @@ class MAGNUM_SHADERS_EXPORT Phong: public GL::AbstractShaderProgram {
*
* Convenience alternative to @ref setLightColors() when there is just
* one light.
* @see @ref setLightColor(UnsignedInt, const Color4&)
* @see @ref setLightColor(UnsignedInt, const Magnum::Color4&)
*/
Phong& setLightColor(const Color4& color) {
Phong& setLightColor(const Magnum::Color4& color) {
return setLightColors({&color, 1});
}

14
src/Magnum/Shaders/Phong.vert

@ -93,6 +93,15 @@ in mediump vec2 textureCoords;
out mediump vec2 interpolatedTextureCoords;
#endif
#ifdef VERTEX_COLOR
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = COLOR_ATTRIBUTE_LOCATION)
#endif
in lowp vec4 vertexColor;
out lowp vec4 interpolatedVertexColor;
#endif
#if LIGHT_COUNT
out mediump vec3 transformedNormal;
#ifdef NORMAL_TEXTURE
@ -129,4 +138,9 @@ void main() {
/* Texture coordinates, if needed */
interpolatedTextureCoords = textureCoords;
#endif
#ifdef VERTEX_COLOR
/* Vertex colors, if enabled */
interpolatedVertexColor = vertexColor;
#endif
}

5
src/Magnum/Shaders/Test/CMakeLists.txt

@ -94,7 +94,9 @@ if(BUILD_GL_TESTS)
FlatTestFiles/textured2D-alpha.tga
FlatTestFiles/textured3D-alpha.tga
FlatTestFiles/textured2D-alpha-mask0.5.tga
FlatTestFiles/textured3D-alpha-mask0.5.tga)
FlatTestFiles/textured3D-alpha-mask0.5.tga
FlatTestFiles/vertexColor2D.tga
FlatTestFiles/vertexColor3D.tga)
if(NOT BUILD_PLUGINS_STATIC)
target_include_directories(ShadersFlatGLTest PRIVATE $<TARGET_FILE_DIR:ShadersPhongGLTest>)
else()
@ -140,6 +142,7 @@ if(BUILD_GL_TESTS)
PhongTestFiles/textured-normal.tga
PhongTestFiles/textured-specular.tga
PhongTestFiles/textured.tga
PhongTestFiles/vertexColor.tga
# For zero lights test (equivalency to Flat3D)
FlatTestFiles/textured3D-alpha-mask0.5.tga)

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

@ -80,6 +80,9 @@ struct FlatGLTest: GL::OpenGLTester {
void renderTextured2D();
void renderTextured3D();
template<class T> void renderVertexColor2D();
template<class T> void renderVertexColor3D();
void renderAlphaSetup();
void renderAlphaTeardown();
@ -127,6 +130,8 @@ constexpr struct {
{"textured", Flat2D::Flag::Textured},
{"alpha mask", Flat2D::Flag::AlphaMask},
{"alpha mask + textured", Flat2D::Flag::AlphaMask|Flat2D::Flag::Textured},
{"vertex colors", Flat2D::Flag::VertexColor},
{"vertex colors + textured", Flat2D::Flag::VertexColor|Flat2D::Flag::Textured},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", Flat2D::Flag::ObjectId},
{"object ID + alpha mask + textured", Flat2D::Flag::ObjectId|Flat2D::Flag::AlphaMask|Flat2D::Flag::Textured}
@ -182,7 +187,11 @@ FlatGLTest::FlatGLTest() {
&FlatGLTest::renderSinglePixelTextured2D,
&FlatGLTest::renderSinglePixelTextured3D,
&FlatGLTest::renderTextured2D,
&FlatGLTest::renderTextured3D},
&FlatGLTest::renderTextured3D,
&FlatGLTest::renderVertexColor2D<Color3>,
&FlatGLTest::renderVertexColor2D<Color4>,
&FlatGLTest::renderVertexColor3D<Color3>,
&FlatGLTest::renderVertexColor3D<Color4>},
&FlatGLTest::renderSetup,
&FlatGLTest::renderTeardown);
@ -603,6 +612,118 @@ void FlatGLTest::renderTextured3D() {
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
}
template<class T> void FlatGLTest::renderVertexColor2D() {
setTestCaseTemplateName(T::Size == 3 ? "Color3" : "Color4");
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found.");
Trade::MeshData2D circleData = Primitives::circle2DSolid(32,
Primitives::CircleTextureCoords::Generate);
/* Highlight a quarter */
Containers::Array<T> colorData{Containers::DirectInit, circleData.positions(0).size(), 0x999999_rgbf};
for(std::size_t i = 8; i != 16; ++i)
colorData[i + 1] = 0xffff99_rgbf*1.5f;
GL::Buffer colors;
colors.setData(colorData);
GL::Mesh circle = MeshTools::compile(circleData);
circle.addVertexBuffer(colors, 0, GL::Attribute<Shaders::Flat2D::Color3::Location, T>{});
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
GL::Texture2D texture;
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(SHADERS_TEST_DIR, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0)));
texture.setMinificationFilter(GL::SamplerFilter::Linear)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, TextureFormatRGB, image->size())
.setSubImage(0, {}, *image);
Flat2D shader{Flat2D::Flag::Textured|Flat2D::Flag::VertexColor};
shader.setTransformationProjectionMatrix(Matrix3::projection({2.1f, 2.1f}))
.setColor(0x9999ff_rgbf)
.bindTexture(texture);
circle.draw(shader);
MAGNUM_VERIFY_NO_GL_ERROR();
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
/* SwiftShader has minor rounding errors. ARM Mali slightly more */
const Float maxThreshold = 1.334f, meanThreshold = 0.015f;
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage, so it's worse */
const Float maxThreshold = 1.334f, meanThreshold = 0.013f;
#endif
CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/vertexColor2D.tga"),
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
}
template<class T> void FlatGLTest::renderVertexColor3D() {
setTestCaseTemplateName(T::Size == 3 ? "Color3" : "Color4");
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found.");
Trade::MeshData3D sphereData = Primitives::uvSphereSolid(16, 32,
Primitives::UVSphereTextureCoords::Generate);
/* Highlight the middle rings */
Containers::Array<T> colorData{Containers::DirectInit, sphereData.positions(0).size(), 0x999999_rgbf};
for(std::size_t i = 6*33; i != 9*33; ++i)
colorData[i + 1] = 0xffff99_rgbf*1.5f;
GL::Buffer colors;
colors.setData(colorData);
GL::Mesh sphere = MeshTools::compile(sphereData);
sphere.addVertexBuffer(colors, 0, GL::Attribute<Shaders::Flat3D::Color4::Location, T>{});
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
GL::Texture2D texture;
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(SHADERS_TEST_DIR, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0)));
texture.setMinificationFilter(GL::SamplerFilter::Linear)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, TextureFormatRGB, image->size())
.setSubImage(0, {}, *image);
Flat3D shader{Flat3D::Flag::Textured|Flat3D::Flag::VertexColor};
shader.setTransformationProjectionMatrix(
Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f)*
Matrix4::translation(Vector3::zAxis(-2.15f))*
Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf))
.setColor(0x9999ff_rgbf)
.bindTexture(texture);
sphere.draw(shader);
MAGNUM_VERIFY_NO_GL_ERROR();
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
/* SwiftShader has some minor differences on the edges */
const Float maxThreshold = 76.67f, meanThreshold = 0.072f;
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage, so it's worse */
const Float maxThreshold = 76.67f, meanThreshold = 0.072f;
#endif
CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join(SHADERS_TEST_DIR, "FlatTestFiles/vertexColor3D.tga"),
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
}
void FlatGLTest::renderAlphaSetup() {
renderSetup();
if(RenderAlphaData[testCaseInstanceId()].blending)

BIN
src/Magnum/Shaders/Test/FlatTestFiles/vertexColor2D.tga

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
src/Magnum/Shaders/Test/FlatTestFiles/vertexColor3D.tga

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

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

@ -81,6 +81,8 @@ struct PhongGLTest: GL::OpenGLTester {
void renderTextured();
void renderTexturedNormal();
template<class T> void renderVertexColor();
void renderShininess();
void renderAlphaSetup();
@ -137,6 +139,8 @@ constexpr struct {
{"ambient + diffuse + specular + normal texture", Phong::Flag::AmbientTexture|Phong::Flag::DiffuseTexture|Phong::Flag::SpecularTexture|Phong::Flag::NormalTexture, 1},
{"alpha mask", Phong::Flag::AlphaMask, 1},
{"alpha mask + diffuse texture", Phong::Flag::AlphaMask|Phong::Flag::DiffuseTexture, 1},
{"vertex colors", Phong::Flag::VertexColor, 1},
{"vertex colors + diffuse texture", Phong::Flag::VertexColor|Phong::Flag::DiffuseTexture, 1},
#ifndef MAGNUM_TARGET_GLES2
{"object ID", Phong::Flag::ObjectId, 1},
{"object ID + alpha mask + specular texture", Phong::Flag::ObjectId|Phong::Flag::AlphaMask|Phong::Flag::SpecularTexture, 1},
@ -286,6 +290,11 @@ PhongGLTest::PhongGLTest() {
&PhongGLTest::renderSetup,
&PhongGLTest::renderTeardown);
addTests({&PhongGLTest::renderVertexColor<Color3>,
&PhongGLTest::renderVertexColor<Color4>},
&PhongGLTest::renderSetup,
&PhongGLTest::renderTeardown);
addInstancedTests({&PhongGLTest::renderShininess},
Containers::arraySize(RenderShininessData),
&PhongGLTest::renderSetup,
@ -817,6 +826,69 @@ void PhongGLTest::renderTexturedNormal() {
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
}
template<class T> void PhongGLTest::renderVertexColor() {
setTestCaseTemplateName(T::Size == 3 ? "Color3" : "Color4");
if(!(_manager.loadState("AnyImageImporter") & PluginManager::LoadState::Loaded) ||
!(_manager.loadState("TgaImporter") & PluginManager::LoadState::Loaded))
CORRADE_SKIP("AnyImageImporter / TgaImageImporter plugins not found.");
Trade::MeshData3D sphereData = Primitives::uvSphereSolid(16, 32,
Primitives::UVSphereTextureCoords::Generate);
/* Highlight the middle rings */
Containers::Array<T> colorData{Containers::DirectInit, sphereData.positions(0).size(), 0x999999_rgbf};
for(std::size_t i = 6*33; i != 9*33; ++i)
colorData[i + 1] = 0xffff99_rgbf*1.5f;
GL::Buffer colors;
colors.setData(colorData);
GL::Mesh sphere = MeshTools::compile(sphereData);
sphere.addVertexBuffer(colors, 0, GL::Attribute<Shaders::Phong::Color3::Location, T>{});
Containers::Pointer<Trade::AbstractImporter> importer = _manager.loadAndInstantiate("AnyImageImporter");
CORRADE_VERIFY(importer);
GL::Texture2D diffuse;
Containers::Optional<Trade::ImageData2D> image;
CORRADE_VERIFY(importer->openFile(Utility::Directory::join(SHADERS_TEST_DIR, "TestFiles/diffuse-texture.tga")) && (image = importer->image2D(0)));
diffuse.setMinificationFilter(GL::SamplerFilter::Linear)
.setMagnificationFilter(GL::SamplerFilter::Linear)
.setWrapping(GL::SamplerWrapping::ClampToEdge)
.setStorage(1, TextureFormatRGB, image->size())
.setSubImage(0, {}, *image);
Phong shader{Phong::Flag::DiffuseTexture|Phong::Flag::VertexColor, 2};
shader.setLightPositions({{-3.0f, -3.0f, 0.0f},
{ 3.0f, -3.0f, 0.0f}})
.setTransformationMatrix(
Matrix4::translation(Vector3::zAxis(-2.15f))*
Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf))
/** @todo use normalMatrix() instead */
.setNormalMatrix((Matrix4::rotationY(-15.0_degf)*
Matrix4::rotationX(15.0_degf)).rotationScaling())
.setProjectionMatrix(Matrix4::perspectiveProjection(60.0_degf, 1.0f, 0.1f, 10.0f))
.setDiffuseColor(0x9999ff_rgbf)
.bindDiffuseTexture(diffuse);
sphere.draw(shader);
MAGNUM_VERIFY_NO_GL_ERROR();
#if !(defined(MAGNUM_TARGET_GLES2) && defined(MAGNUM_TARGET_WEBGL))
/* SwiftShader has some minor differences on the edges */
const Float maxThreshold = 105.4f, meanThreshold = 0.075f;
#else
/* WebGL 1 doesn't have 8bit renderbuffer storage, so it's worse */
const Float maxThreshold = 105.4f, meanThreshold = 0.075f;
#endif
CORRADE_COMPARE_WITH(
/* Dropping the alpha channel, as it's always 1.0 */
Containers::arrayCast<Color3ub>(_framebuffer.read(_framebuffer.viewport(), {PixelFormat::RGBA8Unorm}).pixels<Color4ub>()),
Utility::Directory::join(SHADERS_TEST_DIR, "PhongTestFiles/vertexColor.tga"),
(DebugTools::CompareImageToFile{_manager, maxThreshold, meanThreshold}));
}
void PhongGLTest::renderShininess() {
auto&& data = RenderShininessData[testCaseInstanceId()];
setTestCaseDescription(data.name);

BIN
src/Magnum/Shaders/Test/PhongTestFiles/vertexColor.tga

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

5
src/Magnum/Shaders/VertexColor.h

@ -49,6 +49,11 @@ configure the shader.
@image html shaders-vertexcolor.png width=256px
This shader is equivalent to @ref Flat with @ref Flat::Flag::VertexColor
enabled; the 3D version of this shader is equivalent to @ref Phong with
@ref Phong::Flag::VertexColor enabled. In both cases this implementation is
much simpler and thus likely also faster.
@section Shaders-VertexColor-example Example usage
Common mesh setup. The shader accepts either three- or four-component color

Loading…
Cancel
Save