diff --git a/src/Shaders/CMakeLists.txt b/src/Shaders/CMakeLists.txt index 96f1708c7..aa1b50560 100644 --- a/src/Shaders/CMakeLists.txt +++ b/src/Shaders/CMakeLists.txt @@ -1,11 +1,13 @@ corrade_add_resource(MagnumShaders_RCS MagnumShaders FlatShader2D.vert FlatShader2D.frag PhongShader.vert PhongShader.frag + TextShader2D.vert TextShader2D.frag VertexColorShader2D.vert VertexColorShader2D.frag compatibility.glsl) set(MagnumShaders_SRCS FlatShader.cpp PhongShader.cpp + TextShader.cpp VertexColorShader.cpp ${MagnumShaders_RCS}) set(MagnumShaders_HEADERS @@ -13,6 +15,7 @@ set(MagnumShaders_HEADERS FlatShader.h PhongShader.h Shaders.h + TextShader.h VertexColorShader.h magnumShadersVisibility.h) diff --git a/src/Shaders/Shaders.h b/src/Shaders/Shaders.h index 846a0c3f1..80052a755 100644 --- a/src/Shaders/Shaders.h +++ b/src/Shaders/Shaders.h @@ -33,6 +33,10 @@ typedef FlatShader<3> FlatShader3D; class PhongShader; +template class TextShader; +typedef TextShader<2> TextShader2D; +typedef TextShader<3> TextShader3D; + template class VertexColorShader; typedef VertexColorShader<2> VertexColorShader2D; typedef VertexColorShader<3> VertexColorShader3D; diff --git a/src/Shaders/TextShader.cpp b/src/Shaders/TextShader.cpp new file mode 100644 index 000000000..69a61d762 --- /dev/null +++ b/src/Shaders/TextShader.cpp @@ -0,0 +1,88 @@ +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +#include "TextShader.h" + +#include + +#include "Context.h" +#include "Extensions.h" +#include "Shader.h" + +namespace Magnum { namespace Shaders { + +namespace { + template struct ShaderName {}; + + template<> struct ShaderName<2> { + constexpr static const char* vertex() { return "TextShader2D.vert"; } + constexpr static const char* fragment() { return "TextShader2D.frag"; } + }; + + template<> struct ShaderName<3> { + constexpr static const char* vertex() { return "TextShader3D.vert"; } + constexpr static const char* fragment() { return "TextShader3D.frag"; } + }; +} + +template TextShader::TextShader() { + Corrade::Utility::Resource rs("MagnumShaders"); + + #ifndef MAGNUM_TARGET_GLES + Version v = Context::current()->supportedVersion({Version::GL320, Version::GL210}); + #else + Version v = Context::current()->supportedVersion({Version::GLES300, Version::GLES200}); + #endif + + Shader vertexShader(v, Shader::Type::Vertex); + vertexShader.addSource(rs.get("compatibility.glsl")); + vertexShader.addSource(rs.get(ShaderName::vertex())); + AbstractTextShader::attachShader(vertexShader); + + Shader fragmentShader(v, Shader::Type::Fragment); + fragmentShader.addSource(rs.get("compatibility.glsl")); + fragmentShader.addSource(rs.get(ShaderName::fragment())); + AbstractTextShader::attachShader(fragmentShader); + + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) { + #else + if(!Context::current()->isVersionSupported(Version::GLES300)) { + #endif + AbstractTextShader::bindAttributeLocation(AbstractTextShader::Position::Location, "position"); + AbstractTextShader::bindAttributeLocation(AbstractTextShader::TextureCoordinates::Location, "textureCoordinates"); + } + + AbstractTextShader::link(); + + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) { + #else + { + #endif + transformationProjectionMatrixUniform = AbstractTextShader::uniformLocation("transformationProjectionMatrix"); + colorUniform = AbstractTextShader::uniformLocation("color"); + } + + #ifndef MAGNUM_TARGET_GLES + if(!Context::current()->isExtensionSupported()) + AbstractTextShader::setUniform(AbstractTextShader::uniformLocation("fontTexture"), AbstractTextShader::FontTextureLayer); + #endif +} + +template class TextShader<2>; +template class TextShader<3>; + +}} diff --git a/src/Shaders/TextShader.h b/src/Shaders/TextShader.h new file mode 100644 index 000000000..de2d06523 --- /dev/null +++ b/src/Shaders/TextShader.h @@ -0,0 +1,64 @@ +#ifndef Magnum_Shaders_TextShader_h +#define Magnum_Shaders_TextShader_h +/* + Copyright © 2010, 2011, 2012 Vladimír Vondruš + + This file is part of Magnum. + + Magnum is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 3 + only, as published by the Free Software Foundation. + + Magnum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License version 3 for more details. +*/ + +/** @file + * @brief Class Magnum::Shaders::TextShader + */ + +#include "Math/Matrix3.h" +#include "Math/Matrix4.h" +#include "AbstractTextShader.h" + +#include "magnumShadersVisibility.h" + +namespace Magnum { namespace Shaders { + +/** +@brief %Text shader + +@see TextShader2D, TextShader3D +*/ +template class MAGNUM_SHADERS_EXPORT TextShader: public AbstractTextShader { + public: + TextShader(); + + /** @brief Set transformation and projection matrix */ + inline TextShader* setTransformationProjectionMatrix(const typename DimensionTraits::MatrixType& matrix) { + AbstractTextShader::setUniform(transformationProjectionMatrixUniform, matrix); + return this; + } + + /** @brief Set text color */ + inline TextShader* setColor(const Color3<>& color) { + AbstractTextShader::setUniform(colorUniform, color); + return this; + } + + private: + GLint transformationProjectionMatrixUniform = 0, + colorUniform = 1; +}; + +/** @brief Two-dimensional text shader */ +typedef TextShader<2> TextShader2D; + +/** @brief Three-dimensional text shader */ +typedef TextShader<3> TextShader3D; + +}} + +#endif diff --git a/src/Shaders/TextShader2D.frag b/src/Shaders/TextShader2D.frag new file mode 100644 index 000000000..fdc02e682 --- /dev/null +++ b/src/Shaders/TextShader2D.frag @@ -0,0 +1,27 @@ +#ifndef NEW_GLSL +#define in varying +#define fragmentColor gl_FragColor +#endif + +#ifdef EXPLICIT_UNIFORM_LOCATION +layout(location = 1) uniform vec3 color; +#else +uniform lowp vec3 color; +#endif + +#ifdef EXPLICIT_TEXTURE_LAYER +layout(binding = 16) uniform sampler2D fontTexture; +#else +uniform lowp sampler2D fontTexture; +#endif + +in vec2 fragmentTextureCoordinates; + +#ifdef NEW_GLSL +out vec4 fragmentColor; +#endif + +void main() { + lowp float intensity = texture(fontTexture, fragmentTextureCoordinates).r; + fragmentColor = vec4(intensity*color, intensity); +} diff --git a/src/Shaders/TextShader2D.vert b/src/Shaders/TextShader2D.vert new file mode 100644 index 000000000..9d030d59d --- /dev/null +++ b/src/Shaders/TextShader2D.vert @@ -0,0 +1,25 @@ +#ifndef NEW_GLSL +#define in attribute +#define out varying +#endif + +#ifdef EXPLICIT_UNIFORM_LOCATION +layout(location = 0) uniform mat3 transformationProjectionMatrix; +#else +uniform highp mat3 transformationProjectionMatrix; +#endif + +#ifdef EXPLICIT_ATTRIB_LOCATION +layout(location = 0) in highp vec3 position; +layout(location = 1) in mediump vec2 textureCoordinates; +#else +in highp vec3 position; +in mediump vec2 textureCoordinates; +#endif + +out vec2 fragmentTextureCoordinates; + +void main() { + gl_Position = vec4(transformationProjectionMatrix*position, 0.0).xywz; + fragmentTextureCoordinates = textureCoordinates; +}