Browse Source

Shaders: textured version of Flat shader.

pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
60d8d1af16
  1. 28
      src/Shaders/Flat.cpp
  2. 17
      src/Shaders/Flat.frag
  3. 82
      src/Shaders/Flat.h
  4. 15
      src/Shaders/Flat2D.vert
  5. 15
      src/Shaders/Flat3D.vert
  6. 16
      src/Shaders/Test/FlatTest.cpp

28
src/Shaders/Flat.cpp

@ -37,7 +37,7 @@ namespace {
template<> constexpr const char* vertexShaderName<3>() { return "Flat3D.vert"; }
}
template<UnsignedInt dimensions> Flat<dimensions>::Flat(): transformationProjectionMatrixUniform(0), colorUniform(1) {
template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): transformationProjectionMatrixUniform(0), colorUniform(1), _flags(flags) {
Utility::Resource rs("MagnumShaders");
#ifndef MAGNUM_TARGET_GLES
@ -46,18 +46,20 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(): transformationProject
const Version version = Context::current()->supportedVersion({Version::GLES300, Version::GLES200});
#endif
Shader frag(version, Shader::Type::Vertex);
frag.addSource(rs.get("compatibility.glsl"))
.addSource(rs.get(vertexShaderName<dimensions>()));
CORRADE_INTERNAL_ASSERT_OUTPUT(frag.compile());
attachShader(frag);
Shader vert(version, Shader::Type::Fragment);
vert.addSource(rs.get("compatibility.glsl"))
vert.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
.addSource(rs.get("compatibility.glsl"))
.addSource(rs.get("Flat.frag"));
CORRADE_INTERNAL_ASSERT_OUTPUT(vert.compile());
attachShader(vert);
Shader frag(version, Shader::Type::Vertex);
frag.addSource(flags & Flag::Textured ? "#define TEXTURED\n" : "")
.addSource(rs.get("compatibility.glsl"))
.addSource(rs.get(vertexShaderName<dimensions>()));
CORRADE_INTERNAL_ASSERT_OUTPUT(frag.compile());
attachShader(frag);
#ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isExtensionSupported<Extensions::GL::ARB::explicit_attrib_location>(version))
#else
@ -65,6 +67,7 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(): transformationProject
#endif
{
bindAttributeLocation(Position::Location, "position");
if(flags & Flag::Textured) bindAttributeLocation(TextureCoordinates::Location, "textureCoordinates");
}
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
@ -74,7 +77,14 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(): transformationProject
#endif
{
transformationProjectionMatrixUniform = uniformLocation("transformationProjectionMatrix");
colorUniform = uniformLocation("color");
if(!(flags & Flag::Textured)) colorUniform = uniformLocation("color");
}
#ifndef MAGNUM_TARGET_GLES
if(flags && !Context::current()->isExtensionSupported<Extensions::GL::ARB::shading_language_420pack>(version))
#endif
{
if(flags & Flag::Textured) setUniform(uniformLocation("textureData"), TextureLayer);
}
}

17
src/Shaders/Flat.frag

@ -24,18 +24,35 @@
#ifndef NEW_GLSL
#define fragmentColor gl_FragColor
#define texture texture2D
#endif
#ifdef TEXTURED
#ifdef EXPLICIT_TEXTURE_LAYER
layout(binding = 0) uniform sampler2D textureData;
#else
uniform sampler2D textureData;
#endif
#else
#ifdef EXPLICIT_UNIFORM_LOCATION
layout(location = 1) uniform vec4 color;
#else
uniform lowp vec4 color;
#endif
#endif
#ifdef TEXTURED
in mediump vec2 interpolatedTextureCoords;
#endif
#ifdef NEW_GLSL
out lowp vec4 fragmentColor;
#endif
void main() {
#ifdef TEXTURED
fragmentColor = texture(textureData, interpolatedTextureCoords);
#else
fragmentColor = color;
#endif
}

82
src/Shaders/Flat.h

@ -38,18 +38,78 @@
namespace Magnum { namespace Shaders {
namespace Implementation {
enum class FlatFlag: UnsignedByte { Textured = 1 << 0 };
typedef Containers::EnumSet<FlatFlag, UnsignedByte> FlatFlags;
}
/**
@brief Flat shader
Draws whole mesh with one color.
@see Flat2D, Flat3D
Draws whole mesh with given unshaded color or texture. For colored mesh you
need to provide @ref Position attribute in your triangle mesh and call at least
@ref setTransformationProjectionMatrix() and @ref setColor().
If you want to use texture instead of color, you need to provide also
@ref TextureCoordinates attribute. Pass @ref Flag::Textured to constructor and
then at render time bind the texture to its respective layer instead of calling
@ref setColor(). Example:
@code
Shaders::Flat2D shader(Shaders::Flat2D::Flag::Textured);
// ...
myTexture.bind(Shaders::Flat2D::TextureLayer);
@endcode
@see @ref Flat2D, @ref Flat3D
*/
template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public AbstractShaderProgram {
public:
/** @brief Vertex position */
typedef Attribute<0, typename DimensionTraits<dimensions, Float>::VectorType> Position;
explicit Flat();
/**
* @brief Texture coordinates
*
* Used only if @ref Flag::Textured is set.
*/
typedef Attribute<2, Vector2> TextureCoordinates;
enum: Int {
/** Layer for color texture. Used only if @ref Flag::Textured is set. */
TextureLayer = 0
};
#ifdef DOXYGEN_GENERATING_OUTPUT
/**
* @brief Shader flag
*
* @see @ref Flags, @ref flags()
*/
enum class Flag: UnsignedByte {
Textured = 1 << 0 /**< The shader uses texture instead of color */
};
/**
* @brief Shader flags
*
* @see @ref flags()
*/
typedef Containers::EnumSet<Flag, UnsignedByte> Flags;
#else
typedef Implementation::FlatFlag Flag;
typedef Implementation::FlatFlags Flags;
#endif
/**
* @brief Constructor
* @param flags Shader flags
*/
explicit Flat(Flags flags = Flags());
/** @brief Shader flags */
Flags flags() const { return _flags; }
/**
* @brief Set transformation and projection matrix
@ -63,15 +123,16 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public Abstra
/**
* @brief Set color
* @return Reference to self (for method chaining)
*
* Has no effect if @ref Flag::Textured is set.
*/
Flat<dimensions>& setColor(const Color4& color) {
setUniform(colorUniform, color);
return *this;
}
Flat<dimensions>& setColor(const Color4& color);
private:
Int transformationProjectionMatrixUniform,
colorUniform;
Flags _flags;
};
/** @brief 2D flat shader */
@ -80,6 +141,13 @@ typedef Flat<2> Flat2D;
/** @brief 3D flat shader */
typedef Flat<3> Flat3D;
CORRADE_ENUMSET_OPERATORS(Implementation::FlatFlags)
template<UnsignedInt dimensions> inline Flat<dimensions>& Flat<dimensions>::setColor(const Color4& color) {
if(!(_flags & Flag::Textured)) setUniform(colorUniform, color);
return *this;
}
}}
#endif

15
src/Shaders/Flat2D.vert

@ -24,6 +24,7 @@
#ifndef NEW_GLSL
#define in attribute
#define out varying
#endif
#ifdef EXPLICIT_UNIFORM_LOCATION
@ -38,6 +39,20 @@ layout(location = 0) in highp vec2 position;
in highp vec2 position;
#endif
#ifdef TEXTURED
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = 1) in mediump vec2 textureCoords;
#else
in mediump vec2 textureCoords;
#endif
out mediump vec2 interpolatedTextureCoords;
#endif
void main() {
gl_Position.xywz = vec4(transformationProjectionMatrix*vec3(position, 1.0), 0.0);
#ifdef TEXTURED
/* Texture coordinates, if needed */
interpolatedTextureCoords = textureCoords;
#endif
}

15
src/Shaders/Flat3D.vert

@ -24,6 +24,7 @@
#ifndef NEW_GLSL
#define in attribute
#define out varying
#endif
#ifdef EXPLICIT_UNIFORM_LOCATION
@ -38,6 +39,20 @@ layout(location = 0) in highp vec4 position;
in highp vec4 position;
#endif
#ifdef TEXTURED
#ifdef EXPLICIT_ATTRIB_LOCATION
layout(location = 1) in mediump vec2 textureCoords;
#else
in mediump vec2 textureCoords;
#endif
out mediump vec2 interpolatedTextureCoords;
#endif
void main() {
gl_Position = transformationProjectionMatrix*position;
#ifdef TEXTURED
/* Texture coordinates, if needed */
interpolatedTextureCoords = textureCoords;
#endif
}

16
src/Shaders/Test/FlatTest.cpp

@ -33,11 +33,15 @@ class FlatTest: public Magnum::Test::AbstractOpenGLTester {
void compile2D();
void compile3D();
void compile2DTextured();
void compile3DTextured();
};
FlatTest::FlatTest() {
addTests({&FlatTest::compile2D,
&FlatTest::compile3D});
&FlatTest::compile3D,
&FlatTest::compile2DTextured,
&FlatTest::compile3DTextured});
}
void FlatTest::compile2D() {
@ -50,6 +54,16 @@ void FlatTest::compile3D() {
CORRADE_VERIFY(shader.validate().first);
}
void FlatTest::compile2DTextured() {
Shaders::Flat2D shader(Shaders::Flat2D::Flag::Textured);
CORRADE_VERIFY(shader.validate().first);
}
void FlatTest::compile3DTextured() {
Shaders::Flat3D shader(Shaders::Flat3D::Flag::Textured);
CORRADE_VERIFY(shader.validate().first);
}
}}}
CORRADE_TEST_MAIN(Magnum::Shaders::Test::FlatTest)

Loading…
Cancel
Save