From 4152e1fc9d1acc7859dc307d158ed68d4e4858dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 10 Sep 2012 02:37:07 +0200 Subject: [PATCH] Better ability to create portable shaders. Now the #version string is added from Shader class itself, making it possible to do workarounds for older versions more conveniently. As a consequence, #version must not be part of shader source anymore. --- src/AbstractShaderProgram.h | 4 ++-- src/Shader.cpp | 23 +++++++++++++++++++++++ src/Shader.h | 27 +++++++++++++++------------ src/Shaders/PhongShader.cpp | 4 ++-- src/Shaders/PhongShader.frag | 2 -- src/Shaders/PhongShader.vert | 2 -- 6 files changed, 42 insertions(+), 20 deletions(-) diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 831f6593b..8078c9e6f 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -66,8 +66,8 @@ static const GLint SpecularTextureUniform = 3; @code MyShader() { // Load shaders from file and attach them to the program - attachShader(Shader::fromFile(Shader::Type::Vertex, "PhongShader.vert")); - attachShader(Shader::fromFile(Shader::Type::Fragment, "PhongShader.frag")); + attachShader(Shader::fromFile(Version::430, Shader::Type::Vertex, "PhongShader.vert")); + attachShader(Shader::fromFile(Version::430, Shader::Type::Fragment, "PhongShader.frag")); // Link link(); diff --git a/src/Shader.cpp b/src/Shader.cpp index 2a6fe17f5..ea4004814 100644 --- a/src/Shader.cpp +++ b/src/Shader.cpp @@ -29,6 +29,29 @@ using namespace std; namespace Magnum { +Shader::Shader(Version version, Type type): _type(type), _state(State::Initialized), shader(0) { + shader = glCreateShader(static_cast(_type)); + + switch(version) { + #ifndef MAGNUM_TARGET_GLES + case Version::GL210: addSource("#version 120\n"); break; + case Version::GL300: addSource("#version 130\n"); break; + case Version::GL310: addSource("#version 140\n"); break; + case Version::GL320: addSource("#version 150\n"); break; + case Version::GL330: addSource("#version 330\n"); break; + case Version::GL400: addSource("#version 400\n"); break; + case Version::GL410: addSource("#version 410\n"); break; + case Version::GL420: addSource("#version 420\n"); break; + case Version::GL430: addSource("#version 430\n"); break; + #else + case Version::GLES200: addSource("#version 100\n"); break; + case Version::GLES300: addSource("#version 300\n"); break; + #endif + + default: break; + } +} + Shader::Shader(Shader&& other): _type(other._type), _state(other._state), sources(other.sources), shader(other.shader) { other.shader = 0; } diff --git a/src/Shader.h b/src/Shader.h index f25a50e19..7da337718 100644 --- a/src/Shader.h +++ b/src/Shader.h @@ -23,6 +23,7 @@ #include #include "Magnum.h" +#include "Context.h" #include "magnumVisibility.h" @@ -86,54 +87,56 @@ class MAGNUM_EXPORT Shader { /** * @brief Load shader from source + * @param version Target version * @param type %Shader type * @param source %Shader source * @return Shader instance * * Loads the shader from one source. Shorthand for * @code - * Shader s(type); + * Shader s(version, type); * s.addData(data); * @endcode * Note that it is also possible to create shader from more than one * source. */ - inline static Shader fromData(Type type, const std::string& source) { - Shader s(type); + inline static Shader fromData(Version version, Type type, const std::string& source) { + Shader s(version, type); s.addSource(source); return s; } /** * @brief Load shader from file + * @param version Target version * @param type %Shader type - * @param filename %Source filename + * @param filename Source filename * @return Shader instance * * Loads the shader from from one file. Shorthand for * @code - * Shader s(type); + * Shader s(version, type); * s.addFile(filename); * @endcode * Note that it is also possible to create shader from more than one * source. */ - inline static Shader fromFile(Type type, const char* filename) { - Shader s(type); + inline static Shader fromFile(Version version, Type type, const char* filename) { + Shader s(version, type); s.addFile(filename); return s; } /** * @brief Constructor + * @param version Target version + * @param type %Shader type * - * Creates empty OpenGL shader. Sources can be added with addSource() - * or addFile(). + * Creates empty OpenGL shader and adds @c \#version directive at the + * beginning. Sources can be added with addSource() or addFile(). * @see fromData(), fromFile(), @fn_gl{CreateShader} */ - inline Shader(Type type): _type(type), _state(State::Initialized), shader(0) { - shader = glCreateShader(static_cast(_type)); - } + Shader(Version version, Type type); /** * @brief Destructor diff --git a/src/Shaders/PhongShader.cpp b/src/Shaders/PhongShader.cpp index bf2ce456e..382648f2c 100644 --- a/src/Shaders/PhongShader.cpp +++ b/src/Shaders/PhongShader.cpp @@ -23,8 +23,8 @@ namespace Magnum { namespace Shaders { PhongShader::PhongShader() { Corrade::Utility::Resource rs("MagnumShaders"); - attachShader(Shader::fromData(Shader::Type::Vertex, rs.get("PhongShader.vert"))); - attachShader(Shader::fromData(Shader::Type::Fragment, rs.get("PhongShader.frag"))); + attachShader(Shader::fromData(Version::GL330, Shader::Type::Vertex, rs.get("PhongShader.vert"))); + attachShader(Shader::fromData(Version::GL330, Shader::Type::Fragment, rs.get("PhongShader.frag"))); link(); diff --git a/src/Shaders/PhongShader.frag b/src/Shaders/PhongShader.frag index 230af1736..16a100336 100644 --- a/src/Shaders/PhongShader.frag +++ b/src/Shaders/PhongShader.frag @@ -1,5 +1,3 @@ -#version 330 - uniform vec3 ambientColor = vec3(0.0, 0.0, 0.0); uniform vec3 diffuseColor; uniform vec3 specularColor = vec3(1.0, 1.0, 1.0); diff --git a/src/Shaders/PhongShader.vert b/src/Shaders/PhongShader.vert index 19755516a..228cbad97 100644 --- a/src/Shaders/PhongShader.vert +++ b/src/Shaders/PhongShader.vert @@ -1,5 +1,3 @@ -#version 330 - uniform mat4 transformationMatrix; uniform mat4 projectionMatrix; uniform vec3 light;