diff mbox

[Branch,~glmark2-dev/glmark2/trunk] Rev 172: SceneTexture: Add test for bilinear filtering implemented in the fragment shader.

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

Commit Message

alexandros.frantzis@linaro.org Nov. 30, 2011, 11:04 a.m. UTC
Merge authors:
  Alexandros Frantzis (afrantzis)
Related merge proposals:
  https://code.launchpad.net/~glmark2-dev/glmark2/bilinear-shader/+merge/83795
  proposed by: Alexandros Frantzis (afrantzis)
  review: Approve - Jesse Barker (jesse-barker)
------------------------------------------------------------
revno: 172 [merge]
committer: Alexandros Frantzis <alexandros.frantzis@linaro.org>
branch nick: trunk
timestamp: Wed 2011-11-30 13:02:09 +0200
message:
  SceneTexture: Add test for bilinear filtering implemented in the fragment shader.
added:
  data/shaders/light-basic-tex-bilinear.frag
modified:
  src/scene-texture.cpp
  src/shader-source.cpp
  src/shader-source.h


--
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

=== added file 'data/shaders/light-basic-tex-bilinear.frag'
--- data/shaders/light-basic-tex-bilinear.frag	1970-01-01 00:00:00 +0000
+++ data/shaders/light-basic-tex-bilinear.frag	2011-11-29 10:38:50 +0000
@@ -0,0 +1,31 @@ 
+uniform sampler2D MaterialTexture0;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+const vec2 TexelSize = vec2(1.0 / TextureSize.x, 1.0 / TextureSize.y); 
+
+/*
+ * See http://www.gamerendering.com/2008/10/05/bilinear-interpolation/
+ * for a more thorough explanation of how this works.
+ */
+vec4 texture2DBilinear(sampler2D sampler, vec2 uv)
+{
+    // Get the needed texture samples
+    vec4 tl = texture2D(sampler, uv);
+    vec4 tr = texture2D(sampler, uv + vec2(TexelSize.x, 0));
+    vec4 bl = texture2D(sampler, uv + vec2(0, TexelSize.y));
+    vec4 br = texture2D(sampler, uv + vec2(TexelSize.x , TexelSize.y));
+
+    // Mix the samples according to the GL specification
+    vec2 f = fract(uv * TextureSize);
+    vec4 tA = mix(tl, tr, f.x);
+    vec4 tB = mix(bl, br, f.x);
+    return mix(tA, tB, f.y);
+}
+
+void main(void)
+{
+    vec4 texel = texture2DBilinear(MaterialTexture0, TextureCoord);
+    gl_FragColor = texel * Color;
+}

=== modified file 'src/scene-texture.cpp'
--- src/scene-texture.cpp	2011-11-11 11:07:15 +0000
+++ src/scene-texture.cpp	2011-11-29 14:47:05 +0000
@@ -38,7 +38,7 @@ 
     Scene(pCanvas, "texture")
 {
     options_["texture-filter"] = Scene::Option("texture-filter", "nearest",
-                                               "[nearest, linear, mipmap]");
+                                               "[nearest, linear, linear-shader, mipmap]");
 }
 
 SceneTexture::~SceneTexture()
@@ -76,13 +76,48 @@ 
 {
     Scene::setup();
 
-    // Load shaders
     static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
     static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex.frag");
+    static const std::string frg_shader_bilinear_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex-bilinear.frag");
     static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
     static const LibMatrix::vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
+
+    // Create texture according to selected filtering
+    GLint min_filter = GL_NONE;
+    GLint mag_filter = GL_NONE;
+    const std::string &filter = options_["texture-filter"].value;
+
+    if (filter == "nearest") {
+        min_filter = GL_NEAREST;
+        mag_filter = GL_NEAREST;
+    }
+    else if (filter == "linear") {
+        min_filter = GL_LINEAR;
+        mag_filter = GL_LINEAR;
+    }
+    else if (filter == "linear-shader") {
+        min_filter = GL_NEAREST;
+        mag_filter = GL_NEAREST;
+    }
+    else if (filter == "mipmap") {
+        min_filter = GL_LINEAR_MIPMAP_LINEAR;
+        mag_filter = GL_LINEAR;
+    }
+
+    Texture::load(GLMARK_DATA_PATH"/textures/crate-base.png", &texture_,
+                  min_filter, mag_filter, 0);
+
+    // Load shaders
     ShaderSource vtx_source(vtx_shader_filename);
-    ShaderSource frg_source(frg_shader_filename);
+    ShaderSource frg_source;
+    if (filter == "linear-shader") {
+        frg_source.append_file(frg_shader_bilinear_filename);
+        LibMatrix::vec2 texture_size(512, 512);
+        frg_source.add_const("TextureSize", texture_size);
+    }
+    else {
+        frg_source.append_file(frg_shader_filename);
+    }
 
     // Add constants to shaders
     vtx_source.add_const("LightSourcePosition", lightPosition);
@@ -100,27 +135,6 @@ 
     attrib_locations.push_back(program_["texcoord"].location());
     mesh_.set_attrib_locations(attrib_locations);
 
-    // Create texture according to selected filtering
-    GLint min_filter = GL_NONE;
-    GLint mag_filter = GL_NONE;
-    const std::string &filter = options_["texture-filter"].value;
-
-    if (filter == "nearest") {
-        min_filter = GL_NEAREST;
-        mag_filter = GL_NEAREST;
-    }
-    else if (filter == "linear") {
-        min_filter = GL_LINEAR;
-        mag_filter = GL_LINEAR;
-    }
-    else if (filter == "mipmap") {
-        min_filter = GL_LINEAR_MIPMAP_LINEAR;
-        mag_filter = GL_LINEAR;
-    }
-
-    Texture::load(GLMARK_DATA_PATH"/textures/crate-base.png", &texture_,
-                  min_filter, mag_filter, 0);
-
     program_.start();
 
     currentFrame_ = 0;
@@ -190,7 +204,7 @@ 
 Scene::ValidationResult
 SceneTexture::validate()
 {
-    static const double radius_3d(std::sqrt(3.0));
+    static const double radius_3d(std::sqrt(3 * 2.0 * 2.0));
 
     if (rotation_.x() != 0 || rotation_.y() != 0 || rotation_.z() != 0)
         return Scene::ValidationUnknown;
@@ -206,6 +220,8 @@ 
         ref = Canvas::Pixel(0x3b, 0x3a, 0x39, 0xff);
     else if (filter == "linear")
         ref = Canvas::Pixel(0x36, 0x36, 0x34, 0xff);
+    else if (filter == "linear-shader")
+        ref = Canvas::Pixel(0x30, 0x30, 0x2f, 0xff);
     else if (filter == "mipmap")
         ref = Canvas::Pixel(0x35, 0x35, 0x34, 0xff);
     else

=== modified file 'src/shader-source.cpp'
--- src/shader-source.cpp	2011-10-26 11:12:19 +0000
+++ src/shader-source.cpp	2011-11-29 10:36:37 +0000
@@ -263,6 +263,25 @@ 
 }
 
 /**
+ * Adds a vec2 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ * @param function if not empty, the function to put the definition in
+ */
+void
+ShaderSource::add_const(const std::string &name, const LibMatrix::vec2 &v,
+                        const std::string &function)
+{
+    std::stringstream ss;
+
+    ss << "const vec2 " << name << " = vec2(" << std::fixed;
+    ss << v.x() << ", " << v.y() << ");" << std::endl;
+
+    add(ss.str(), function);
+}
+
+/**
  * Adds a vec3 constant definition.
  *
  * @param name the name of the constant

=== modified file 'src/shader-source.h'
--- src/shader-source.h	2011-10-26 11:12:19 +0000
+++ src/shader-source.h	2011-11-29 10:36:37 +0000
@@ -55,6 +55,8 @@ 
                    const std::string &function = "");
     void add_const(const std::string &name, std::vector<float> &f,
                    const std::string &function = "");
+    void add_const(const std::string &name, const LibMatrix::vec2 &v,
+                   const std::string &function = "");
     void add_const(const std::string &name, const LibMatrix::vec3 &v,
                    const std::string &function = "");
     void add_const(const std::string &name, const LibMatrix::vec4 &v,