From patchwork Wed Jul 4 10:29:10 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 9819 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 55F5D23E23 for ; Wed, 4 Jul 2012 10:29:15 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id D18C3A18025 for ; Wed, 4 Jul 2012 10:29:14 +0000 (UTC) Received: by yenq6 with SMTP id q6so6804558yen.11 for ; Wed, 04 Jul 2012 03:29:14 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :content-type:mime-version:x-launchpad-project:x-launchpad-branch :x-launchpad-message-rationale:x-launchpad-branch-revision-number :x-launchpad-notification-type:to:from:subject:message-id:date :reply-to:sender:errors-to:precedence:x-generated-by :x-launchpad-hash:x-gm-message-state; bh=if7LqMD6gblVDx4yXi9/52F71w7cLsCGyTrlvrWlHQ0=; b=S+We80oWCsEaC7mivXZR4jX9wm73CAAg3sWNmztUX3fWqpO+cxwXo1na2umaPzxxTb PCT2uRw5Fs/K/N1nV/hAkzTrez61n3WjzIGb8/LJcu1wZ/udQ8nres/UwnQASsjorDrE F+I8SJK9YDCne8nybBo1NMV6nP4gFZ7X1/wTJ8p/w3yFbR5ubBSVZDGMaU09kU3Hl7yu 35L7jJWMjO+ZuG+MDzAEEGL08laPOzcq1MSblqp2dKEyqSu/kDwxjS/zwaSNg/ybrcF+ 6itQdX5YQxATUS5KRTS6jsJ8SsGUbQbnV/zfjlhZr1cxi+9vkQiWi/Kq4wUs4BmJltid qUQw== Received: by 10.50.57.167 with SMTP id j7mr10825476igq.53.1341397753951; Wed, 04 Jul 2012 03:29:13 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.231.24.148 with SMTP id v20csp52031ibb; Wed, 4 Jul 2012 03:29:11 -0700 (PDT) Received: by 10.216.201.79 with SMTP id a57mr5330632weo.164.1341397751202; Wed, 04 Jul 2012 03:29:11 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id g20si19102885wem.88.2012.07.04.03.29.10 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 04 Jul 2012 03:29:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1SmMpa-0004pT-K6 for ; Wed, 04 Jul 2012 10:29:10 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 8841AE00AA for ; Wed, 4 Jul 2012 10:29:10 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 229 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 229: SceneTerrain: Add scene based on WebGL dynamic terrain demo. Message-Id: <20120704102910.10897.47392.launchpad@ackee.canonical.com> Date: Wed, 04 Jul 2012 10:29:10 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="15544"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: a507d2333b94192218c37bf810fc11d330b39ce7 X-Gm-Message-State: ALoCoQm0L7+WijCW+Lky0ufJ0hYP9zUVyaPzaHu8cij15Y0jy95YMYUJe+u3QwbLG+xmGkkczDc5 Merge authors: Alexandros Frantzis (afrantzis) Related merge proposals: https://code.launchpad.net/~linaro-graphics-wg/glmark2/scene-terrain/+merge/113185 proposed by: Alexandros Frantzis (afrantzis) review: Approve - Jesse Barker (jesse-barker) ------------------------------------------------------------ revno: 229 [merge] committer: Alexandros Frantzis branch nick: trunk timestamp: Wed 2012-07-04 13:20:52 +0300 message: SceneTerrain: Add scene based on WebGL dynamic terrain demo. added: data/shaders/terrain-blur.frag data/shaders/terrain-luminance.frag data/shaders/terrain-noise.frag data/shaders/terrain-normalmap.frag data/shaders/terrain-overlay.frag data/shaders/terrain-texture.vert data/shaders/terrain.frag data/shaders/terrain.vert data/textures/terrain-backgrounddetailed6.jpg data/textures/terrain-grasslight-512-nm.jpg data/textures/terrain-grasslight-512.jpg src/scene-terrain/ src/scene-terrain.cpp src/scene-terrain/base-renderer.cpp src/scene-terrain/blur-renderer.cpp src/scene-terrain/copy-renderer.cpp src/scene-terrain/luminance-renderer.cpp src/scene-terrain/normal-from-height-renderer.cpp src/scene-terrain/overlay-renderer.cpp src/scene-terrain/renderer-chain.cpp src/scene-terrain/renderer.h src/scene-terrain/simplex-noise-renderer.cpp src/scene-terrain/terrain-renderer.cpp src/scene-terrain/texture-renderer.cpp modified: android/jni/Android.mk android/jni/Android.ndk.mk src/android.cpp src/main.cpp src/scene.h src/wscript_build --- 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 === modified file 'android/jni/Android.mk' --- android/jni/Android.mk 2012-06-27 08:13:50 +0000 +++ android/jni/Android.mk 2012-06-29 12:27:16 +0000 @@ -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' --- android/jni/Android.ndk.mk 2012-06-27 08:13:50 +0000 +++ android/jni/Android.ndk.mk 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain-blur.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain-blur.frag 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain-luminance.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain-luminance.frag 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain-noise.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain-noise.frag 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain-normalmap.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain-normalmap.frag 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain-overlay.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain-overlay.frag 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain-texture.vert 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain-texture.vert 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain.frag 2012-06-29 12:27:16 +0000 @@ -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' --- data/shaders/terrain.vert 1970-01-01 00:00:00 +0000 +++ data/shaders/terrain.vert 2012-06-29 12:27:16 +0000 @@ -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' --- src/android.cpp 2012-06-15 13:24:32 +0000 +++ src/android.cpp 2012-06-29 12:27:16 +0000 @@ -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' --- src/main.cpp 2012-05-15 08:40:46 +0000 +++ src/main.cpp 2012-06-29 12:27:16 +0000 @@ -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::const_iterator iter = scenes.begin(); iter != scenes.end(); === added directory 'src/scene-terrain' === added file 'src/scene-terrain.cpp' --- src/scene-terrain.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain.cpp 2012-07-03 09:56:14 +0000 @@ -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 . + * + * 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(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(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' --- src/scene-terrain/base-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/base-renderer.cpp 2012-07-04 10:14:08 +0000 @@ -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 . + * + * 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' --- src/scene-terrain/blur-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/blur-renderer.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * 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(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(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(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(i - radius); + for (unsigned int j = 0; j < side; j++) { + int joffset = static_cast(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' --- src/scene-terrain/copy-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/copy-renderer.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * 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' --- src/scene-terrain/luminance-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/luminance-renderer.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * 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' --- src/scene-terrain/normal-from-height-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/normal-from-height-renderer.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * 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' --- src/scene-terrain/overlay-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/overlay-renderer.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * 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(size); + static_cast(onscreen); + static_cast(has_depth); +} + +void +OverlayRenderer::setup_texture(GLint min_filter, GLint mag_filter, + GLint wrap_s, GLint wrap_t) +{ + static_cast(min_filter); + static_cast(mag_filter); + static_cast(wrap_s); + static_cast(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 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 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' --- src/scene-terrain/renderer-chain.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/renderer-chain.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + */ +#include "renderer.h" + +void +RendererChain::setup(const LibMatrix::vec2 &size, bool onscreen, bool has_depth) +{ + static_cast(size); + static_cast(onscreen); + static_cast(has_depth); +} + +void +RendererChain::setup_texture(GLint min_filter, GLint mag_filter, + GLint wrap_s, GLint wrap_t) +{ + static_cast(min_filter); + static_cast(mag_filter); + static_cast(wrap_s); + static_cast(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::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' --- src/scene-terrain/renderer.h 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/renderer.h 2012-06-29 12:46:57 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + */ +#include + +#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 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' --- src/scene-terrain/simplex-noise-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/simplex-noise-renderer.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * 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' --- src/scene-terrain/terrain-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/terrain-renderer.cpp 2012-06-29 12:46:57 +0000 @@ -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 . + * + * 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 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(x) / n_x, + 1.0 - static_cast(y) / n_y); + LibMatrix::vec2 uv_lr(static_cast(x + 1) / n_x, + 1.0 - static_cast(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 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' --- src/scene-terrain/texture-renderer.cpp 1970-01-01 00:00:00 +0000 +++ src/scene-terrain/texture-renderer.cpp 2012-06-29 12:27:16 +0000 @@ -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 . + * + * 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 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 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' --- src/scene.h 2012-05-15 12:46:43 +0000 +++ src/scene.h 2012-06-29 12:27:16 +0000 @@ -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' --- src/wscript_build 2012-06-25 11:40:03 +0000 +++ src/wscript_build 2012-06-29 12:27:16 +0000 @@ -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'] )