diff mbox

[Branch,~glmark2-dev/glmark2/trunk] Rev 132: SceneShading: Merge multiple light support for phong shading.

Message ID 20110914084113.10119.60106.launchpad@ackee.canonical.com
State Accepted
Headers show

Commit Message

alexandros.frantzis@linaro.org Sept. 14, 2011, 8:41 a.m. UTC
Merge authors:
  Jesse Barker (jesse-barker)
Related merge proposals:
  https://code.launchpad.net/~jesse-barker/glmark2/multi-light-phong/+merge/73075
  proposed by: Jesse Barker (jesse-barker)
------------------------------------------------------------
revno: 132 [merge]
committer: Alexandros Frantzis <alexandros.frantzis@linaro.org>
branch nick: trunk
timestamp: Wed 2011-09-14 11:39:16 +0300
message:
  SceneShading: Merge multiple light support for phong shading.
modified:
  data/shaders/light-phong.frag
  src/scene-shading.cpp


--
lp:glmark2
https://code.launchpad.net/~glmark2-dev/glmark2/trunk

You are subscribed to branch lp:glmark2.
To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription
diff mbox

Patch

=== modified file 'data/shaders/light-phong.frag'
--- data/shaders/light-phong.frag	2011-07-27 15:02:27 +0000
+++ data/shaders/light-phong.frag	2011-09-13 16:08:19 +0000
@@ -5,17 +5,16 @@ 
 varying vec3 vertex_normal;
 varying vec4 vertex_position;
 
-void main(void)
+vec4
+compute_color(vec4 light_position, vec4 diffuse_light_color)
 {
     const vec4 lightAmbient = vec4(0.1, 0.1, 0.1, 1.0);
-    const vec4 lightDiffuse = vec4(0.8, 0.8, 0.8, 1.0);
     const vec4 lightSpecular = vec4(0.8, 0.8, 0.8, 1.0);
-    const vec4 matAmbient = vec4(1.0, 1.0, 1.0, 1.0);
-    const vec4 matDiffuse = vec4(0.0, 0.0, 1.0, 1.0);
+    const vec4 matAmbient = vec4(0.2, 0.2, 0.2, 1.0);
     const vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
     const float matShininess = 100.0;
     vec3 eye_direction = normalize(-vertex_position.xyz);
-    vec3 light_direction = normalize(LightSourcePosition.xyz/LightSourcePosition.w -
+    vec3 light_direction = normalize(light_position.xyz/light_position.w -
                                      vertex_position.xyz/vertex_position.w);
     vec3 normalized_normal = normalize(vertex_normal);
     vec3 reflection = reflect(-light_direction, normalized_normal);
@@ -23,6 +22,12 @@ 
     float diffuseTerm = max(0.0, dot(normalized_normal, light_direction));
     vec4 specular = (lightSpecular * matSpecular);
     vec4 ambient = (lightAmbient * matAmbient);
-    vec4 diffuse = (lightDiffuse * matDiffuse);
-    gl_FragColor = (specular * specularTerm) + ambient + (diffuse * diffuseTerm);
+    vec4 diffuse = (diffuse_light_color * MaterialDiffuse);
+    vec4 result = (specular * specularTerm) + ambient + (diffuse * diffuseTerm);
+    return result;
+}
+
+void main(void)
+{
+$DO_LIGHTS$
 }

=== modified file 'src/scene-shading.cpp'
--- src/scene-shading.cpp	2011-08-31 21:22:27 +0000
+++ src/scene-shading.cpp	2011-09-14 08:39:16 +0000
@@ -29,12 +29,36 @@ 
 #include "shader-source.h"
 
 #include <cmath>
+#include <sstream>
+
+using std::string;
+using std::endl;
+
+template<typename T> T
+fromString(const string& asString)
+{
+    std::stringstream ss(asString);
+    T retVal;
+    ss >> retVal;
+    return retVal;
+}
+
+template<typename T>
+string
+toString(const T t)
+{
+    std::stringstream ss;
+    ss << t;
+    return ss.str();
+}
 
 SceneShading::SceneShading(Canvas &pCanvas) :
     Scene(pCanvas, "shading")
 {
     mOptions["shading"] = Scene::Option("shading", "gouraud",
                                         "[gouraud, blinn-phong-inf, phong]");
+    mOptions["num-lights"] = Scene::Option("num-lights", "1",
+            "The number of lights applied to the scene (phong only)");
 }
 
 SceneShading::~SceneShading()
@@ -71,6 +95,52 @@ 
     mMesh.reset();
 }
 
+static string
+get_fragment_shader_source(const string& frg_file, unsigned int lights)
+{
+    ShaderSource source(frg_file);
+
+    static const string lightPositionName("LightSourcePosition");
+    static const string lightColorName("LightColor");
+    static const string callCompute("    gl_FragColor += compute_color(");
+    static const string commaString(", ");
+    static const string rParenString(");");
+    std::stringstream doLightSS;
+    doLightSS << string("    gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);");
+    doLightSS << endl;
+    float theta(2.0 * M_PI / lights);
+    float phi(theta / 2.0);
+    float intensity(0.8 / lights);
+    LibMatrix::vec4 lightCol(intensity, intensity, intensity, 1.0);
+    for (unsigned int l = 0; l < lights; l++)
+    {
+        // Construct constant names for the light position and color and add it
+        // to the list of constants for the shader.
+        string indexString(toString(l));
+        string curLightPosition(lightPositionName + indexString);
+        string curLightColor(lightColorName + indexString);
+        float sin_theta(sin(theta * l));
+        float cos_theta(cos(theta * l));
+        float sin_phi(sin(phi * l));
+        float cos_phi(cos(phi * l));
+        LibMatrix::vec4 lightPos(cos_phi * sin_theta, cos_phi * cos_theta, sin_phi, 1.0);
+        source.add_const(curLightPosition, lightPos);
+        source.add_const(curLightColor, lightCol);
+
+        // Add the section of source to the substantive...
+        doLightSS << callCompute;
+        doLightSS << curLightPosition;
+        doLightSS << commaString;
+        doLightSS << curLightColor;
+        doLightSS << rParenString;
+        doLightSS << endl;
+    }
+
+    source.replace("$DO_LIGHTS$", doLightSS.str());
+
+    return source.str();
+}
+
 void SceneShading::setup()
 {
     Scene::setup();
@@ -84,34 +154,38 @@ 
     halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
     halfVector.normalize();
 
+    // Load and add constants to shaders
     std::string vtx_shader_filename;
     std::string frg_shader_filename;
     const std::string &shading = mOptions["shading"].value;
-
+    ShaderSource vtx_source;
+    ShaderSource frg_source;
     if (shading == "gouraud") {
         vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.vert";
         frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.frag";
+        frg_source.append_file(frg_shader_filename);
+        vtx_source.append_file(vtx_shader_filename);
+        vtx_source.add_const("LightSourcePosition", lightPosition);
+        vtx_source.add_const("MaterialDiffuse", materialDiffuse);
     }
     else if (shading == "blinn-phong-inf") {
         vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.vert";
         frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-advanced.frag";
+        frg_source.append_file(frg_shader_filename);
+        frg_source.add_const("LightSourcePosition", lightPosition);
+        frg_source.add_const("LightSourceHalfVector", halfVector);
+        vtx_source.append_file(vtx_shader_filename);
     }
     else if (shading == "phong") {
         vtx_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.vert";
         frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.frag";
+        unsigned int num_lights = fromString<unsigned int>(mOptions["num-lights"].value);
+        string fragsource = get_fragment_shader_source(frg_shader_filename, num_lights);
+        frg_source.append(fragsource);
+        frg_source.add_const("MaterialDiffuse", materialDiffuse);
+        vtx_source.append_file(vtx_shader_filename);
     }
 
-    // Load shaders
-    ShaderSource vtx_source(vtx_shader_filename);
-    ShaderSource frg_source(frg_shader_filename);
-
-    // Add constants to shaders
-    vtx_source.add_const("LightSourcePosition", lightPosition);
-    vtx_source.add_const("MaterialDiffuse", materialDiffuse);
-
-    frg_source.add_const("LightSourcePosition", lightPosition);
-    frg_source.add_const("LightSourceHalfVector", halfVector);
-
     if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
                                           frg_source.str()))
     {