=== added file 'data/shaders/light-basic-tex-bilinear.frag'
@@ -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'
@@ -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'
@@ -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'
@@ -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,