From 5818a76850183f5e1840210f6f6e8f4821e7cd23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 14 Feb 2012 00:27:35 +0100 Subject: [PATCH] New library with sample shaders, currently only Phong shader. --- CMakeLists.txt | 1 + modules/FindMagnum.cmake | 4 +- src/CMakeLists.txt | 1 + src/Shaders/CMakeLists.txt | 12 ++++ src/Shaders/PhongShader.cpp | 50 +++++++++++++++++ src/Shaders/PhongShader.frag | 34 ++++++++++++ src/Shaders/PhongShader.h | 103 +++++++++++++++++++++++++++++++++++ src/Shaders/PhongShader.vert | 26 +++++++++ 8 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 src/Shaders/CMakeLists.txt create mode 100644 src/Shaders/PhongShader.cpp create mode 100644 src/Shaders/PhongShader.frag create mode 100644 src/Shaders/PhongShader.h create mode 100644 src/Shaders/PhongShader.vert diff --git a/CMakeLists.txt b/CMakeLists.txt index dbe5ce867..92d417876 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ set_parent_scope(MAGNUM_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") set_parent_scope(MAGNUM_LIBRARY Magnum) set_parent_scope(MAGNUM_PRIMITIVES_LIBRARY MagnumPrimitives) set_parent_scope(MAGNUM_MESHTOOLS_LIBRARY MagnumMeshTools) +set_parent_scope(MAGNUM_SHADERS_LIBRARY MagnumShaders) include(FindMagnum) add_subdirectory(modules) diff --git a/modules/FindMagnum.cmake b/modules/FindMagnum.cmake index 046a3e4e7..48fd4faf1 100644 --- a/modules/FindMagnum.cmake +++ b/modules/FindMagnum.cmake @@ -16,7 +16,7 @@ find_package(Corrade REQUIRED) find_package(OpenGL REQUIRED) find_package(GLEW REQUIRED) -if (MAGNUM_INCLUDE_DIR AND MAGNUM_LIBRARY AND MAGNUM_PRIMITIVES_LIBRARY AND MAGNUM_MESHTOOLS_LIBRARY) +if (MAGNUM_INCLUDE_DIR AND MAGNUM_LIBRARY AND MAGNUM_PRIMITIVES_LIBRARY AND MAGNUM_MESHTOOLS_LIBRARY AND MAGNUM_SHADERS_LIBRARY) # Already in cache set(MAGNUM_FOUND TRUE) @@ -26,6 +26,7 @@ else() find_library(MAGNUM_LIBRARY Magnum) find_library(MAGNUM_PRIMITIVES_LIBRARY MagnumPrimitives) find_library(MAGNUM_MESHTOOLS_LIBRARY MagnumMeshTools) + find_library(MAGNUM_SHADERS_LIBRARY MagnumShaders) # Paths find_path(MAGNUM_INCLUDE_DIR @@ -39,6 +40,7 @@ else() MAGNUM_LIBRARY MAGNUM_PRIMITIVES_LIBRARY MAGNUM_MESHTOOLS_LIBRARY + MAGNUM_SHADERS_LIBRARY ) endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 76ef23daa..898e3300e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,6 +5,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CORRADE_INCLUDE_DIR}) add_subdirectory(Math) add_subdirectory(MeshTools) add_subdirectory(Primitives) +add_subdirectory(Shaders) set(Magnum_SRCS Object.cpp diff --git a/src/Shaders/CMakeLists.txt b/src/Shaders/CMakeLists.txt new file mode 100644 index 000000000..62764eb56 --- /dev/null +++ b/src/Shaders/CMakeLists.txt @@ -0,0 +1,12 @@ +find_package(Qt4 REQUIRED) + +corrade_add_resource(Shaders shaders PhongShader.frag PhongShader.vert) +set(Shaders_SRCS + PhongShader.cpp + ${Shaders} +) + +add_library(MagnumShaders SHARED ${Shaders_SRCS}) +target_link_libraries(MagnumShaders ${MAGNUM_LIBRARY}) + +install(TARGETS MagnumShaders DESTINATION ${MAGNUM_LIBRARY_INSTALL_DIR}) diff --git a/src/Shaders/PhongShader.cpp b/src/Shaders/PhongShader.cpp new file mode 100644 index 000000000..ebec7e61d --- /dev/null +++ b/src/Shaders/PhongShader.cpp @@ -0,0 +1,50 @@ +/* + 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 "PhongShader.h" + +#include "Utility/Resource.h" + +using namespace Corrade::Utility; + +namespace Magnum { namespace Shaders { + +PhongShader::PhongShader() { + Resource rs("shaders"); + Shader* vertexShader = Shader::fromData(Shader::Vertex, rs.get("PhongShader.vert")); + Shader* fragmentShader = Shader::fromData(Shader::Fragment, rs.get("PhongShader.frag")); + attachShader(vertexShader); + attachShader(fragmentShader); + + bindAttribute(Vertex, "vertex"); + bindAttribute(Normal, "normal"); + + link(); + delete vertexShader; + delete fragmentShader; + + ambientColorUniform = uniformLocation("ambientColor"); + diffuseColorUniform = uniformLocation("diffuseColor"); + specularColorUniform = uniformLocation("specularColor"); + shininessUniform = uniformLocation("shininess"); + transformationMatrixUniform = uniformLocation("transformationMatrix"); + projectionMatrixUniform = uniformLocation("projectionMatrix"); + lightUniform = uniformLocation("light"); + lightAmbientColorUniform = uniformLocation("lightAmbientColor"); + lightDiffuseColorUniform = uniformLocation("lightDiffuseColor"); + lightSpecularColorUniform = uniformLocation("lightSpecularColor"); +} + +}} diff --git a/src/Shaders/PhongShader.frag b/src/Shaders/PhongShader.frag new file mode 100644 index 000000000..f34a95cf3 --- /dev/null +++ b/src/Shaders/PhongShader.frag @@ -0,0 +1,34 @@ +#version 330 + +uniform vec3 ambientColor; +uniform vec3 diffuseColor; +uniform vec3 specularColor; +uniform float shininess; + +uniform vec3 lightAmbientColor; +uniform vec3 lightDiffuseColor; +uniform vec3 lightSpecularColor; + +in vec3 transformedNormal; +in vec3 lightDirection; + +out vec4 color; + +void main() { + /* Ambient color */ + color.rgb = ambientColor*lightAmbientColor; + + /* Add diffuse color */ + float intensity = max(0.0, dot(transformedNormal, lightDirection)); + color.rgb += diffuseColor*lightDiffuseColor*intensity; + + /* Add specular color, if needed */ + if(intensity != 0) { + vec3 reflection = reflect(-lightDirection, transformedNormal); + float specularity = pow(max(0.0, dot(transformedNormal, reflection)), shininess); + color.rgb += specularColor*lightSpecularColor*specularity; + } + + /* Force alpha to 1 */ + color.a = 1.0; +} diff --git a/src/Shaders/PhongShader.h b/src/Shaders/PhongShader.h new file mode 100644 index 000000000..5fa9a8198 --- /dev/null +++ b/src/Shaders/PhongShader.h @@ -0,0 +1,103 @@ +#ifndef Magnum_Shaders_PhongShader_h +#define Magnum_Shaders_PhongShader_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::PhongShader + */ + +#include "AbstractShaderProgram.h" + +namespace Magnum { namespace Shaders { + +/** @brief Phong shader */ +class PhongShader: public AbstractShaderProgram { + public: + /** @brief Attribute */ + enum Attribute { + Vertex = 1, /**< @brief Vertex position (four-component vector) */ + Normal = 2 /**< @brief Normal direction (three-component vector) */ + }; + + /** @brief Constructor */ + PhongShader(); + + /** @brief Object ambient color */ + inline void setAmbientColorUniform(const Vector3& color) { + setUniform(ambientColorUniform, color); + } + + /** @brief Object diffuse color */ + inline void setDiffuseColorUniform(const Vector3& color) { + setUniform(diffuseColorUniform, color); + } + + /** @brief Object specular color */ + inline void setSpecularColorUniform(const Vector3& color) { + setUniform(specularColorUniform, color); + } + + /** @brief Object shininess */ + inline void setShininessUniform(GLfloat shininess) { + setUniform(shininessUniform, shininess); + } + + /** @brief Transformation matrix */ + inline void setTransformationMatrixUniform(const Matrix4& matrix) { + setUniform(transformationMatrixUniform, matrix); + } + + /** @brief Projection matrix */ + inline void setProjectionMatrixUniform(const Matrix4& matrix) { + setUniform(projectionMatrixUniform, matrix); + } + + /** @brief Light position */ + inline void setLightUniform(const Vector3& light) { + setUniform(lightUniform, light); + } + + /** @brief Light ambient color */ + inline void setLightAmbientColorUniform(const Vector3& color) { + setUniform(lightAmbientColorUniform, color); + } + + /** @brief Light diffuse color */ + inline void setLightDiffuseColorUniform(const Vector3& color) { + setUniform(lightDiffuseColorUniform, color); + } + + /** @brief Light specular color */ + inline void setLightSpecularColorUniform(const Vector3& color) { + setUniform(lightSpecularColorUniform, color); + } + + private: + GLint ambientColorUniform, + diffuseColorUniform, + specularColorUniform, + shininessUniform, + transformationMatrixUniform, + projectionMatrixUniform, + lightUniform, + lightAmbientColorUniform, + lightDiffuseColorUniform, + lightSpecularColorUniform; +}; + +}} + +#endif diff --git a/src/Shaders/PhongShader.vert b/src/Shaders/PhongShader.vert new file mode 100644 index 000000000..d02bd08fc --- /dev/null +++ b/src/Shaders/PhongShader.vert @@ -0,0 +1,26 @@ +#version 330 + +uniform mat4 transformationMatrix; +uniform mat4 projectionMatrix; +uniform vec3 light; + +in vec4 vertex; +in vec4 normal; + +out vec3 transformedNormal; +out vec3 lightDirection; + +void main() { + /* Transformed vertex position */ + vec4 transformedVertex4 = transformationMatrix*vertex; + vec3 transformedVertex = transformedVertex4.xyz/transformedVertex4.w; + + /* Transformed normal vector */ + transformedNormal = normalize(mat3x3(transformationMatrix)*normal.xyz); + + /* Direction to the light */ + lightDirection = normalize(light.xyz - transformedVertex); + + /* Transform the vertex */ + gl_Position = projectionMatrix*transformationMatrix*vertex; +}