Merge lp:~linaro-graphics-wg/glmark2/desktop into lp:glmark2/2011.11

Proposed by Alexandros Frantzis
Status: Merged
Merged at revision: 130
Proposed branch: lp:~linaro-graphics-wg/glmark2/desktop
Merge into: lp:glmark2/2011.11
Diff against target: 958 lines (+848/-8)
9 files modified
data/shaders/desktop-blur.frag (+17/-0)
data/shaders/desktop.frag (+14/-0)
data/shaders/desktop.vert (+11/-0)
src/android.cpp (+2/-0)
src/canvas-android.cpp (+2/-2)
src/canvas-x11.cpp (+6/-6)
src/main.cpp (+2/-0)
src/scene-desktop.cpp (+775/-0)
src/scene.h (+19/-0)
To merge this branch: bzr merge lp:~linaro-graphics-wg/glmark2/desktop
Reviewer Review Type Date Requested Status
Jesse Barker Pending
Review via email: mp+75039@code.launchpad.net

Description of the change

New "desktop" benchmarking scene and one effect (blur).

To post a comment you must log in.
Revision history for this message
Jesse Barker (jesse-barker) wrote :
Download full text (31.3 KiB)

Overall, looks really good. I like it. A few very small nits inline,
none of which should hold up the merge (and are all optional)...

On Mon, Sep 12, 2011 at 9:40 AM, Alexandros Frantzis <email address hidden> wrote:
> Alexandros Frantzis has proposed merging lp:~linaro-graphics-wg/glmark2/desktop into lp:glmark2.
>
> Requested reviews:
>  Jesse Barker (jesse-barker)
>
> For more details, see:
> https://code.launchpad.net/~linaro-graphics-wg/glmark2/desktop/+merge/75039
>
> New "desktop" benchmarking scene and one effect (blur).
> --
> https://code.launchpad.net/~linaro-graphics-wg/glmark2/desktop/+merge/75039
> You are requested to review the proposed merge of lp:~linaro-graphics-wg/glmark2/desktop into lp:glmark2.
>
> === added file 'data/shaders/desktop-blur.frag'
> --- data/shaders/desktop-blur.frag      1970-01-01 00:00:00 +0000
> +++ data/shaders/desktop-blur.frag      2011-09-12 16:40:37 +0000
> @@ -0,0 +1,17 @@
> +#ifdef GL_ES
> +precision mediump float;
> +#endif
> +
> +uniform sampler2D Texture0;
> +
> +varying vec2 TextureCoord;
> +
> +void main(void)
> +{
> +    vec4 result;
> +
> +    $CONVOLUTION$
> +
> +    gl_FragColor = result;
> +}
> +
>
> === added file 'data/shaders/desktop.frag'
> --- data/shaders/desktop.frag   1970-01-01 00:00:00 +0000
> +++ data/shaders/desktop.frag   2011-09-12 16:40:37 +0000
> @@ -0,0 +1,14 @@
> +#ifdef GL_ES
> +precision mediump float;
> +#endif
> +
> +uniform sampler2D MaterialTexture0;
> +
> +varying vec2 TextureCoord;
> +
> +void main(void)
> +{
> +    vec4 texel = texture2D(MaterialTexture0, TextureCoord);
> +    gl_FragColor = texel;
> +}
> +
>
> === added file 'data/shaders/desktop.vert'
> --- data/shaders/desktop.vert   1970-01-01 00:00:00 +0000
> +++ data/shaders/desktop.vert   2011-09-12 16:40:37 +0000
> @@ -0,0 +1,11 @@
> +attribute vec2 position;
> +attribute vec2 texcoord;
> +
> +varying vec2 TextureCoord;
> +
> +void main(void)
> +{
> +    gl_Position = vec4(position, 0.0, 1.0);
> +
> +    TextureCoord = texcoord;
> +}
>
> === added file 'data/textures/desktop-window.png'
> Binary files data/textures/desktop-window.png   1970-01-01 00:00:00 +0000 and data/textures/desktop-window.png  2011-09-12 16:40:37 +0000 differ
> === modified file 'src/android.cpp'
> --- src/android.cpp     2011-08-18 15:03:40 +0000
> +++ src/android.cpp     2011-09-12 16:40:37 +0000
> @@ -44,6 +44,7 @@
>     "effect2d:kernel=0,1,0;1,-4,1;0,1,0;",
>     "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",
>     "pulsar:quads=5:texture=false:light=false",
> +    "desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true",
>     "conditionals:vertex-steps=0:fragment-steps=0",
>     "conditionals:vertex-steps=0:fragment-steps=5",
>     "conditionals:vertex-steps=5:fragment-steps=0",
> @@ -85,6 +86,7 @@
>     Benchmark::register_scene(*new SceneBump(*g_canvas));
>     Benchmark::register_scene(*new SceneEffect2D(*g_canvas));
>     Benchmark::register_scene(*new ScenePulsar(*g_canvas));
> +    Benchmark::register_scene(*new SceneDesktop(canvas));
>
>     add_default_benchmarks(g_benchmarks);
>
>
> === modified file 'src/canvas-android.cpp'
> --- src/canvas-android.cpp      2011-08-10 18:00:03 +0000
> +++ src/canv...

139. By Alexandros Frantzis

SceneDesktop: Set texture and fbo variables to 0 after deleting their resources.

140. By Alexandros Frantzis

SceneDesktop: Code cleanup.

Revision history for this message
Alexandros Frantzis (afrantzis) wrote :

> > +protected:
> > +    void draw_quad_with_program(const GLfloat *position, const GLfloat
> *texcoord,
> > +                                Program &program)
>
> Why not make this take "const vector<vec2>& position" and "const
> vector<vec2>& texcoord"? Works just fine with the GL interfaces....

The reasons I am not keen on this are:

1. Currently (ie not C++11) there is no simple way to initialize a static const std::vector.
2. Due to the way the vector is going to be used in the function (&vector[0]), all safety benefits of using std::vector are essentially lost.
3. We don't really need a variable-size container in this case.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/shaders/desktop-blur.frag'
--- data/shaders/desktop-blur.frag 1970-01-01 00:00:00 +0000
+++ data/shaders/desktop-blur.frag 2011-09-13 09:41:05 +0000
@@ -0,0 +1,17 @@
1#ifdef GL_ES
2precision mediump float;
3#endif
4
5uniform sampler2D Texture0;
6
7varying vec2 TextureCoord;
8
9void main(void)
10{
11 vec4 result;
12
13 $CONVOLUTION$
14
15 gl_FragColor = result;
16}
17
018
=== added file 'data/shaders/desktop.frag'
--- data/shaders/desktop.frag 1970-01-01 00:00:00 +0000
+++ data/shaders/desktop.frag 2011-09-13 09:41:05 +0000
@@ -0,0 +1,14 @@
1#ifdef GL_ES
2precision mediump float;
3#endif
4
5uniform sampler2D MaterialTexture0;
6
7varying vec2 TextureCoord;
8
9void main(void)
10{
11 vec4 texel = texture2D(MaterialTexture0, TextureCoord);
12 gl_FragColor = texel;
13}
14
015
=== added file 'data/shaders/desktop.vert'
--- data/shaders/desktop.vert 1970-01-01 00:00:00 +0000
+++ data/shaders/desktop.vert 2011-09-13 09:41:05 +0000
@@ -0,0 +1,11 @@
1attribute vec2 position;
2attribute vec2 texcoord;
3
4varying vec2 TextureCoord;
5
6void main(void)
7{
8 gl_Position = vec4(position, 0.0, 1.0);
9
10 TextureCoord = texcoord;
11}
012
=== added file 'data/textures/desktop-window.png'
1Binary files data/textures/desktop-window.png 1970-01-01 00:00:00 +0000 and data/textures/desktop-window.png 2011-09-13 09:41:05 +0000 differ13Binary files data/textures/desktop-window.png 1970-01-01 00:00:00 +0000 and data/textures/desktop-window.png 2011-09-13 09:41:05 +0000 differ
=== modified file 'src/android.cpp'
--- src/android.cpp 2011-08-18 15:03:40 +0000
+++ src/android.cpp 2011-09-13 09:41:05 +0000
@@ -44,6 +44,7 @@
44 "effect2d:kernel=0,1,0;1,-4,1;0,1,0;",44 "effect2d:kernel=0,1,0;1,-4,1;0,1,0;",
45 "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",45 "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",
46 "pulsar:quads=5:texture=false:light=false",46 "pulsar:quads=5:texture=false:light=false",
47 "desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true",
47 "conditionals:vertex-steps=0:fragment-steps=0",48 "conditionals:vertex-steps=0:fragment-steps=0",
48 "conditionals:vertex-steps=0:fragment-steps=5",49 "conditionals:vertex-steps=0:fragment-steps=5",
49 "conditionals:vertex-steps=5:fragment-steps=0",50 "conditionals:vertex-steps=5:fragment-steps=0",
@@ -85,6 +86,7 @@
85 Benchmark::register_scene(*new SceneBump(*g_canvas));86 Benchmark::register_scene(*new SceneBump(*g_canvas));
86 Benchmark::register_scene(*new SceneEffect2D(*g_canvas));87 Benchmark::register_scene(*new SceneEffect2D(*g_canvas));
87 Benchmark::register_scene(*new ScenePulsar(*g_canvas));88 Benchmark::register_scene(*new ScenePulsar(*g_canvas));
89 Benchmark::register_scene(*new SceneDesktop(canvas));
8890
89 add_default_benchmarks(g_benchmarks);91 add_default_benchmarks(g_benchmarks);
9092
9193
=== modified file 'src/canvas-android.cpp'
--- src/canvas-android.cpp 2011-08-10 18:00:03 +0000
+++ src/canvas-android.cpp 2011-09-13 09:41:05 +0000
@@ -35,8 +35,6 @@
35 if (!eglSwapInterval(eglGetCurrentDisplay(), 0))35 if (!eglSwapInterval(eglGetCurrentDisplay(), 0))
36 Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");36 Log::info("** Failed to set swap interval. Results may be bounded above by refresh rate.\n");
3737
38 glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
39 glClearDepthf(1.0f);
40 glEnable(GL_DEPTH_TEST);38 glEnable(GL_DEPTH_TEST);
41 glDepthFunc(GL_LEQUAL);39 glDepthFunc(GL_LEQUAL);
42 glEnable(GL_CULL_FACE);40 glEnable(GL_CULL_FACE);
@@ -56,6 +54,8 @@
56void54void
57CanvasAndroid::clear()55CanvasAndroid::clear()
58{56{
57 glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
58 glClearDepthf(1.0f);
59 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);59 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
60}60}
6161
6262
=== modified file 'src/canvas-x11.cpp'
--- src/canvas-x11.cpp 2011-08-09 10:51:03 +0000
+++ src/canvas-x11.cpp 2011-09-13 09:41:05 +0000
@@ -84,12 +84,6 @@
84 if (!make_current())84 if (!make_current())
85 return false;85 return false;
8686
87 glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
88#if USE_GL
89 glClearDepth(1.0f);
90#elif USE_GLESv2
91 glClearDepthf(1.0f);
92#endif
93 glEnable(GL_DEPTH_TEST);87 glEnable(GL_DEPTH_TEST);
94 glDepthFunc(GL_LEQUAL);88 glDepthFunc(GL_LEQUAL);
95 glEnable(GL_CULL_FACE);89 glEnable(GL_CULL_FACE);
@@ -110,6 +104,12 @@
110void104void
111CanvasX11::clear()105CanvasX11::clear()
112{106{
107 glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
108#if USE_GL
109 glClearDepth(1.0f);
110#elif USE_GLESv2
111 glClearDepthf(1.0f);
112#endif
113 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);113 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
114}114}
115115
116116
=== modified file 'src/main.cpp'
--- src/main.cpp 2011-09-07 09:40:57 +0000
+++ src/main.cpp 2011-09-13 09:41:05 +0000
@@ -54,6 +54,7 @@
54 "effect2d:kernel=0,1,0;1,-4,1;0,1,0;",54 "effect2d:kernel=0,1,0;1,-4,1;0,1,0;",
55 "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",55 "effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",
56 "pulsar:quads=5:texture=false:light=false",56 "pulsar:quads=5:texture=false:light=false",
57 "desktop:windows=4:effect=blur:blur-radius=5:passes=1:separable=true",
57 "conditionals:vertex-steps=0:fragment-steps=0",58 "conditionals:vertex-steps=0:fragment-steps=0",
58 "conditionals:vertex-steps=0:fragment-steps=5",59 "conditionals:vertex-steps=0:fragment-steps=5",
59 "conditionals:vertex-steps=5:fragment-steps=0",60 "conditionals:vertex-steps=5:fragment-steps=0",
@@ -96,6 +97,7 @@
96 scenes.push_back(new SceneBump(canvas));97 scenes.push_back(new SceneBump(canvas));
97 scenes.push_back(new SceneEffect2D(canvas));98 scenes.push_back(new SceneEffect2D(canvas));
98 scenes.push_back(new ScenePulsar(canvas));99 scenes.push_back(new ScenePulsar(canvas));
100 scenes.push_back(new SceneDesktop(canvas));
99101
100 for (vector<Scene*>::const_iterator iter = scenes.begin();102 for (vector<Scene*>::const_iterator iter = scenes.begin();
101 iter != scenes.end();103 iter != scenes.end();
102104
=== added file 'src/scene-desktop.cpp'
--- src/scene-desktop.cpp 1970-01-01 00:00:00 +0000
+++ src/scene-desktop.cpp 2011-09-13 09:41:05 +0000
@@ -0,0 +1,775 @@
1/*
2 * Copyright © 2010-2011 Linaro Limited
3 *
4 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
5 *
6 * glmark2 is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
9 * version.
10 *
11 * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14 * details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * glmark2. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors:
20 * Alexandros Frantzis (glmark2)
21 */
22#include <cmath>
23
24#include "scene.h"
25#include "mat.h"
26#include "stack.h"
27#include "vec.h"
28#include "log.h"
29#include "program.h"
30#include "shader-source.h"
31#include "util.h"
32
33enum BlurDirection {
34 BlurDirectionHorizontal,
35 BlurDirectionVertical,
36 BlurDirectionBoth
37};
38
39static void
40create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source,
41 unsigned int radius, float sigma, BlurDirection direction)
42{
43 vtx_source.append_file(GLMARK_DATA_PATH"/shaders/desktop.vert");
44 frg_source.append_file(GLMARK_DATA_PATH"/shaders/desktop-blur.frag");
45
46 /* Don't let the gaussian curve become too narrow */
47 if (sigma < 1.0)
48 sigma = 1.0;
49
50 unsigned int side = 2 * radius + 1;
51
52 for (size_t i = 0; i < radius + 1; i++) {
53 float s2 = 2.0 * sigma * sigma;
54 float k = 1.0 / std::sqrt(M_PI * s2) * std::exp( - ((float)i * i) / s2);
55 std::stringstream ss_tmp;
56 ss_tmp << "Kernel" << i;
57 frg_source.add_const(ss_tmp.str(), k);
58 }
59
60 std::stringstream ss;
61 ss << "result = " << std::endl;
62
63 if (direction == BlurDirectionHorizontal) {
64 for (size_t i = 0; i < side; i++) {
65 int offset = (int)(i - radius);
66 ss << "texture2D(Texture0, TextureCoord + vec2(" <<
67 offset << ".0 * TextureStepX, 0.0)) * Kernel" <<
68 std::abs(offset) << " +" << std::endl;
69 }
70 ss << "0.0 ;" << std::endl;
71 }
72 else if (direction == BlurDirectionVertical) {
73 for (size_t i = 0; i < side; i++) {
74 int offset = (int)(i - radius);
75 ss << "texture2D(Texture0, TextureCoord + vec2(0.0, " <<
76 offset << ".0 * TextureStepY)) * Kernel" <<
77 std::abs(offset) << " +" << std::endl;
78 }
79 ss << "0.0 ;" << std::endl;
80 }
81 else if (direction == BlurDirectionBoth) {
82 for (size_t i = 0; i < side; i++) {
83 int ioffset = (int)(i - radius);
84 for (size_t j = 0; j < side; j++) {
85 int joffset = (int)(j - radius);
86 ss << "texture2D(Texture0, TextureCoord + vec2(" <<
87 ioffset << ".0 * TextureStepX, " <<
88 joffset << ".0 * TextureStepY))" <<
89 " * Kernel" << std::abs(ioffset) <<
90 " * Kernel" << std::abs(joffset) << " +" << std::endl;
91 }
92 }
93 ss << " 0.0;" << std::endl;
94 }
95
96 frg_source.replace("$CONVOLUTION$", ss.str());
97}
98
99/**
100 * A RenderObject represents a source and target of rendering
101 * operations.
102 */
103class RenderObject
104{
105public:
106 RenderObject() : texture_(0), fbo_(0) { }
107
108 virtual ~RenderObject() { release(); }
109
110 virtual void init()
111 {
112 /* Create a texture to draw to */
113 glGenTextures(1, &texture_);
114 glBindTexture(GL_TEXTURE_2D, texture_);
115 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
116 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
117 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
118 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
119 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
120 GL_RGBA, GL_UNSIGNED_BYTE, 0);
121
122 /* Create a FBO */
123 glGenFramebuffers(1, &fbo_);
124 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
125 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
126 GL_TEXTURE_2D, texture_, 0);
127
128 glBindFramebuffer(GL_FRAMEBUFFER, 0);
129
130 /* Load the shader program when this class if first used */
131 if (RenderObject::use_count == 0) {
132 ShaderSource vtx_source(GLMARK_DATA_PATH"/shaders/desktop.vert");
133 ShaderSource frg_source(GLMARK_DATA_PATH"/shaders/desktop.frag");
134 Scene::load_shaders_from_strings(main_program, vtx_source.str(),
135 frg_source.str());
136 }
137
138 RenderObject::use_count++;
139 }
140
141 virtual void release()
142 {
143 /* Release resources */
144 glDeleteTextures(1, &texture_);
145 glDeleteFramebuffers(1, &fbo_);
146 texture_ = 0;
147 fbo_ = 0;
148
149 /*
150 * Release the shader program when object of this class
151 * are no longer in use.
152 */
153 RenderObject::use_count--;
154 if (RenderObject::use_count == 0)
155 RenderObject::main_program.release();
156 }
157
158 void make_current()
159 {
160 glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
161 glViewport(0, 0, size_.x(), size_.y());
162 }
163
164 void position(const LibMatrix::vec2& pos) { pos_ = pos; }
165 const LibMatrix::vec2& position() { return pos_; }
166
167
168 virtual void size(const LibMatrix::vec2& size)
169 {
170 /* Recreate the backing texture with correct size */
171 if (size_.x() != size.x() || size_.y() != size.y()) {
172 size_ = size;
173 glBindTexture(GL_TEXTURE_2D, texture_);
174 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0,
175 GL_RGBA, GL_UNSIGNED_BYTE, 0);
176 clear();
177 }
178 }
179
180 const LibMatrix::vec2& size() { return size_; }
181
182 const LibMatrix::vec2& speed() { return speed_; }
183 void speed(const LibMatrix::vec2& speed) { speed_ = speed; }
184
185 GLuint texture() { return texture_; }
186
187 virtual void clear()
188 {
189 make_current();
190 glClear(GL_COLOR_BUFFER_BIT);
191 }
192
193 virtual void render_to(RenderObject& target, Program& program = main_program)
194 {
195 LibMatrix::vec2 final_pos(pos_ + size_);
196 LibMatrix::vec2 ll(target.normalize_position(pos_));
197 LibMatrix::vec2 ur(target.normalize_position(final_pos));
198
199 GLfloat position[2 * 4] = {
200 ll.x(), ll.y(),
201 ur.x(), ll.y(),
202 ll.x(), ur.y(),
203 ur.x(), ur.y(),
204 };
205
206 static const GLfloat texcoord[2 * 4] = {
207 0.0, 0.0,
208 1.0, 0.0,
209 0.0, 1.0,
210 1.0, 1.0,
211 };
212
213 target.make_current();
214
215 glActiveTexture(GL_TEXTURE0);
216 glBindTexture(GL_TEXTURE_2D, texture_);
217 draw_quad_with_program(position, texcoord, program);
218 }
219
220 virtual void render_from(RenderObject& target, Program& program = main_program)
221 {
222 LibMatrix::vec2 final_pos(pos_ + size_);
223 LibMatrix::vec2 ll_tex(target.normalize_texcoord(pos_));
224 LibMatrix::vec2 ur_tex(target.normalize_texcoord(final_pos));
225
226 static const GLfloat position_blur[2 * 4] = {
227 -1.0, -1.0,
228 1.0, -1.0,
229 -1.0, 1.0,
230 1.0, 1.0,
231 };
232 GLfloat texcoord_blur[2 * 4] = {
233 ll_tex.x(), ll_tex.y(),
234 ur_tex.x(), ll_tex.y(),
235 ll_tex.x(), ur_tex.y(),
236 ur_tex.x(), ur_tex.y(),
237 };
238
239 make_current();
240 glBindTexture(GL_TEXTURE_2D, target.texture());
241 draw_quad_with_program(position_blur, texcoord_blur, program);
242 }
243
244 /**
245 * Normalizes a position from [0, size] to [-1.0, 1.0]
246 */
247 LibMatrix::vec2 normalize_position(LibMatrix::vec2& pos)
248 {
249 return LibMatrix::vec2(2.0 * pos.x() / size_.x() - 1.0,
250 2.0 * pos.y() / size_.y() - 1.0);
251 }
252
253 /**
254 * Normalizes a position from [0, size] to [0.0, 1.0]
255 */
256 LibMatrix::vec2 normalize_texcoord(LibMatrix::vec2& pos)
257 {
258 return LibMatrix::vec2(pos.x() / size_.x(),
259 pos.y() / size_.y());
260 }
261
262
263protected:
264 void draw_quad_with_program(const GLfloat *position, const GLfloat *texcoord,
265 Program &program)
266 {
267 int pos_index = program["position"].location();
268 int tex_index = program["texcoord"].location();
269
270 program.start();
271
272 glEnableVertexAttribArray(pos_index);
273 glEnableVertexAttribArray(tex_index);
274 glVertexAttribPointer(pos_index, 2,
275 GL_FLOAT, GL_FALSE, 0, position);
276 glVertexAttribPointer(tex_index, 2,
277 GL_FLOAT, GL_FALSE, 0, texcoord);
278
279 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
280
281 glDisableVertexAttribArray(tex_index);
282 glDisableVertexAttribArray(pos_index);
283
284 program.stop();
285 }
286
287 static Program main_program;
288
289 LibMatrix::vec2 pos_;
290 LibMatrix::vec2 size_;
291 LibMatrix::vec2 speed_;
292 GLuint texture_;
293 GLuint fbo_;
294
295private:
296 static int use_count;
297
298};
299
300int RenderObject::use_count = 0;
301Program RenderObject::main_program;
302
303/**
304 * A RenderObject representing the screen.
305 *
306 * Rendering to this objects renders to the screen framebuffer.
307 */
308class RenderScreen : public RenderObject
309{
310public:
311 virtual void init() {}
312};
313
314/**
315 * A RenderObject with a background image.
316 *
317 * The image is drawn to the RenderObject automatically when the
318 * object is cleared, resized etc
319 */
320class RenderClearImage : public RenderObject
321{
322public:
323 RenderClearImage(const std::string& texture) :
324 RenderObject(), background_texture_name(texture),
325 background_texture_(0) {}
326
327 virtual void init()
328 {
329 RenderObject::init();
330
331 /* Load the image into a texture */
332 Texture::load(background_texture_name,
333 &background_texture_, GL_LINEAR, GL_LINEAR, 0);
334
335 }
336
337 virtual void release()
338 {
339 glDeleteTextures(1, &background_texture_);
340 background_texture_ = 0;
341
342 RenderObject::release();
343 }
344
345 virtual void clear()
346 {
347 static const GLfloat position[2 * 4] = {
348 -1.0, -1.0,
349 1.0, -1.0,
350 -1.0, 1.0,
351 1.0, 1.0,
352 };
353 static const GLfloat texcoord[2 * 4] = {
354 0.0, 0.0,
355 1.0, 0.0,
356 0.0, 1.0,
357 1.0, 1.0,
358 };
359
360 make_current();
361 glClear(GL_COLOR_BUFFER_BIT);
362
363 glActiveTexture(GL_TEXTURE0);
364 glBindTexture(GL_TEXTURE_2D, background_texture_);
365
366 glEnable(GL_BLEND);
367 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
368 draw_quad_with_program(position, texcoord, main_program);
369 glDisable(GL_BLEND);
370 }
371
372private:
373 std::string background_texture_name;
374 GLuint background_texture_;
375};
376
377/**
378 * A RenderObject that blurs the target it is drawn to.
379 */
380class RenderWindowBlur : public RenderObject
381{
382public:
383 RenderWindowBlur(unsigned int passes, unsigned int radius, bool separable,
384 bool draw_contents = true) :
385 RenderObject(), passes_(passes), radius_(radius), separable_(separable),
386 draw_contents_(draw_contents) {}
387
388 virtual void init()
389 {
390 RenderObject::init();
391
392 /* Only have one instance of the window contents data */
393 if (draw_contents_ && RenderWindowBlur::use_count == 0)
394 window_contents_.init();
395
396 RenderWindowBlur::use_count++;
397 }
398
399 virtual void release()
400 {
401 RenderWindowBlur::use_count--;
402
403 /* Only have one instance of the window contents data */
404 if (draw_contents_ && RenderWindowBlur::use_count == 0)
405 window_contents_.release();
406
407 RenderObject::release();
408 }
409
410 virtual void size(const LibMatrix::vec2& size)
411 {
412 RenderObject::size(size);
413 if (draw_contents_)
414 window_contents_.size(size);
415 }
416
417 virtual void render_to(RenderObject& target, Program& program)
418 {
419 (void)program;
420
421 if (separable_) {
422 Program& blur_program_h1 = blur_program_h(target.size().x());
423 Program& blur_program_v1 = blur_program_v(target.size().y());
424
425 for (unsigned int i = 0; i < passes_; i++) {
426 render_from(target, blur_program_h1);
427 RenderObject::render_to(target, blur_program_v1);
428 }
429 }
430 else {
431 Program& blur_program1 = blur_program(target.size().x(), target.size().y());
432
433 for (unsigned int i = 0; i < passes_; i++) {
434 if (i % 2 == 0)
435 render_from(target, blur_program1);
436 else
437 RenderObject::render_to(target, blur_program1);
438 }
439
440 if (passes_ % 2 == 1)
441 RenderObject::render_to(target);
442 }
443
444 /*
445 * Blend the window contents with the target texture.
446 */
447 if (draw_contents_) {
448 glEnable(GL_BLEND);
449 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
450 window_contents_.position(position());
451 window_contents_.render_to(target);
452 glDisable(GL_BLEND);
453 }
454 }
455
456private:
457 Program& blur_program(unsigned int w, unsigned int h)
458 {
459 /*
460 * If the size of the window has changed we must recreate
461 * the shader to contain the correct texture step values.
462 */
463 if (blur_program_dim_.x() != w || blur_program_dim_.y() != h ||
464 !blur_program_.ready())
465 {
466 blur_program_dim_.x(w);
467 blur_program_dim_.y(h);
468
469 blur_program_.release();
470
471 ShaderSource vtx_source;
472 ShaderSource frg_source;
473 create_blur_shaders(vtx_source, frg_source, radius_,
474 radius_ / 3.0, BlurDirectionBoth);
475 frg_source.add_const("TextureStepX", 1.0 / w);
476 frg_source.add_const("TextureStepY", 1.0 / h);
477 Scene::load_shaders_from_strings(blur_program_, vtx_source.str(),
478 frg_source.str());
479 }
480
481 return blur_program_;
482 }
483
484 Program& blur_program_h(unsigned int w)
485 {
486 /*
487 * If the size of the window has changed we must recreate
488 * the shader to contain the correct texture step values.
489 */
490 if (blur_program_dim_.x() != w ||
491 !blur_program_h_.ready())
492 {
493 blur_program_dim_.x(w);
494
495 blur_program_h_.release();
496
497 ShaderSource vtx_source;
498 ShaderSource frg_source;
499 create_blur_shaders(vtx_source, frg_source, radius_,
500 radius_ / 3.0, BlurDirectionHorizontal);
501 frg_source.add_const("TextureStepX", 1.0 / w);
502 Scene::load_shaders_from_strings(blur_program_h_, vtx_source.str(),
503 frg_source.str());
504 }
505
506 return blur_program_h_;
507 }
508
509 Program& blur_program_v(unsigned int h)
510 {
511 /*
512 * If the size of the window has changed we must recreate
513 * the shader to contain the correct texture step values.
514 */
515 if (blur_program_dim_.y() != h ||
516 !blur_program_v_.ready())
517 {
518 blur_program_dim_.y(h);
519
520 blur_program_v_.release();
521
522 ShaderSource vtx_source;
523 ShaderSource frg_source;
524 create_blur_shaders(vtx_source, frg_source, radius_,
525 radius_ / 3.0, BlurDirectionVertical);
526 frg_source.add_const("TextureStepY", 1.0 / h);
527 Scene::load_shaders_from_strings(blur_program_v_, vtx_source.str(),
528 frg_source.str());
529 }
530
531 return blur_program_v_;
532 }
533
534 LibMatrix::uvec2 blur_program_dim_;
535 Program blur_program_;
536 Program blur_program_h_;
537 Program blur_program_v_;
538 unsigned int passes_;
539 unsigned int radius_;
540 bool separable_;
541 bool draw_contents_;
542
543 static int use_count;
544 static RenderClearImage window_contents_;
545
546};
547
548int RenderWindowBlur::use_count = 0;
549RenderClearImage RenderWindowBlur::window_contents_(GLMARK_DATA_PATH"/textures/desktop-window.png");
550
551/*******************************
552 * SceneDesktop implementation *
553 *******************************/
554
555/**
556 * Private structure used to avoid contaminating scene.h with all of the
557 * SceneDesktop internal classes.
558 */
559struct SceneDesktopPrivate
560{
561 RenderScreen screen;
562 RenderClearImage desktop;
563 std::vector<RenderObject *> windows;
564
565 SceneDesktopPrivate() :
566 desktop(GLMARK_DATA_PATH"/textures/effect-2d.png") {}
567
568 ~SceneDesktopPrivate() { Util::dispose_pointer_vector(windows); }
569
570};
571
572
573SceneDesktop::SceneDesktop(Canvas &canvas) :
574 Scene(canvas, "desktop")
575{
576 priv_ = new SceneDesktopPrivate();
577 mOptions["effect"] = Scene::Option("effect", "blur",
578 "the effect to use [blur]");
579 mOptions["windows"] = Scene::Option("windows", "4",
580 "the number of windows");
581 mOptions["window-size"] = Scene::Option("window-size", "0.35",
582 "the window size as a percentage of the minimum screen dimension [0.0 - 0.5]");
583 mOptions["passes"] = Scene::Option("passes", "1",
584 "the number of effect passes (effect dependent)");
585 mOptions["blur-radius"] = Scene::Option("blur-radius", "5",
586 "the blur effect radius (in pixels)");
587 mOptions["separable"] = Scene::Option("separable", "true",
588 "use separable convolution for the blur effect");
589}
590
591SceneDesktop::~SceneDesktop()
592{
593 delete priv_;
594}
595
596int
597SceneDesktop::load()
598{
599 priv_->screen.init();
600 priv_->desktop.init();
601 return 1;
602}
603
604void
605SceneDesktop::unload()
606{
607 priv_->desktop.release();
608 priv_->screen.release();
609}
610
611void
612SceneDesktop::setup()
613{
614 Scene::setup();
615
616 std::stringstream ss;
617 unsigned int windows(0);
618 unsigned int passes(0);
619 unsigned int blur_radius(0);
620 float window_size_factor(0.0);
621 bool separable(mOptions["separable"].value == "true");
622
623 ss << mOptions["windows"].value;
624 ss >> windows;
625 ss.clear();
626 ss << mOptions["window-size"].value;
627 ss >> window_size_factor;
628 ss.clear();
629 ss << mOptions["passes"].value;
630 ss >> passes;
631 ss.clear();
632 ss << mOptions["blur-radius"].value;
633 ss >> blur_radius;
634
635 /* Ensure we get a transparent clear color for all following operations */
636 glClearColor(0.0, 0.0, 0.0, 0.0);
637 glDisable(GL_DEPTH_TEST);
638 glDepthMask(GL_FALSE);
639
640 /* Set up the screen and desktop RenderObjects */
641 priv_->screen.size(LibMatrix::vec2(mCanvas.width(), mCanvas.height()));
642 priv_->desktop.size(LibMatrix::vec2(mCanvas.width(), mCanvas.height()));
643
644 /* Create the windows */
645 float angular_step(2.0 * M_PI / windows);
646 unsigned int min_dimension = std::min(mCanvas.width(), mCanvas.height());
647 float window_size(min_dimension * window_size_factor);
648 static const LibMatrix::vec2 corner_offset(window_size / 2.0,
649 window_size / 2.0);
650
651 for (unsigned int i = 0; i < windows; i++) {
652 LibMatrix::vec2 center(mCanvas.width() * (0.5 + 0.25 * cos(i * angular_step)),
653 mCanvas.height() * (0.5 + 0.25 * sin(i * angular_step)));
654 RenderObject* win(new RenderWindowBlur(passes, blur_radius, separable));
655 (void)angular_step;
656
657 win->init();
658 win->position(center - corner_offset);
659 win->size(LibMatrix::vec2(window_size, window_size));
660 /*
661 * Set the speed in increments of about 30 degrees (but not exactly,
662 * so we don't get windows moving just on the X axis or Y axis).
663 */
664 win->speed(LibMatrix::vec2(cos(0.1 + i * M_PI / 6.0) * mCanvas.width() / 3,
665 sin(0.1 + i * M_PI / 6.0) * mCanvas.height() / 3));
666 /*
667 * Perform a dummy rendering to ensure internal shaders are initialized
668 * now, in order not to affect the benchmarking.
669 */
670 win->render_to(priv_->desktop);
671 priv_->windows.push_back(win);
672 }
673
674 /*
675 * Ensure the screen is the current rendering target (it might have changed
676 * to a FBO in the previous steps).
677 */
678 priv_->screen.make_current();
679
680 mCurrentFrame = 0;
681 mRunning = true;
682 mStartTime = Scene::get_timestamp_us() / 1000000.0;
683 mLastUpdateTime = mStartTime;
684}
685
686void
687SceneDesktop::teardown()
688{
689 Util::dispose_pointer_vector(priv_->windows);
690 priv_->screen.make_current();
691
692 glEnable(GL_DEPTH_TEST);
693 glDepthMask(GL_TRUE);
694
695 Scene::teardown();
696}
697
698void
699SceneDesktop::update()
700{
701 double current_time = Scene::get_timestamp_us() / 1000000.0;
702 double dt = current_time - mLastUpdateTime;
703 double elapsed_time = current_time - mStartTime;
704
705 mLastUpdateTime = current_time;
706
707 std::vector<RenderObject *>& windows(priv_->windows);
708
709 /*
710 * Move the windows around the screen, bouncing them back when
711 * they reach the edge.
712 */
713 for (std::vector<RenderObject *>::const_iterator iter = windows.begin();
714 iter != windows.end();
715 iter++)
716 {
717 bool should_update = true;
718 RenderObject *win = *iter;
719 LibMatrix::vec2 new_pos(
720 win->position().x() + win->speed().x() * dt,
721 win->position().y() + win->speed().y() * dt);
722
723 if (new_pos.x() < 0.0 ||
724 new_pos.x() + win->size().x() > ((float)mCanvas.width()))
725 {
726 win->speed(LibMatrix::vec2(-win->speed().x(), win->speed().y()));
727 should_update = false;
728 }
729
730 if (new_pos.y() < 0.0 ||
731 new_pos.y() + win->size().y() > ((float)mCanvas.height()))
732 {
733 win->speed(LibMatrix::vec2(win->speed().x(), -win->speed().y()));
734 should_update = false;
735 }
736
737 if (should_update)
738 win->position(new_pos);
739 }
740
741 if (elapsed_time >= mDuration) {
742 mAverageFPS = mCurrentFrame / elapsed_time;
743 mRunning = false;
744 }
745
746 mCurrentFrame++;
747}
748
749void
750SceneDesktop::draw()
751{
752 std::vector<RenderObject *>& windows(priv_->windows);
753
754 /* Ensure we get a transparent clear color for all following operations */
755 glClearColor(0.0, 0.0, 0.0, 0.0);
756
757 priv_->desktop.clear();
758
759 for (std::vector<RenderObject *>::const_iterator iter = windows.begin();
760 iter != windows.end();
761 iter++)
762 {
763 RenderObject *win = *iter;
764 win->render_to(priv_->desktop);
765 }
766
767 priv_->desktop.render_to(priv_->screen);
768
769}
770
771Scene::ValidationResult
772SceneDesktop::validate()
773{
774 return ValidationUnknown;
775}
0776
=== modified file 'src/scene.h'
--- src/scene.h 2011-08-18 13:20:04 +0000
+++ src/scene.h 2011-09-13 09:41:05 +0000
@@ -331,4 +331,23 @@
331 void create_and_setup_mesh();331 void create_and_setup_mesh();
332};332};
333333
334struct SceneDesktopPrivate;
335
336class SceneDesktop : public Scene
337{
338public:
339 SceneDesktop(Canvas &canvas);
340 int load();
341 void unload();
342 void setup();
343 void teardown();
344 void update();
345 void draw();
346 ValidationResult validate();
347
348 ~SceneDesktop();
349
350private:
351 SceneDesktopPrivate *priv_;
352};
334#endif353#endif

Subscribers

People subscribed via source and target branches