=== modified file 'android/jni/Android.mk'
@@ -61,11 +61,13 @@
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src \
$(LOCAL_PATH)/src/libmatrix \
$(LOCAL_PATH)/src/scene-ideas \
+ $(LOCAL_PATH)/src/scene-terrain \
$(LOCAL_PATH)/src/libjpeg-turbo \
$(LOCAL_PATH)/src/libpng \
external/zlib
LOCAL_SRC_FILES := $(filter-out src/canvas% src/main.cpp, \
$(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/*.cpp))) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/scene-terrain/*.cpp)) \
src/canvas-android.cpp
LOCAL_PRELINK_MODULE := false
=== modified file 'android/jni/Android.ndk.mk'
@@ -54,10 +54,12 @@
LOCAL_C_INCLUDES := $(LOCAL_PATH)/src \
$(LOCAL_PATH)/src/libmatrix \
$(LOCAL_PATH)/src/scene-ideas \
+ $(LOCAL_PATH)/src/scene-terrain \
$(LOCAL_PATH)/src/libjpeg-turbo \
$(LOCAL_PATH)/src/libpng
LOCAL_SRC_FILES := $(filter-out src/canvas% src/main.cpp, \
$(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/*.cpp))) \
+ $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/scene-terrain/*.cpp)) \
src/canvas-android.cpp
include $(BUILD_SHARED_LIBRARY)
=== added file 'data/shaders/terrain-blur.frag'
@@ -0,0 +1,14 @@
+uniform sampler2D Texture0;
+
+varying vec2 vUv;
+
+void main(void)
+{
+ vec4 result;
+ vec2 TextureCoord = vUv;
+
+ $CONVOLUTION$
+
+ gl_FragColor = vec4(result.xyz, 1.0);
+}
+
=== added file 'data/shaders/terrain-luminance.frag'
@@ -0,0 +1,15 @@
+uniform sampler2D tDiffuse;
+
+varying vec2 vUv;
+
+void main()
+{
+ vec4 texel = texture2D( tDiffuse, vUv );
+
+ vec3 luma = vec3( 0.299, 0.587, 0.114 );
+
+ float v = dot( texel.xyz, luma );
+
+ gl_FragColor = vec4( v, v, v, texel.w );
+}
+
=== added file 'data/shaders/terrain-noise.frag'
@@ -0,0 +1,124 @@
+//
+// Description : Array and textureless GLSL 3D simplex noise function.
+// Author : Ian McEwan, Ashima Arts.
+// Maintainer : ijm
+// Lastmod : 20110409 (stegu)
+// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
+// Distributed under the MIT License. See LICENSE file.
+//
+
+#ifdef GL_ES
+#define MEDIUMP mediump
+#else
+#define MEDIUMP
+#endif
+
+uniform float time;
+uniform MEDIUMP vec2 uvScale;
+varying vec2 vUv;
+
+vec4 permute(vec4 x)
+{
+ return mod(((x * 34.0) + 1.0) * x, 289.0);
+}
+
+vec4 taylorInvSqrt(vec4 r)
+{
+ return 1.79284291400159 - 0.85373472095314 * r;
+}
+
+float snoise(vec3 v)
+{
+ const vec2 C = vec2(1.0 / 6.0, 1.0 / 3.0);
+ const vec4 D = vec4(0.0, 0.5, 1.0, 2.0);
+
+ // First corner
+ vec3 i = floor(v + dot(v, C.yyy));
+ vec3 x0 = v - i + dot(i, C.xxx);
+
+ // Other corners
+ vec3 g = step(x0.yzx, x0.xyz);
+ vec3 l = 1.0 - g;
+ vec3 i1 = min(g.xyz, l.zxy);
+ vec3 i2 = max(g.xyz, l.zxy);
+
+ vec3 x1 = x0 - i1 + 1.0 * C.xxx;
+ vec3 x2 = x0 - i2 + 2.0 * C.xxx;
+ vec3 x3 = x0 - 1. + 3.0 * C.xxx;
+
+ // Permutations
+ i = mod(i, 289.0);
+ vec4 p = permute(permute(permute(
+ i.z + vec4(0.0, i1.z, i2.z, 1.0))
+ + i.y + vec4(0.0, i1.y, i2.y, 1.0))
+ + i.x + vec4(0.0, i1.x, i2.x, 1.0));
+
+ // Gradients
+ // (N*N points uniformly over a square, mapped onto an octahedron.)
+
+ float n_ = 1.0 / 7.0; // N=7
+
+ vec3 ns = n_ * D.wyz - D.xzx;
+
+ vec4 j = p - 49.0 * floor(p * ns.z *ns.z); // mod(p,N*N)
+
+ vec4 x_ = floor(j * ns.z);
+ vec4 y_ = floor(j - 7.0 * x_); // mod(j,N)
+
+ vec4 x = x_ *ns.x + ns.yyyy;
+ vec4 y = y_ *ns.x + ns.yyyy;
+ vec4 h = 1.0 - abs(x) - abs(y);
+
+ vec4 b0 = vec4(x.xy, y.xy);
+ vec4 b1 = vec4(x.zw, y.zw);
+
+
+ vec4 s0 = floor(b0) * 2.0 + 1.0;
+ vec4 s1 = floor(b1) * 2.0 + 1.0;
+ vec4 sh = -step(h, vec4(0.0));
+
+ vec4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
+ vec4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
+
+ vec3 p0 = vec3(a0.xy, h.x);
+ vec3 p1 = vec3(a0.zw, h.y);
+ vec3 p2 = vec3(a1.xy, h.z);
+ vec3 p3 = vec3(a1.zw, h.w);
+
+ // Normalise gradients
+
+ vec4 norm = taylorInvSqrt(vec4(dot(p0, p0), dot(p1, p1), dot(p2, p2), dot(p3, p3)));
+ p0 *= norm.x;
+ p1 *= norm.y;
+ p2 *= norm.z;
+ p3 *= norm.w;
+
+ // Mix final noise value
+
+ vec4 m = max(0.6 - vec4(dot(x0, x0), dot(x1, x1), dot(x2, x2), dot(x3, x3)), 0.0);
+ m = m * m;
+ return 42.0 * dot(m*m, vec4(dot(p0, x0), dot(p1, x1),
+ dot(p2, x2), dot(p3, x3)));
+}
+
+float surface3(vec3 coord)
+{
+ float n = 0.0;
+
+ n += 1.0 * abs(snoise(coord));
+ n += 0.5 * abs(snoise(coord * 2.0));
+ n += 0.25 * abs(snoise(coord * 4.0));
+ n += 0.125 * abs(snoise(coord * 8.0));
+
+ return n;
+}
+
+void main(void)
+{
+ vec3 coord = vec3(vUv.x, uvScale.y - vUv.y, -time);
+ float n = surface3(coord);
+
+ gl_FragColor = vec4(vec3(n, n, n), 1.0);
+}
+
+
=== added file 'data/shaders/terrain-normalmap.frag'
@@ -0,0 +1,15 @@
+uniform float height;
+uniform vec2 resolution;
+uniform sampler2D heightMap;
+
+varying vec2 vUv;
+
+void main()
+{
+ float val = texture2D( heightMap, vUv ).x;
+
+ float valU = texture2D( heightMap, vUv + vec2( 1.0 / resolution.x, 0.0 ) ).x;
+ float valV = texture2D( heightMap, vUv + vec2( 0.0, 1.0 / resolution.y ) ).x;
+
+ gl_FragColor = vec4( ( 0.5 * normalize( vec3( val - valU, val - valV, height ) ) + 0.5 ), 1.0 );
+}
=== added file 'data/shaders/terrain-overlay.frag'
@@ -0,0 +1,10 @@
+uniform float opacity;
+uniform sampler2D tDiffuse;
+
+varying vec2 vUv;
+
+void main()
+{
+ vec4 texel = texture2D(tDiffuse, vUv);
+ gl_FragColor = opacity * texel;
+}
=== added file 'data/shaders/terrain-texture.vert'
@@ -0,0 +1,18 @@
+#ifdef GL_ES
+#define MEDIUMP mediump
+#else
+#define MEDIUMP
+#endif
+
+uniform vec2 uvOffset;
+uniform MEDIUMP vec2 uvScale;
+
+attribute vec3 position;
+
+varying vec2 vUv;
+
+void main()
+{
+ vUv = uvScale * (position.xy * 0.5 + 0.5) + uvOffset;
+ gl_Position = vec4( position, 1.0);
+}
=== added file 'data/shaders/terrain.frag'
@@ -0,0 +1,112 @@
+uniform vec3 uAmbientColor;
+uniform vec3 uDiffuseColor;
+uniform vec3 uSpecularColor;
+uniform float uShininess;
+uniform float uOpacity;
+uniform bool enableDiffuse1;
+uniform bool enableDiffuse2;
+uniform bool enableSpecular;
+uniform sampler2D tDiffuse1;
+uniform sampler2D tDiffuse2;
+uniform sampler2D tDetail;
+uniform sampler2D tNormal;
+uniform sampler2D tSpecular;
+uniform sampler2D tDisplacement;
+uniform float uNormalScale;
+uniform vec2 uRepeatOverlay;
+uniform vec2 uOffset;
+varying vec3 vTangent;
+varying vec3 vBinormal;
+varying vec3 vNormal;
+varying vec2 vUv;
+uniform vec3 ambientLightColor;
+uniform mat4 viewMatrix;
+
+#define MAX_POINT_LIGHTS 1
+//#define USE_FOG
+//#define FOG_EXP2
+
+#if MAX_POINT_LIGHTS > 0
+uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];
+uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];
+uniform float pointLightDistance[ MAX_POINT_LIGHTS ];
+#endif
+
+varying vec3 vViewPosition;
+
+// CHUNK: fog_pars_fragment
+#ifdef USE_FOG
+uniform vec3 fogColor;
+#ifdef FOG_EXP2
+uniform float fogDensity;
+#else
+uniform float fogNear;
+uniform float fogFar;
+#endif
+#endif
+
+void main() {
+ gl_FragColor = vec4( vec3( 1.0 ), uOpacity );
+ vec3 specularTex = vec3( 1.0 );
+ vec2 uvOverlay = uRepeatOverlay * vUv + uOffset;
+ vec3 normalTex = texture2D( tDetail, uvOverlay ).xyz * 2.0 - 1.0;
+ normalTex.xy *= uNormalScale;
+ normalTex = normalize( normalTex );
+
+ vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );
+ vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );
+ gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, vUv) );
+
+ specularTex = texture2D( tSpecular, uvOverlay ).xyz;
+
+ mat3 tbn= mat3( vTangent, vBinormal, vNormal );
+ vec3 finalNormal = tbn * normalTex;
+ vec3 normal = normalize( finalNormal );
+ vec3 viewPosition = normalize( vViewPosition );
+
+ // point lights
+#if MAX_POINT_LIGHTS > 0
+ vec3 pointDiffuse = vec3( 0.0 );
+ vec3 pointSpecular = vec3( 0.0 );
+ for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {
+ vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );
+ vec3 lVector = lPosition.xyz + vViewPosition.xyz;
+ float lDistance = 1.0;
+ if ( pointLightDistance[ i ] > 0.0 )
+ lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );
+ lVector = normalize( lVector );
+ vec3 pointHalfVector = normalize( lVector + viewPosition );
+ float pointDistance = lDistance;
+ float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );
+ float pointDiffuseWeight = max( dot( normal, lVector ), 0.0 );
+ float pointSpecularWeight = specularTex.r * pow( pointDotNormalHalf, uShininess );
+ pointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;
+ pointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;
+ }
+#endif
+
+ // all lights contribution summation
+ vec3 totalDiffuse = vec3( 0.0 );
+ vec3 totalSpecular = vec3( 0.0 );
+
+
+#if MAX_POINT_LIGHTS > 0
+ totalDiffuse += pointDiffuse;
+ totalSpecular += pointSpecular;
+#endif
+
+ gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );
+
+ //CHUNK: fog_fragment
+#ifdef USE_FOG
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+#ifdef FOG_EXP2
+ const float LOG2 = 1.442695;
+ float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );
+ fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );
+#else
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+#endif
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+#endif
+}
=== added file 'data/shaders/terrain.vert'
@@ -0,0 +1,48 @@
+// Transformation matrices
+uniform mat4 modelViewMatrix;
+uniform mat4 normalMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+
+// Vertex attributes
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 tangent;
+attribute vec2 uv;
+
+// Uniforms
+uniform sampler2D tNormal;
+uniform sampler2D tDisplacement;
+uniform float uDisplacementScale;
+uniform float uDisplacementBias;
+
+// Varyings
+varying vec3 vTangent;
+varying vec3 vBinormal;
+varying vec3 vNormal;
+varying vec2 vUv;
+varying vec3 vViewPosition;
+
+void main()
+{
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ vViewPosition = -mvPosition.xyz;
+ vNormal = normalize(vec3(normalMatrix * vec4(normal, 1.0)));
+
+ // tangent and binormal vectors
+ vTangent = normalize(vec3(normalMatrix * vec4(tangent, 1.0)));
+ vBinormal = cross( vNormal, vTangent );
+ vBinormal = normalize( vBinormal );
+
+ // texture coordinates
+ vUv = uv;
+
+ // displacement mapping
+ vec3 dv = texture2D( tDisplacement, uv ).xyz;
+ float df = uDisplacementScale * dv.x + uDisplacementBias;
+ vec4 displacedPosition = vec4(vNormal.xyz * df, 0.0 ) + mvPosition;
+ gl_Position = projectionMatrix * displacedPosition;
+
+ vec3 normalTex = texture2D(tNormal, uv).xyz * 2.0 - 1.0;
+ vNormal = vec3(normalMatrix * vec4(normalTex, 1.0));
+}
=== added file 'data/textures/terrain-backgrounddetailed6.jpg'
Binary files data/textures/terrain-backgrounddetailed6.jpg 1970-01-01 00:00:00 +0000 and data/textures/terrain-backgrounddetailed6.jpg 2012-06-29 12:27:16 +0000 differ
=== added file 'data/textures/terrain-grasslight-512-nm.jpg'
Binary files data/textures/terrain-grasslight-512-nm.jpg 1970-01-01 00:00:00 +0000 and data/textures/terrain-grasslight-512-nm.jpg 2012-06-29 12:27:16 +0000 differ
=== added file 'data/textures/terrain-grasslight-512.jpg'
Binary files data/textures/terrain-grasslight-512.jpg 1970-01-01 00:00:00 +0000 and data/textures/terrain-grasslight-512.jpg 2012-06-29 12:27:16 +0000 differ
=== modified file 'src/android.cpp'
@@ -222,6 +222,7 @@
Benchmark::register_scene(*new SceneDesktop(*g_canvas));
Benchmark::register_scene(*new SceneBuffer(*g_canvas));
Benchmark::register_scene(*new SceneIdeas(*g_canvas));
+ Benchmark::register_scene(*new SceneTerrain(*g_canvas));
g_benchmark_collection = new BenchmarkCollection();
g_benchmark_collection->populate_from_options();
=== modified file 'src/main.cpp'
@@ -61,6 +61,7 @@
scenes.push_back(new SceneDesktop(canvas));
scenes.push_back(new SceneBuffer(canvas));
scenes.push_back(new SceneIdeas(canvas));
+ scenes.push_back(new SceneTerrain(canvas));
for (vector<Scene*>::const_iterator iter = scenes.begin();
iter != scenes.end();
=== added directory 'src/scene-terrain'
=== added file 'src/scene-terrain.cpp'
@@ -0,0 +1,355 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "mesh.h"
+#include "util.h"
+#include "texture.h"
+#include "shader-source.h"
+#include "renderer.h"
+
+using LibMatrix::vec2;
+using LibMatrix::vec3;
+using LibMatrix::vec4;
+using LibMatrix::mat4;
+
+class SceneTerrainPrivate
+{
+public:
+ SceneTerrainPrivate(Canvas &canvas, const LibMatrix::vec2 &repeat_overlay,
+ bool use_bloom, bool use_tilt_shift) :
+ canvas(canvas), repeat_overlay(repeat_overlay),
+ use_bloom(use_bloom), use_tilt_shift(use_tilt_shift),
+ terrain_renderer(0), bloom_v_renderer(0), bloom_h_renderer(0),
+ overlay_renderer(0), tilt_v_renderer(0), tilt_h_renderer(0),
+ copy_renderer(0), height_map_renderer(0), normal_map_renderer(0),
+ specular_map_renderer(0),
+ height_normal_chain(0), bloom_chain(0), tilt_chain(0), terrain_chain(0)
+ {
+ init_renderers();
+ }
+
+ ~SceneTerrainPrivate()
+ {
+ release_renderers();
+ }
+
+ void init_renderers()
+ {
+ /* Create and set up renderers */
+ const vec2 map_res(256.0f, 256.0f);
+ const vec2 screen_res(canvas.width(), canvas.height());
+ const vec2 bloom_res(256.0f, 256.0f);
+ const vec2 grass_res(512.0f, 512.0f);
+
+ height_map_renderer = new SimplexNoiseRenderer(map_res);
+ height_map_renderer->setup(height_map_renderer->size(), false, false);
+
+ normal_map_renderer = new NormalFromHeightRenderer(map_res);
+ normal_map_renderer->setup(normal_map_renderer->size(), false, false);
+
+ specular_map_renderer = new LuminanceRenderer(grass_res);
+ specular_map_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_REPEAT, GL_REPEAT);
+ specular_map_renderer->setup(specular_map_renderer->size(), false, false);
+
+ terrain_renderer = new TerrainRenderer(screen_res, repeat_overlay);
+ terrain_renderer->setup(terrain_renderer->size(),
+ !use_bloom && !use_tilt_shift,
+ true);
+ terrain_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+
+ /* Bloom */
+ if (use_bloom) {
+ bloom_h_renderer = new BlurRenderer(bloom_res, 2, 4.0,
+ BlurRenderer::BlurDirectionHorizontal,
+ vec2(1.0, 1.0) / screen_res,
+ 0.0);
+ bloom_h_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ bloom_h_renderer->setup(bloom_h_renderer->size(), false, false);
+
+ bloom_v_renderer = new BlurRenderer(bloom_res, 2, 4.0,
+ BlurRenderer::BlurDirectionVertical,
+ vec2(1.0, 1.0) / bloom_res,
+ 0.0);
+ bloom_v_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ bloom_v_renderer->setup(bloom_v_renderer->size(), false, false);
+ overlay_renderer = new OverlayRenderer(*terrain_renderer, 0.6);
+ }
+
+ /* Tilt-shift */
+ if (use_tilt_shift) {
+ tilt_h_renderer = new BlurRenderer(screen_res, 4, 2.7,
+ BlurRenderer::BlurDirectionHorizontal,
+ vec2(1.0, 1.0) / screen_res,
+ 0.5);
+ tilt_h_renderer->setup_texture(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,
+ GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+ tilt_h_renderer->setup(tilt_h_renderer->size(), false, false);
+
+ tilt_v_renderer = new BlurRenderer(screen_res, 4, 2.7,
+ BlurRenderer::BlurDirectionVertical,
+ vec2(1.0, 1.0) / screen_res,
+ 0.5);
+ }
+
+ /* Copy renderer */
+ if (use_bloom && !use_tilt_shift)
+ copy_renderer = new CopyRenderer(screen_res);
+
+ /* Height normal chain */
+ height_normal_chain = new RendererChain();
+ height_normal_chain->append(*height_map_renderer);
+ height_normal_chain->append(*normal_map_renderer);
+
+ /* Bloom effect chain */
+ if (use_bloom) {
+ bloom_chain = new RendererChain();
+ bloom_chain->append(*bloom_h_renderer);
+ bloom_chain->append(*bloom_v_renderer);
+ bloom_chain->append(*overlay_renderer);
+ }
+
+ /* Tilt-shift effect chain */
+ if (use_tilt_shift) {
+ tilt_chain = new RendererChain();
+ tilt_chain->append(*tilt_h_renderer);
+ tilt_chain->append(*tilt_v_renderer);
+ }
+
+ /* Terrain chain */
+ terrain_chain = new RendererChain();
+ terrain_chain->append(*terrain_renderer);
+ if (use_bloom)
+ terrain_chain->append(*bloom_chain);
+ if (use_tilt_shift)
+ terrain_chain->append(*tilt_chain);
+
+ /*
+ * If are just using bloom, the terrain is rendered to a texture and
+ * bloom applied on that texture. We need to "copy" that texture's
+ * contents to the screen to make the scene visible.
+ */
+ if (use_bloom && !use_tilt_shift)
+ terrain_chain->append(*copy_renderer);
+
+ /*
+ * Set up renderer textures.
+ */
+ terrain_renderer->height_map_texture(height_map_renderer->texture());
+ terrain_renderer->normal_map_texture(normal_map_renderer->texture());
+ terrain_renderer->specular_map_texture(specular_map_renderer->texture());
+
+ specular_map_renderer->input_texture(terrain_renderer->diffuse1_texture());
+ }
+
+ void release_renderers()
+ {
+ delete terrain_chain;
+ delete bloom_chain;
+ delete tilt_chain;
+ delete height_normal_chain;
+
+ delete height_map_renderer;
+ delete normal_map_renderer;
+ delete specular_map_renderer;
+ delete terrain_renderer;
+ delete bloom_v_renderer;
+ delete bloom_h_renderer;
+ delete overlay_renderer;
+ delete tilt_v_renderer;
+ delete tilt_h_renderer;
+ delete copy_renderer;
+ }
+
+ Canvas &canvas;
+ LibMatrix::vec2 repeat_overlay;
+ bool use_bloom;
+ bool use_tilt_shift;
+
+ /* Renderers */
+ TerrainRenderer *terrain_renderer;
+ BlurRenderer *bloom_v_renderer;
+ BlurRenderer *bloom_h_renderer;
+ OverlayRenderer *overlay_renderer;
+ BlurRenderer *tilt_v_renderer;
+ BlurRenderer *tilt_h_renderer;
+ CopyRenderer *copy_renderer;
+
+ SimplexNoiseRenderer *height_map_renderer;
+ NormalFromHeightRenderer *normal_map_renderer;
+ LuminanceRenderer *specular_map_renderer;
+
+ /* Chains */
+ RendererChain *height_normal_chain;
+ RendererChain *bloom_chain;
+ RendererChain *tilt_chain;
+ RendererChain *terrain_chain;
+};
+
+SceneTerrain::SceneTerrain(Canvas &pCanvas) :
+ Scene(pCanvas, "terrain"), priv_(0)
+{
+ options_["repeat-overlay"] = Scene::Option("repeat-overlay", "6.0",
+ "How many times to repeat the terrain texture on the terrain plane (per side)");
+ options_["bloom"] = Scene::Option("bloom", "true",
+ "Use bloom post-processing effect [true,false]");
+ options_["tilt-shift"] = Scene::Option("tilt-shift", "true",
+ "Use tilt-shift post-processing effect [true,false]");
+}
+
+SceneTerrain::~SceneTerrain()
+{
+ delete priv_;
+}
+
+bool
+SceneTerrain::load()
+{
+ Scene::load();
+
+ running_ = false;
+
+ return true;
+}
+
+void
+SceneTerrain::unload()
+{
+ Scene::unload();
+}
+
+void
+SceneTerrain::setup()
+{
+ Scene::setup();
+
+ /* Ensure implementation supports vertex texture fetch */
+ GLint vertex_textures;
+ glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &vertex_textures);
+ if (vertex_textures <= 0) {
+ Log::error("SceneTerrain requires Vertex Texture Fetch support, "
+ "but GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS is %d\n",
+ vertex_textures);
+ currentFrame_ = 0;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ running_ = false;
+ return;
+ }
+
+ /* Parse options */
+ float repeat = Util::fromString<double>(options_["repeat-overlay"].value);
+ LibMatrix::vec2 repeat_overlay(repeat, repeat);
+ bool use_bloom = options_["bloom"].value == "true";
+ bool use_tilt_shift = options_["tilt-shift"].value == "true";
+
+ priv_ = new SceneTerrainPrivate(canvas_, repeat_overlay,
+ use_bloom, use_tilt_shift);
+
+ /* Set up terrain rendering program */
+ LibMatrix::Stack4 model;
+ LibMatrix::Stack4 camera;
+ LibMatrix::mat4 projection = LibMatrix::Mat4::perspective(
+ 40.0, canvas_.width() / static_cast<float>(canvas_.height()),
+ 2.0, 4000.0);
+
+ /* Place camera */
+ camera.lookAt(-1200.0f, 800.0f, 1200.0f,
+ 0.0, 0.0, 0.0,
+ 0.0, 1.0, 0.0);
+
+ /* Move and rotate plane */
+ model.translate(0.0f, -125.0f, 0.0f);
+ model.rotate(-90.0, 1.0f, 0.0f, 0.0f);
+
+ LibMatrix::mat4 view_matrix(camera.getCurrent());
+ LibMatrix::mat4 model_matrix(model.getCurrent());
+
+ LibMatrix::mat4 model_view_matrix(view_matrix * model_matrix);
+
+ LibMatrix::mat4 normal_matrix(model_view_matrix);
+ normal_matrix.inverse().transpose();
+
+ /* Set up terrain renderer program */
+ priv_->terrain_renderer->program().start();
+ priv_->terrain_renderer->program()["viewMatrix"] = view_matrix;
+ priv_->terrain_renderer->program()["modelViewMatrix"] = model_view_matrix;
+ priv_->terrain_renderer->program()["normalMatrix"] = normal_matrix;
+ priv_->terrain_renderer->program()["projectionMatrix"] = projection;
+
+ /* Create the specular map */
+ priv_->specular_map_renderer->render();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glViewport(0, 0, canvas_.width(), canvas_.height());
+
+ currentFrame_ = 0;
+ startTime_ = Util::get_timestamp_us() / 1000000.0;
+ running_ = true;
+}
+
+void
+SceneTerrain::teardown()
+{
+ delete priv_;
+ priv_ = 0;
+ Scene::teardown();
+}
+
+void
+SceneTerrain::update()
+{
+ Scene::update();
+
+ double now = Util::get_timestamp_us() / 1000000.0;
+ float diff = now - startTime_;
+ float scale = priv_->terrain_renderer->repeat_overlay().x() /
+ priv_->height_map_renderer->uv_scale().x();
+
+ /* Update height map */
+ priv_->height_map_renderer->program().start();
+ priv_->height_map_renderer->program()["uvOffset"] = vec2(diff * 0.05f, 0.0f);
+ priv_->terrain_renderer->program().start();
+ priv_->terrain_renderer->program()["uOffset"] = vec2(scale * diff * 0.05f, 0.0f);
+}
+
+void
+SceneTerrain::draw()
+{
+ /* Render the height and normal maps used by the terrain */
+ priv_->height_normal_chain->render();
+
+ /* Render the terrain plus any post-processing effects */
+ priv_->terrain_chain->render();
+}
+
+Scene::ValidationResult
+SceneTerrain::validate()
+{
+ return Scene::ValidationUnknown;
+}
=== added file 'src/scene-terrain/base-renderer.cpp'
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "renderer.h"
+
+BaseRenderer::BaseRenderer(const LibMatrix::vec2 &size) :
+ texture_(0), input_texture_(0), fbo_(0), depth_renderbuffer_(0),
+ min_filter_(GL_LINEAR), mag_filter_(GL_LINEAR),
+ wrap_s_(GL_CLAMP_TO_EDGE), wrap_t_(GL_CLAMP_TO_EDGE)
+{
+ setup(size, true, true);
+}
+
+BaseRenderer::~BaseRenderer()
+{
+ glDeleteTextures(1, &texture_);
+ glDeleteRenderbuffers(1, &depth_renderbuffer_);
+ glDeleteFramebuffers(1, &fbo_);
+}
+
+void
+BaseRenderer::setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth)
+{
+ size_ = size;
+ recreate(onscreen, has_depth);
+}
+
+void
+BaseRenderer::setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t)
+{
+ min_filter_ = min_filter;
+ mag_filter_ = mag_filter;
+ wrap_s_ = wrap_s;
+ wrap_t_ = wrap_t;
+ update_texture_parameters();
+}
+
+void
+BaseRenderer::make_current()
+{
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glViewport(0, 0, size_.x(), size_.y());
+ if (!fbo_ || depth_renderbuffer_) {
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(GL_TRUE);
+ }
+ else {
+ glDisable(GL_DEPTH_TEST);
+ glDepthMask(GL_FALSE);
+ }
+}
+
+void
+BaseRenderer::update_mipmap()
+{
+ if (texture_ && min_filter_ != GL_NEAREST && min_filter_ != GL_LINEAR) {
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+}
+
+void
+BaseRenderer::recreate(bool onscreen, bool has_depth)
+{
+ if (texture_) {
+ glDeleteTextures(1, &texture_);
+ texture_ = 0;
+ }
+ if (fbo_) {
+ glDeleteRenderbuffers(1, &depth_renderbuffer_);
+ depth_renderbuffer_ = 0;
+ glDeleteFramebuffers(1, &fbo_);
+ fbo_ = 0;
+ }
+ if (!onscreen) {
+ create_texture();
+ create_fbo(has_depth);
+ }
+}
+
+void
+BaseRenderer::create_texture()
+{
+ glGenTextures(1, &texture_);
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
+ update_texture_parameters();
+}
+
+void
+BaseRenderer::update_texture_parameters()
+{
+ if (texture_) {
+ glBindTexture(GL_TEXTURE_2D, texture_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrap_s_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrap_t_);
+ }
+ update_mipmap();
+}
+
+void
+BaseRenderer::create_fbo(bool has_depth)
+{
+ if (has_depth) {
+ /* Create a renderbuffer for depth storage */
+ glGenRenderbuffers(1, &depth_renderbuffer_);
+ glBindRenderbuffer(GL_RENDERBUFFER, depth_renderbuffer_);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
+ size_.x(), size_.y());
+ }
+
+ /* Create the FBO and attach the texture and the renderebuffer */
+ glGenFramebuffers(1, &fbo_);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, texture_, 0);
+ if (has_depth) {
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_RENDERBUFFER, depth_renderbuffer_);
+ }
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+}
=== added file 'src/scene-terrain/blur-renderer.cpp'
@@ -0,0 +1,161 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+void
+create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source,
+ unsigned int radius, float sigma, BlurRenderer::BlurDirection direction,
+ float tilt_shift);
+
+BlurRenderer::BlurRenderer(const LibMatrix::vec2 &size, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step, float tilt_shift) :
+ TextureRenderer(size, *blur_program(true, radius, sigma, dir, step, tilt_shift))
+{
+ blur_program_ = blur_program(false, radius, sigma, dir, step, tilt_shift);
+}
+
+Program *
+BlurRenderer::blur_program(bool create_new, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step,
+ float tilt_shift)
+{
+ static Program *blur_program(0);
+ if (create_new)
+ blur_program = 0;
+
+ if (!blur_program) {
+ blur_program = new Program();
+ ShaderSource blur_vtx_shader;
+ ShaderSource blur_frg_shader;
+ create_blur_shaders(blur_vtx_shader, blur_frg_shader, radius,
+ sigma, dir, tilt_shift);
+
+ if (dir == BlurDirectionHorizontal || dir == BlurDirectionBoth)
+ blur_frg_shader.add_const("TextureStepX", step.x());
+ if (dir == BlurDirectionVertical || dir == BlurDirectionBoth)
+ blur_frg_shader.add_const("TextureStepY", step.y());
+
+ Scene::load_shaders_from_strings(*blur_program,
+ blur_vtx_shader.str(),
+ blur_frg_shader.str());
+ blur_program->start();
+ (*blur_program)["Texture0"] = 0;
+ (*blur_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*blur_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ blur_program->stop();
+ }
+
+ return blur_program;
+}
+
+void
+create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source,
+ unsigned int radius, float sigma, BlurRenderer::BlurDirection direction,
+ float tilt_shift)
+{
+ vtx_source.append_file(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ frg_source.append_file(GLMARK_DATA_PATH"/shaders/terrain-blur.frag");
+
+ /* Don't let the gaussian curve become too narrow */
+ if (sigma < 1.0)
+ sigma = 1.0;
+
+ unsigned int side = 2 * radius + 1;
+ float values[radius];
+ float sum = 0.0;
+
+ for (unsigned int i = 0; i < radius + 1; i++) {
+ float s2 = 2.0 * sigma * sigma;
+ float k = 1.0 / std::sqrt(M_PI * s2) * std::exp( - (static_cast<float>(i) * i) / s2);
+ values[i] = k;
+ sum += k;
+ }
+
+ sum += sum - values[0];
+
+ for (unsigned int i = 0; i < radius + 1; i++) {
+ std::stringstream ss_tmp;
+ ss_tmp << "Kernel" << i;
+ frg_source.add_const(ss_tmp.str(), values[i] / sum);
+ }
+
+ frg_source.add_const("TiltShift", tilt_shift);
+
+ std::stringstream ss;
+
+ if (direction == BlurRenderer::BlurDirectionHorizontal ||
+ direction == BlurRenderer::BlurDirectionBoth)
+ {
+ if (tilt_shift == 1.0)
+ ss << "const float stepX = TextureStepX;" << std::endl;
+ else
+ ss << "float stepX = TextureStepX * abs(TiltShift - TextureCoord.y) / abs(1.0 - TiltShift);" << std::endl;
+ }
+
+ if (direction == BlurRenderer::BlurDirectionVertical ||
+ direction == BlurRenderer::BlurDirectionBoth)
+ {
+ if (tilt_shift == 1.0)
+ ss << "const float stepY = TextureStepY;" << std::endl;
+ else
+ ss << "float stepY = TextureStepY * abs(TiltShift - TextureCoord.y) / abs(1.0 - TiltShift);" << std::endl;
+ }
+
+ ss << "result = " << std::endl;
+
+ if (direction == BlurRenderer::BlurDirectionHorizontal) {
+ for (unsigned int i = 0; i < side; i++) {
+ int offset = static_cast<int>(i - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(" <<
+ offset << ".0 * stepX, 0.0)) * Kernel" <<
+ std::abs(offset) << " +" << std::endl;
+ }
+ ss << "0.0 ;" << std::endl;
+ }
+ else if (direction == BlurRenderer::BlurDirectionVertical) {
+ for (unsigned int i = 0; i < side; i++) {
+ int offset = static_cast<int>(i - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(0.0, " <<
+ offset << ".0 * stepY)) * Kernel" <<
+ std::abs(offset) << " +" << std::endl;
+ }
+ ss << "0.0 ;" << std::endl;
+ }
+ else if (direction == BlurRenderer::BlurDirectionBoth) {
+ for (unsigned int i = 0; i < side; i++) {
+ int ioffset = static_cast<int>(i - radius);
+ for (unsigned int j = 0; j < side; j++) {
+ int joffset = static_cast<int>(j - radius);
+ ss << "texture2D(Texture0, TextureCoord + vec2(" <<
+ ioffset << ".0 * stepX, " <<
+ joffset << ".0 * stepY))" <<
+ " * Kernel" << std::abs(ioffset) <<
+ " * Kernel" << std::abs(joffset) << " +" << std::endl;
+ }
+ }
+ ss << " 0.0;" << std::endl;
+ }
+
+ frg_source.replace("$CONVOLUTION$", ss.str());
+}
=== added file 'src/scene-terrain/copy-renderer.cpp'
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+CopyRenderer::CopyRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *copy_program(true))
+{
+ copy_program_ = copy_program(false);
+}
+
+Program *
+CopyRenderer::copy_program(bool create_new)
+{
+ static Program *copy_program(0);
+ if (create_new)
+ copy_program = 0;
+
+ if (!copy_program) {
+ copy_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-overlay.frag");
+
+ Scene::load_shaders_from_strings(*copy_program, vtx_shader.str(), frg_shader.str());
+
+ copy_program->start();
+ (*copy_program)["tDiffuse"] = 0;
+ (*copy_program)["opacity"] = 1.0f;
+ (*copy_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*copy_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ copy_program->stop();
+ }
+
+ return copy_program;
+}
=== added file 'src/scene-terrain/luminance-renderer.cpp'
@@ -0,0 +1,57 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+LuminanceRenderer::LuminanceRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *luminance_program(true))
+{
+ luminance_program_ = luminance_program(false);
+}
+
+Program *
+LuminanceRenderer::luminance_program(bool create_new)
+{
+ static Program *luminance_program(0);
+ if (create_new)
+ luminance_program = 0;
+
+ if (!luminance_program) {
+ luminance_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-luminance.frag");
+
+ Scene::load_shaders_from_strings(*luminance_program,
+ vtx_shader.str(), frg_shader.str());
+
+ luminance_program->start();
+ (*luminance_program)["tDiffuse"] = 0;
+ (*luminance_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*luminance_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ luminance_program->stop();
+ }
+
+ return luminance_program;
+}
+
+
=== added file 'src/scene-terrain/normal-from-height-renderer.cpp'
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+NormalFromHeightRenderer::NormalFromHeightRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *normal_from_height_program(size, true))
+{
+ normal_from_height_program_ = normal_from_height_program(size, false);
+}
+
+Program *
+NormalFromHeightRenderer::normal_from_height_program(const LibMatrix::vec2 &size,
+ bool create_new)
+{
+ static Program *normal_from_height_program(0);
+ if (create_new)
+ normal_from_height_program = 0;
+
+ if (!normal_from_height_program) {
+ normal_from_height_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-normalmap.frag");
+
+ Scene::load_shaders_from_strings(*normal_from_height_program,
+ vtx_shader.str(), frg_shader.str());
+
+ normal_from_height_program->start();
+ (*normal_from_height_program)["heightMap"] = 0;
+ (*normal_from_height_program)["resolution"] = size;
+ (*normal_from_height_program)["height"] = 0.05f;
+ (*normal_from_height_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*normal_from_height_program)["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ normal_from_height_program->stop();
+ }
+
+ return normal_from_height_program;
+}
+
=== added file 'src/scene-terrain/overlay-renderer.cpp'
@@ -0,0 +1,122 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+OverlayRenderer::OverlayRenderer(IRenderer &target, GLfloat opacity) :
+ target_renderer_(target), opacity_(opacity)
+
+{
+ create_program();
+ create_mesh();
+}
+
+
+void
+OverlayRenderer::setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth)
+{
+ static_cast<void>(size);
+ static_cast<void>(onscreen);
+ static_cast<void>(has_depth);
+}
+
+void
+OverlayRenderer::setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t)
+{
+ static_cast<void>(min_filter);
+ static_cast<void>(mag_filter);
+ static_cast<void>(wrap_s);
+ static_cast<void>(wrap_t);
+}
+
+void
+OverlayRenderer::make_current()
+{
+ target_renderer_.make_current();
+}
+
+void
+OverlayRenderer::update_mipmap()
+{
+ target_renderer_.update_mipmap();
+}
+
+void
+OverlayRenderer::render()
+{
+ target_renderer_.make_current();
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, input_texture_);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ program_.start();
+
+ mesh_.render_vbo();
+
+ program_.stop();
+
+ glDisable(GL_BLEND);
+
+ target_renderer_.update_mipmap();
+}
+
+void
+OverlayRenderer::create_mesh()
+{
+ // Set vertex format
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3); // Position
+ mesh_.set_vertex_format(vertex_format);
+
+ mesh_.make_grid(1, 1, 2.0, 2.0, 0);
+ mesh_.build_vbo();
+
+ program_.start();
+
+ // Set attribute locations
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ program_.stop();
+}
+
+void
+OverlayRenderer::create_program()
+{
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-overlay.frag");
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_shader.str(), frg_shader.str()))
+ return;
+
+ program_.start();
+ program_["tDiffuse"] = 0;
+ program_["opacity"] = opacity_;
+ program_["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ program_["uvScale"] = LibMatrix::vec2(1.0f, 1.0f);
+ program_.stop();
+}
=== added file 'src/scene-terrain/renderer-chain.cpp'
@@ -0,0 +1,115 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "renderer.h"
+
+void
+RendererChain::setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth)
+{
+ static_cast<void>(size);
+ static_cast<void>(onscreen);
+ static_cast<void>(has_depth);
+}
+
+void
+RendererChain::setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t)
+{
+ static_cast<void>(min_filter);
+ static_cast<void>(mag_filter);
+ static_cast<void>(wrap_s);
+ static_cast<void>(wrap_t);
+}
+
+void
+RendererChain::input_texture(GLuint t)
+{
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.front());
+ renderer.input_texture(t);
+ }
+}
+
+GLuint
+RendererChain::texture()
+{
+ GLuint t(0);
+
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ t = renderer.texture();
+ }
+
+ return t;
+}
+
+LibMatrix::vec2
+RendererChain::size()
+{
+ LibMatrix::vec2 s;
+
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ s = renderer.size();
+ }
+
+ return s;
+}
+
+void
+RendererChain::make_current()
+{
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ renderer.make_current();
+ }
+}
+
+void
+RendererChain::update_mipmap()
+{
+ if (!renderers_.empty()) {
+ IRenderer &renderer(*renderers_.back());
+ renderer.update_mipmap();
+ }
+}
+
+void
+RendererChain::render()
+{
+ for(std::vector<IRenderer *>::iterator iter = renderers_.begin();
+ iter != renderers_.end();
+ iter++)
+ {
+ (*iter)->render();
+ }
+}
+
+void
+RendererChain::append(IRenderer &renderer)
+{
+ if (!renderers_.empty()) {
+ IRenderer &prev_renderer(*renderers_.back());
+ renderer.input_texture(prev_renderer.texture());
+ }
+
+ renderers_.push_back(&renderer);
+}
=== added file 'src/scene-terrain/renderer.h'
@@ -0,0 +1,347 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include <vector>
+
+#include "mesh.h"
+#include "vec.h"
+#include "program.h"
+#include "gl-headers.h"
+
+/**
+ * Renderer interface.
+ */
+class IRenderer
+{
+public:
+ /**
+ * Sets up the renderer's target.
+ */
+ virtual void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth) = 0;
+ /**
+ * Sets up the renderer's target texture (if any).
+ */
+ virtual void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t) = 0;
+ /**
+ * Sets the renderer's input texture.
+ */
+ virtual void input_texture(GLuint t) = 0;
+ /**
+ * Gets the renderer's target texture (if any).
+ */
+ virtual GLuint texture() = 0;
+ /**
+ * Gets the size of the renderer's target.
+ */
+ virtual LibMatrix::vec2 size() = 0;
+ /**
+ * Makes the renderer current i.e. the rendering target.
+ */
+ virtual void make_current() = 0;
+ /**
+ * Updates the mipmap of the texture backing the renderer (if any).
+ */
+ virtual void update_mipmap() = 0;
+ /**
+ * Renders to the renderer's target.
+ */
+ virtual void render() = 0;
+
+protected:
+ virtual ~IRenderer() {}
+};
+
+/**
+ * A chain of renderers, which implements IRenderer
+ */
+class RendererChain : public IRenderer
+{
+public:
+ RendererChain() {}
+ virtual ~RendererChain() {}
+
+ /* IRenderer methods */
+ void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth);
+ void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t);
+ void input_texture(GLuint t);
+ GLuint texture();
+ LibMatrix::vec2 size();
+ void make_current();
+ void update_mipmap();
+ void render();
+
+ /**
+ * Appends a renderer to the chain.
+ *
+ * @param renderer the renderer to append
+ */
+ void append(IRenderer &renderer);
+
+private:
+ std::vector<IRenderer *> renderers_;
+};
+
+/**
+ * A base implementation of the IRenderer interface.
+ */
+class BaseRenderer : public IRenderer
+{
+public:
+ BaseRenderer(const LibMatrix::vec2 &size);
+ virtual ~BaseRenderer();
+
+ /* IRenderer methods */
+ virtual void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth);
+ virtual void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t);
+ virtual void input_texture(GLuint t) { input_texture_ = t; }
+ virtual GLuint texture() { return texture_; }
+ virtual LibMatrix::vec2 size() { return size_; }
+ virtual void make_current();
+ virtual void update_mipmap();
+ virtual void render() = 0;
+
+protected:
+ void recreate(bool onscreen, bool has_depth);
+ void create_texture();
+ void update_texture_parameters();
+ void create_fbo(bool has_depth);
+
+ LibMatrix::vec2 size_;
+ GLuint texture_;
+ GLuint input_texture_;
+ GLuint fbo_;
+ GLuint depth_renderbuffer_;
+ GLint min_filter_;
+ GLint mag_filter_;
+ GLint wrap_s_;
+ GLint wrap_t_;
+};
+
+/**
+ * A renderer that renders its input texture to its target,
+ * according to the supplied GL Program.
+ */
+class TextureRenderer : public BaseRenderer
+{
+public:
+ TextureRenderer(const LibMatrix::vec2 &size, Program &program);
+ virtual ~TextureRenderer() { }
+
+ /* IRenderer/BaseRenderer methods */
+ virtual void render();
+
+ /**
+ * Gets the program associated with the renderer.
+ */
+ Program &program() { return program_; }
+
+private:
+ void create_mesh();
+
+ Mesh mesh_;
+ Program &program_;
+};
+
+/**
+ * A renderer that copies the input texture to its target.
+ */
+class CopyRenderer : public TextureRenderer
+{
+public:
+ CopyRenderer(const LibMatrix::vec2 &size);
+
+ virtual ~CopyRenderer() { delete copy_program_; }
+
+private:
+ static Program *copy_program(bool create_new);
+
+ Program *copy_program_;
+};
+
+/**
+ * A renderer that renders simplex noise to its target.
+ */
+class SimplexNoiseRenderer : public TextureRenderer
+{
+public:
+ SimplexNoiseRenderer(const LibMatrix::vec2 &size);
+ virtual ~SimplexNoiseRenderer() { delete noise_program_; }
+
+ LibMatrix::vec2 uv_scale() { return uv_scale_; }
+private:
+ static Program *noise_program(bool create_new);
+ static LibMatrix::vec2 uv_scale_;
+
+ Program *noise_program_;
+};
+
+/**
+ * A renderer that renders a normal map to its target from a
+ * height map in its input texture.
+ */
+class NormalFromHeightRenderer : public TextureRenderer
+{
+public:
+ NormalFromHeightRenderer(const LibMatrix::vec2 &size);
+ virtual ~NormalFromHeightRenderer() { delete normal_from_height_program_; }
+
+private:
+ static Program *normal_from_height_program(const LibMatrix::vec2 &size,
+ bool create_new);
+
+ Program *normal_from_height_program_;
+};
+
+/**
+ * A renderer that renders the luminance of its input texture to its target.
+ */
+class LuminanceRenderer : public TextureRenderer
+{
+public:
+ LuminanceRenderer(const LibMatrix::vec2 &size);
+ virtual ~LuminanceRenderer() { delete luminance_program_; }
+
+private:
+ static Program *luminance_program(bool create_new);
+
+ Program *luminance_program_;
+};
+
+
+/**
+ * A renderer that renders a blurred version of the input texture to its target.
+ */
+class BlurRenderer : public TextureRenderer
+{
+public:
+ enum BlurDirection {
+ BlurDirectionHorizontal,
+ BlurDirectionVertical,
+ BlurDirectionBoth
+ };
+
+ BlurRenderer(const LibMatrix::vec2 &size, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step, float tilt_shift);
+ virtual ~BlurRenderer() { delete blur_program_; }
+
+private:
+ static Program *blur_program(bool create_new, int radius, float sigma,
+ BlurDirection dir, const LibMatrix::vec2 &step,
+ float tilt_shift);
+
+ Program *blur_program_;
+};
+
+/**
+ * A renderer that renders with opacity (overlays) it's input texture over
+ * the target of another renderer.
+ */
+class OverlayRenderer : public IRenderer
+{
+public:
+ OverlayRenderer(IRenderer &target, GLfloat opacity);
+ virtual ~OverlayRenderer() { }
+
+ /* IRenderable Methods */
+ void setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth);
+ void setup_texture(GLint min_filter, GLint mag_filter,
+ GLint wrap_s, GLint wrap_t);
+ void input_texture(GLuint t) { input_texture_ = t; }
+ virtual GLuint texture() { return target_renderer_.texture(); }
+ virtual LibMatrix::vec2 size() { return target_renderer_.size(); }
+ virtual void render();
+ void make_current();
+ void update_mipmap();
+
+private:
+ void create_mesh();
+ void create_program();
+
+ Mesh mesh_;
+ Program program_;
+ IRenderer &target_renderer_;
+ GLfloat opacity_;
+ GLuint input_texture_;
+};
+
+/**
+ * A renderer that renders a dynamic terrain as per the WebGL
+ * dynamic terrain demo.
+ */
+class TerrainRenderer : public BaseRenderer
+{
+public:
+ TerrainRenderer(const LibMatrix::vec2 &size, const LibMatrix::vec2 &repeat_overlay);
+ virtual ~TerrainRenderer();
+
+ /* IRenderable Methods */
+ virtual void render();
+
+ /**
+ * Gets the program associated with the renderer.
+ */
+ Program &program() { return program_; }
+ /**
+ * Sets the height map texture to use.
+ */
+ void height_map_texture(GLuint tex) { height_map_tex_ = tex; }
+ /**
+ * Sets the normal map texture to use.
+ */
+ void normal_map_texture(GLuint tex) { normal_map_tex_ = tex; }
+ /**
+ * Sets the specular map texture to use.
+ */
+ void specular_map_texture(GLuint tex) { specular_map_tex_ = tex; }
+ /**
+ * Returns the main diffuse texture.
+ */
+ GLuint diffuse1_texture() { return diffuse1_tex_; }
+ LibMatrix::vec2 repeat_overlay() { return repeat_overlay_; }
+
+private:
+ void create_mesh();
+ void init_textures();
+ void init_program();
+ void bind_textures();
+ void deinit_textures();
+
+ LibMatrix::vec3 color_to_vec3(uint32_t c)
+ {
+ return LibMatrix::vec3(((c >> 0) & 0xff) / 255.0,
+ ((c >> 8) & 0xff) / 255.0,
+ ((c >> 16) & 0xff) / 255.0);
+ }
+
+ Mesh mesh_;
+ Program program_;
+
+ GLuint height_map_tex_;
+ GLuint normal_map_tex_;
+ GLuint specular_map_tex_;
+ GLuint diffuse1_tex_;
+ GLuint diffuse2_tex_;
+ GLuint detail_tex_;
+ LibMatrix::vec2 repeat_overlay_;
+};
=== added file 'src/scene-terrain/simplex-noise-renderer.cpp'
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "shader-source.h"
+
+LibMatrix::vec2 SimplexNoiseRenderer::uv_scale_(1.5f, 1.5);
+
+SimplexNoiseRenderer::SimplexNoiseRenderer(const LibMatrix::vec2 &size) :
+ TextureRenderer(size, *noise_program(true))
+{
+ noise_program_ = noise_program(false);
+}
+
+Program *
+SimplexNoiseRenderer::noise_program(bool create_new)
+{
+ static Program *noise_program(0);
+ if (create_new)
+ noise_program = 0;
+
+ if (!noise_program) {
+ noise_program = new Program();
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain-texture.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain-noise.frag");
+
+ Scene::load_shaders_from_strings(*noise_program, vtx_shader.str(), frg_shader.str());
+
+ noise_program->start();
+ (*noise_program)["time"] = 1.0f;
+ (*noise_program)["uvOffset"] = LibMatrix::vec2(0.0f, 0.0f);
+ (*noise_program)["uvScale"] = uv_scale_;
+ noise_program->stop();
+ }
+
+ return noise_program;
+}
=== added file 'src/scene-terrain/terrain-renderer.cpp'
@@ -0,0 +1,246 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "scene.h"
+#include "renderer.h"
+#include "texture.h"
+#include "shader-source.h"
+
+TerrainRenderer::TerrainRenderer(const LibMatrix::vec2 &size,
+ const LibMatrix::vec2 &repeat_overlay) :
+ BaseRenderer(size), height_map_tex_(0), normal_map_tex_(0),
+ specular_map_tex_(0), repeat_overlay_(repeat_overlay)
+{
+ create_mesh();
+ init_textures();
+ init_program();
+}
+
+TerrainRenderer::~TerrainRenderer()
+{
+ deinit_textures();
+}
+
+void
+TerrainRenderer::render()
+{
+ make_current();
+ glClearColor(0.825f, 0.7425f, 0.61875f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+ program_.start();
+
+ bind_textures();
+ mesh_.render_vbo();
+
+ program_.stop();
+
+ update_mipmap();
+}
+
+void
+TerrainRenderer::init_textures()
+{
+ /* Create textures */
+ Texture::load("terrain-grasslight-512", &diffuse1_tex_,
+ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, 0);
+ Texture::load("terrain-backgrounddetailed6", &diffuse2_tex_,
+ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, 0);
+ Texture::load("terrain-grasslight-512-nm", &detail_tex_,
+ GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR, 0);
+
+ /* Set REPEAT wrap mode */
+ glBindTexture(GL_TEXTURE_2D, diffuse1_tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glBindTexture(GL_TEXTURE_2D, diffuse2_tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+
+ glBindTexture(GL_TEXTURE_2D, detail_tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+}
+
+
+void
+TerrainRenderer::init_program()
+{
+ ShaderSource vtx_shader(GLMARK_DATA_PATH"/shaders/terrain.vert");
+ ShaderSource frg_shader(GLMARK_DATA_PATH"/shaders/terrain.frag");
+
+ if (!Scene::load_shaders_from_strings(program_, vtx_shader.str(), frg_shader.str()))
+ return;
+
+ program_.start();
+ /* Fog */
+ program_["fogDensity"] = 0.00025f;
+ program_["fogNear"] = 1.0f;
+ program_["fogFar"] = 2000.0f;
+ program_["fogColor"] = LibMatrix::vec3(0.825, 0.7425, 0.61875);
+
+ /* Lights */
+ program_["ambientLightColor"] = color_to_vec3(0xffffff);
+
+ program_["pointLightColor[0]"] = color_to_vec3(0xffffff);
+ program_["pointLightPosition[0]"] = LibMatrix::vec3(0.0, 0.0, 0.0);
+ program_["pointLightDistance[0]"] = 0.0f;
+
+ /* Textures */
+ program_["tDiffuse1"] = 0;
+ program_["tDiffuse2"] = 1;
+ program_["tDetail"] = 2;
+ program_["tNormal"] = 3;
+ program_["tSpecular"] = 4;
+ program_["tDisplacement"] = 5;
+
+ program_["uNormalScale"] = 3.5f;
+
+ program_["uDisplacementBias"] = 0.0f;
+ program_["uDisplacementScale"] = 375.0f;
+
+ program_["uDiffuseColor"] = color_to_vec3(0xffffff);
+ program_["uSpecularColor"] = color_to_vec3(0xffffff);
+ program_["uAmbientColor"] = color_to_vec3(0x888888);
+ program_["uShininess"] = 30.0f;
+ program_["uOpacity"] = 1.0f;
+
+ program_["uRepeatOverlay"] = repeat_overlay_;
+
+ program_["uOffset"] = LibMatrix::vec2(0.0, 0.0);
+
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ attrib_locations.push_back(program_["normal"].location());
+ attrib_locations.push_back(program_["tangent"].location());
+ attrib_locations.push_back(program_["uv"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ program_.stop();
+}
+
+void
+TerrainRenderer::bind_textures()
+{
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, diffuse1_tex_);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, diffuse2_tex_);
+
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, detail_tex_);
+
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, normal_map_tex_);
+
+ glActiveTexture(GL_TEXTURE4);
+ glBindTexture(GL_TEXTURE_2D, specular_map_tex_);
+
+ glActiveTexture(GL_TEXTURE5);
+ glBindTexture(GL_TEXTURE_2D, height_map_tex_);
+}
+
+void
+TerrainRenderer::deinit_textures()
+{
+ glDeleteTextures(1, &diffuse1_tex_);
+ glDeleteTextures(1, &diffuse2_tex_);
+ glDeleteTextures(1, &detail_tex_);
+}
+
+static void
+grid_conf(Mesh &mesh, int x, int y, int n_x, int n_y,
+ LibMatrix::vec3 &ul,
+ LibMatrix::vec3 &ll,
+ LibMatrix::vec3 &ur,
+ LibMatrix::vec3 &lr)
+{
+ struct PlaneMeshVertex {
+ LibMatrix::vec3 position;
+ LibMatrix::vec2 texcoord;
+ LibMatrix::vec3 normal;
+ LibMatrix::vec3 tangent;
+ };
+
+ LibMatrix::vec2 uv_ul(static_cast<float>(x) / n_x,
+ 1.0 - static_cast<float>(y) / n_y);
+ LibMatrix::vec2 uv_lr(static_cast<float>(x + 1) / n_x,
+ 1.0 - static_cast<float>(y + 1) / n_y);
+
+ LibMatrix::vec3 normal(0.0, 0.0, 1.0);
+ LibMatrix::vec3 tangent(1.0, 0.0, 0.0);
+
+ PlaneMeshVertex cell_vertices[] = {
+ {
+ ll,
+ LibMatrix::vec2(uv_ul.x(), uv_lr.y()),
+ normal,
+ tangent
+ },
+ {
+ lr,
+ LibMatrix::vec2(uv_lr.x(), uv_lr.y()),
+ normal,
+ tangent
+ },
+ {
+ ur,
+ LibMatrix::vec2(uv_lr.x(), uv_ul.y()),
+ normal,
+ tangent
+ },
+ {
+ ul,
+ LibMatrix::vec2(uv_ul.x(), uv_ul.y()),
+ normal,
+ tangent
+ }
+ };
+
+ unsigned int vertex_index[] = {0, 1, 2, 0, 2, 3};
+
+ for (size_t i = 0; i < sizeof(vertex_index) / sizeof(*vertex_index); i++) {
+ PlaneMeshVertex& vertex = cell_vertices[vertex_index[i]];
+
+ mesh.next_vertex();
+ mesh.set_attrib(0, vertex.position);
+ mesh.set_attrib(1, vertex.normal);
+ mesh.set_attrib(2, vertex.tangent);
+ mesh.set_attrib(3, vertex.texcoord);
+ }
+}
+
+void
+TerrainRenderer::create_mesh()
+{
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3);
+ vertex_format.push_back(3);
+ vertex_format.push_back(3);
+ vertex_format.push_back(2);
+ mesh_.set_vertex_format(vertex_format);
+
+ mesh_.make_grid(256, 256, 6000, 6000, 0, grid_conf);
+ mesh_.build_vbo();
+}
+
=== added file 'src/scene-terrain/texture-renderer.cpp'
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2012 Linaro Limited
+ *
+ * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
+ *
+ * glmark2 is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later
+ * version.
+ *
+ * glmark2 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 General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * glmark2. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis
+ */
+#include "renderer.h"
+
+TextureRenderer::TextureRenderer(const LibMatrix::vec2 &size, Program &program) :
+ BaseRenderer(size), program_(program)
+{
+ /* Create the mesh (quad) used for rendering */
+ create_mesh();
+}
+
+void
+TextureRenderer::create_mesh()
+{
+ // Set vertex format
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3); // Position
+ mesh_.set_vertex_format(vertex_format);
+
+ mesh_.make_grid(1, 1, 2.0, 2.0, 0);
+ mesh_.build_vbo();
+
+ program_.start();
+
+ // Set attribute locations
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(program_["position"].location());
+ mesh_.set_attrib_locations(attrib_locations);
+
+ program_.stop();
+}
+
+void
+TextureRenderer::render()
+{
+ make_current();
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, input_texture_);
+
+ program_.start();
+
+ mesh_.render_vbo();
+
+ program_.stop();
+
+ update_mipmap();
+}
=== modified file 'src/scene.h'
@@ -504,4 +504,24 @@
SceneIdeasPrivate* priv_;
};
+class SceneTerrainPrivate;
+
+class SceneTerrain : public Scene
+{
+public:
+ SceneTerrain(Canvas &pCanvas);
+ bool load();
+ void unload();
+ void setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~SceneTerrain();
+
+private:
+ SceneTerrainPrivate* priv_;
+};
+
#endif
=== modified file 'src/wscript_build'
@@ -1,11 +1,11 @@
-all_sources = bld.path.ant_glob('*.cpp')
+all_sources = bld.path.ant_glob('*.cpp scene-ideas/*.cc scene-terrain/*.cpp')
common_sources = [f for f in all_sources if f.name.find('canvas-') == -1 and
f.name.find('android') == -1 ]
gl_sources = ['canvas-x11.cpp', 'canvas-x11-glx.cpp']
glesv2_sources = ['canvas-x11.cpp', 'canvas-x11-egl.cpp']
libmatrix_sources = [f for f in bld.path.ant_glob('libmatrix/*.cc')
if not f.name.endswith('test.cc')]
-ideas_sources = bld.path.ant_glob('scene-ideas/*.cc')
+includes = ['.', 'scene-ideas', 'scene-terrain']
if bld.env.USE_GL:
bld(
@@ -19,11 +19,11 @@
)
bld(
features = ['cxx', 'cprogram'],
- source = ideas_sources + common_sources + gl_sources,
+ source = common_sources + gl_sources,
target = 'glmark2',
use = ['x11', 'gl', 'matrix', 'libpng12'],
lib = ['m', 'jpeg'],
- includes = ['.', 'scene-ideas'],
+ includes = includes,
defines = ['USE_GL', 'USE_EXCEPTIONS']
)
@@ -39,10 +39,10 @@
)
bld(
features = ['cxx', 'cprogram'],
- source = ideas_sources + common_sources + glesv2_sources,
+ source = common_sources + glesv2_sources,
target = 'glmark2-es2',
use = ['x11', 'egl', 'glesv2', 'matrix-es2', 'libpng12'],
lib = ['m', 'dl', 'jpeg'],
- includes = ['.', 'scene-ideas'],
+ includes = includes,
defines = ['USE_GLESv2', 'USE_EXCEPTIONS']
)