Merge lp:~glmark2-dev/glmark2/live-fps into lp:glmark2/2011.11
- live-fps
- Merge into trunk
Proposed by
Alexandros Frantzis
Status: | Merged |
---|---|
Merged at revision: | 178 |
Proposed branch: | lp:~glmark2-dev/glmark2/live-fps |
Merge into: | lp:glmark2/2011.11 |
Diff against target: |
504 lines (+397/-0) 8 files modified
data/shaders/text-renderer.frag (+10/-0) data/shaders/text-renderer.vert (+10/-0) doc/glmark2.1.in (+4/-0) src/main.cpp (+15/-0) src/options.cpp (+6/-0) src/options.h (+1/-0) src/text-renderer.cpp (+291/-0) src/text-renderer.h (+60/-0) |
To merge this branch: | bzr merge lp:~glmark2-dev/glmark2/live-fps |
Related bugs: | |
Related blueprints: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jesse Barker | Pending | ||
Review via email:
|
Commit message
Description of the change
Add support for optionally showing a live FPS counter on screen.
To post a comment you must log in.
lp:~glmark2-dev/glmark2/live-fps
updated
- 179. By Alexandros Frantzis
-
TextRenderer: Avoid setting/restoring the VBO state more than once.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added file 'data/shaders/text-renderer.frag' |
2 | --- data/shaders/text-renderer.frag 1970-01-01 00:00:00 +0000 |
3 | +++ data/shaders/text-renderer.frag 2012-01-05 09:43:24 +0000 |
4 | @@ -0,0 +1,10 @@ |
5 | +uniform sampler2D Texture0; |
6 | + |
7 | +varying vec2 TextureCoord; |
8 | + |
9 | +void main(void) |
10 | +{ |
11 | + vec4 texel = texture2D(Texture0, TextureCoord); |
12 | + gl_FragColor = texel; |
13 | +} |
14 | + |
15 | |
16 | === added file 'data/shaders/text-renderer.vert' |
17 | --- data/shaders/text-renderer.vert 1970-01-01 00:00:00 +0000 |
18 | +++ data/shaders/text-renderer.vert 2012-01-05 09:43:24 +0000 |
19 | @@ -0,0 +1,10 @@ |
20 | +attribute vec2 position; |
21 | +attribute vec2 texcoord; |
22 | + |
23 | +varying vec2 TextureCoord; |
24 | + |
25 | +void main(void) |
26 | +{ |
27 | + TextureCoord = texcoord; |
28 | + gl_Position = vec4(position, 0.0, 1.0); |
29 | +} |
30 | |
31 | === added file 'data/textures/glyph-atlas.png' |
32 | Binary files data/textures/glyph-atlas.png 1970-01-01 00:00:00 +0000 and data/textures/glyph-atlas.png 2012-01-05 09:43:24 +0000 differ |
33 | === modified file 'doc/glmark2.1.in' |
34 | --- doc/glmark2.1.in 2011-12-15 13:52:04 +0000 |
35 | +++ doc/glmark2.1.in 2012-01-05 09:43:24 +0000 |
36 | @@ -36,6 +36,10 @@ |
37 | Show all scene option values used for benchmarks |
38 | (only explicitly set options are shown by default) |
39 | .TP |
40 | +\fB\-\-show-fps\fR |
41 | +Show live FPS count on screen (showing live FPS |
42 | +affects benchmarking results, use with care!) |
43 | +.TP |
44 | \fB\-d\fR, \fB\-\-debug\fR |
45 | Display debug messages |
46 | .TP |
47 | |
48 | === modified file 'src/main.cpp' |
49 | --- src/main.cpp 2011-11-11 11:07:15 +0000 |
50 | +++ src/main.cpp 2012-01-05 09:43:24 +0000 |
51 | @@ -28,6 +28,7 @@ |
52 | #include "log.h" |
53 | #include "util.h" |
54 | #include "default-benchmarks.h" |
55 | +#include "text-renderer.h" |
56 | |
57 | #include <iostream> |
58 | #include <fstream> |
59 | @@ -149,6 +150,8 @@ |
60 | void |
61 | do_benchmark(Canvas &canvas, vector<Benchmark *> &benchmarks) |
62 | { |
63 | + static const unsigned int fps_interval = 500000; |
64 | + TextRenderer fps_renderer(canvas); |
65 | unsigned score = 0; |
66 | unsigned int benchmarks_run = 0; |
67 | |
68 | @@ -158,6 +161,7 @@ |
69 | { |
70 | bool keep_running = true; |
71 | Benchmark *bench = *bench_iter; |
72 | + uint64_t fps_timestamp = Util::get_timestamp_us(); |
73 | Scene &scene = bench->setup_scene(); |
74 | |
75 | if (!scene.name().empty()) { |
76 | @@ -172,6 +176,17 @@ |
77 | scene.draw(); |
78 | scene.update(); |
79 | |
80 | + if (Options::show_fps) { |
81 | + uint64_t now = Util::get_timestamp_us(); |
82 | + if (now - fps_timestamp >= fps_interval) { |
83 | + std::stringstream ss; |
84 | + ss << "FPS: " << scene.average_fps(); |
85 | + fps_renderer.text(ss.str()); |
86 | + fps_timestamp = now; |
87 | + } |
88 | + fps_renderer.render(); |
89 | + } |
90 | + |
91 | canvas.update(); |
92 | } |
93 | |
94 | |
95 | === modified file 'src/options.cpp' |
96 | --- src/options.cpp 2011-11-01 16:46:08 +0000 |
97 | +++ src/options.cpp 2012-01-05 09:43:24 +0000 |
98 | @@ -39,6 +39,7 @@ |
99 | bool Options::list_scenes = false; |
100 | bool Options::show_all_options = false; |
101 | bool Options::show_debug = false; |
102 | +bool Options::show_fps = false; |
103 | bool Options::show_help = false; |
104 | |
105 | static struct option long_options[] = { |
106 | @@ -49,6 +50,7 @@ |
107 | {"size", 1, 0, 0}, |
108 | {"list-scenes", 0, 0, 0}, |
109 | {"show-all-options", 0, 0, 0}, |
110 | + {"show-fps", 0, 0, 0}, |
111 | {"debug", 0, 0, 0}, |
112 | {"help", 0, 0, 0}, |
113 | {0, 0, 0, 0} |
114 | @@ -98,6 +100,8 @@ |
115 | " and their options\n" |
116 | " --show-all-options Show all scene option values used for benchmarks\n" |
117 | " (only explicitly set options are shown by default)\n" |
118 | + " --show-fps Show live FPS count on screen (showing live FPS\n" |
119 | + " affects benchmarking results, use with care!)\n" |
120 | " -d, --debug Display debug messages\n" |
121 | " -h, --help Display help\n"); |
122 | } |
123 | @@ -134,6 +138,8 @@ |
124 | Options::list_scenes = true; |
125 | else if (!strcmp(optname, "show-all-options")) |
126 | Options::show_all_options = true; |
127 | + else if (!strcmp(optname, "show-fps")) |
128 | + Options::show_fps = true; |
129 | else if (c == 'd' || !strcmp(optname, "debug")) |
130 | Options::show_debug = true; |
131 | else if (c == 'h' || !strcmp(optname, "help")) |
132 | |
133 | === modified file 'src/options.h' |
134 | --- src/options.h 2011-09-20 12:52:21 +0000 |
135 | +++ src/options.h 2012-01-05 09:43:24 +0000 |
136 | @@ -39,6 +39,7 @@ |
137 | static bool list_scenes; |
138 | static bool show_all_options; |
139 | static bool show_debug; |
140 | + static bool show_fps; |
141 | static bool show_help; |
142 | }; |
143 | |
144 | |
145 | === added file 'src/text-renderer.cpp' |
146 | --- src/text-renderer.cpp 1970-01-01 00:00:00 +0000 |
147 | +++ src/text-renderer.cpp 2012-01-05 09:43:24 +0000 |
148 | @@ -0,0 +1,291 @@ |
149 | +/* |
150 | + * Copyright © 2011 Linaro Limited |
151 | + * |
152 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
153 | + * |
154 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
155 | + * terms of the GNU General Public License as published by the Free Software |
156 | + * Foundation, either version 3 of the License, or (at your option) any later |
157 | + * version. |
158 | + * |
159 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
160 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
161 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
162 | + * details. |
163 | + * |
164 | + * You should have received a copy of the GNU General Public License along with |
165 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
166 | + * |
167 | + * Authors: |
168 | + * Alexandros Frantzis (glmark2) |
169 | + */ |
170 | +#include "text-renderer.h" |
171 | +#include "gl-headers.h" |
172 | +#include "scene.h" |
173 | +#include "shader-source.h" |
174 | +#include "vec.h" |
175 | +#include "mat.h" |
176 | +#include "texture.h" |
177 | + |
178 | +using LibMatrix::vec2; |
179 | +using LibMatrix::mat4; |
180 | + |
181 | +/* These are specific to the glyph texture atlas we are using */ |
182 | +static const unsigned int texture_size(512); |
183 | +static const vec2 glyph_size_pixels(29.0, 57.0); |
184 | +static const vec2 glyph_size(glyph_size_pixels/texture_size); |
185 | + |
186 | +/****************** |
187 | + * Public methods * |
188 | + ******************/ |
189 | + |
190 | +/** |
191 | + * TextRenderer default constructor. |
192 | + */ |
193 | +TextRenderer::TextRenderer(Canvas& canvas) : |
194 | + canvas_(canvas), dirty_(false), position_(-1.0, -1.0), |
195 | + texture_(0) |
196 | +{ |
197 | + size(0.03); |
198 | + |
199 | + glGenBuffers(2, vbo_); |
200 | + ShaderSource vtx_source(GLMARK_DATA_PATH"/shaders/text-renderer.vert"); |
201 | + ShaderSource frg_source(GLMARK_DATA_PATH"/shaders/text-renderer.frag"); |
202 | + |
203 | + if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), |
204 | + frg_source.str())) |
205 | + { |
206 | + return; |
207 | + } |
208 | + |
209 | + GLint prev_program; |
210 | + glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program); |
211 | + |
212 | + program_.start(); |
213 | + program_["Texture0"] = 0; |
214 | + |
215 | + glUseProgram(prev_program); |
216 | + |
217 | + /* Load the glyph texture atlas */ |
218 | + Texture::load(GLMARK_DATA_PATH"/textures/glyph-atlas.png", &texture_, |
219 | + GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR,0); |
220 | +} |
221 | + |
222 | +TextRenderer::~TextRenderer() |
223 | +{ |
224 | + glDeleteBuffers(2, vbo_); |
225 | + glDeleteTextures(1, &texture_); |
226 | +} |
227 | + |
228 | +/** |
229 | + * Sets the text string to render. |
230 | + * |
231 | + * @param t the text string |
232 | + */ |
233 | +void |
234 | +TextRenderer::text(const std::string& t) |
235 | +{ |
236 | + if (text_ != t) { |
237 | + text_ = t; |
238 | + dirty_ = true; |
239 | + } |
240 | +} |
241 | + |
242 | +/** |
243 | + * Sets the screen position to render at. |
244 | + * |
245 | + * @param t the position |
246 | + */ |
247 | +void |
248 | +TextRenderer::position(LibMatrix::vec2& p) |
249 | +{ |
250 | + if (position_ != p) { |
251 | + position_ = p; |
252 | + dirty_ = true; |
253 | + } |
254 | +} |
255 | + |
256 | +/** |
257 | + * Sets the size of each rendered glyph. |
258 | + * |
259 | + * The size corresponds to the width of each glyph |
260 | + * in normalized screen coordinates. |
261 | + * |
262 | + * @param s the size of each glyph |
263 | + */ |
264 | +void |
265 | +TextRenderer::size(float s) |
266 | +{ |
267 | + if (size_.x() != s) { |
268 | + /* Take into account the glyph and canvas aspect ratio */ |
269 | + double canvas_aspect = |
270 | + static_cast<double>(canvas_.width()) / canvas_.height(); |
271 | + double glyph_aspect_rev = glyph_size.y() / glyph_size.x(); |
272 | + size_ = vec2(s, s * canvas_aspect * glyph_aspect_rev); |
273 | + dirty_ = true; |
274 | + } |
275 | +} |
276 | + |
277 | +/** |
278 | + * Renders the text. |
279 | + */ |
280 | +void |
281 | +TextRenderer::render() |
282 | +{ |
283 | + /* Save state */ |
284 | + GLint prev_program = 0; |
285 | + GLint prev_array_buffer = 0; |
286 | + GLint prev_elem_array_buffer = 0; |
287 | + GLint prev_blend_src_rgb = 0; |
288 | + GLint prev_blend_dst_rgb = 0; |
289 | + GLint prev_blend_src_alpha = 0; |
290 | + GLint prev_blend_dst_alpha = 0; |
291 | + GLboolean prev_blend = GL_FALSE; |
292 | + GLboolean prev_depth_test = GL_FALSE; |
293 | + glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program); |
294 | + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &prev_array_buffer); |
295 | + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &prev_elem_array_buffer); |
296 | + glGetIntegerv(GL_BLEND_SRC_RGB, &prev_blend_src_rgb); |
297 | + glGetIntegerv(GL_BLEND_DST_RGB, &prev_blend_dst_rgb); |
298 | + glGetIntegerv(GL_BLEND_SRC_ALPHA, &prev_blend_src_alpha); |
299 | + glGetIntegerv(GL_BLEND_DST_ALPHA, &prev_blend_dst_alpha); |
300 | + glGetBooleanv(GL_BLEND, &prev_blend); |
301 | + glGetBooleanv(GL_DEPTH_TEST, &prev_depth_test); |
302 | + |
303 | + /* Set new state */ |
304 | + glActiveTexture(GL_TEXTURE0); |
305 | + glBindTexture(GL_TEXTURE_2D, texture_); |
306 | + glBindBuffer(GL_ARRAY_BUFFER, vbo_[0]); |
307 | + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo_[1]); |
308 | + glEnable(GL_BLEND); |
309 | + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); |
310 | + glDisable(GL_DEPTH_TEST); |
311 | + |
312 | + if (dirty_) { |
313 | + create_geometry(); |
314 | + dirty_ = false; |
315 | + } |
316 | + |
317 | + program_.start(); |
318 | + GLint position_loc = program_["position"].location(); |
319 | + GLint texcoord_loc = program_["texcoord"].location(); |
320 | + |
321 | + /* Render */ |
322 | + glEnableVertexAttribArray(position_loc); |
323 | + glEnableVertexAttribArray(texcoord_loc); |
324 | + glVertexAttribPointer(position_loc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); |
325 | + glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), |
326 | + reinterpret_cast<const GLvoid *>(2 * sizeof(float))); |
327 | + |
328 | + glDrawElements(GL_TRIANGLES, 6 * text_.length(), GL_UNSIGNED_SHORT, 0); |
329 | + |
330 | + glDisableVertexAttribArray(texcoord_loc); |
331 | + glDisableVertexAttribArray(position_loc); |
332 | + |
333 | + /* Restore state */ |
334 | + if (prev_depth_test == GL_TRUE) |
335 | + glEnable(GL_DEPTH_TEST); |
336 | + if (prev_blend == GL_FALSE) |
337 | + glDisable(GL_BLEND); |
338 | + glBlendFuncSeparate(prev_blend_src_rgb, prev_blend_dst_rgb, |
339 | + prev_blend_src_alpha, prev_blend_dst_alpha); |
340 | + glBindBuffer(GL_ARRAY_BUFFER, prev_array_buffer); |
341 | + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, prev_elem_array_buffer); |
342 | + glUseProgram(prev_program); |
343 | +} |
344 | + |
345 | +/******************* |
346 | + * Private methods * |
347 | + *******************/ |
348 | + |
349 | +/** |
350 | + * Creates the geometry needed to render the text. |
351 | + * |
352 | + * This method assumes that the text VBOs are properly bound. |
353 | + */ |
354 | +void |
355 | +TextRenderer::create_geometry() |
356 | +{ |
357 | + std::vector<float> array; |
358 | + std::vector<GLushort> elem_array; |
359 | + vec2 pos(position_); |
360 | + |
361 | + for (size_t i = 0; i < text_.size(); i++) { |
362 | + vec2 texcoord = get_glyph_coords(text_[i]); |
363 | + |
364 | + /* Emit the elements for this glyph quad */ |
365 | + /* Lower left */ |
366 | + array.push_back(pos.x()); |
367 | + array.push_back(pos.y()); |
368 | + array.push_back(texcoord.x()); |
369 | + array.push_back(texcoord.y()); |
370 | + |
371 | + /* Lower right */ |
372 | + pos.x(pos.x() + size_.x()); |
373 | + texcoord.x(texcoord.x() + glyph_size.x()); |
374 | + array.push_back(pos.x()); |
375 | + array.push_back(pos.y()); |
376 | + array.push_back(texcoord.x()); |
377 | + array.push_back(texcoord.y()); |
378 | + |
379 | + /* Upper left */ |
380 | + pos.x(pos.x() - size_.x()); |
381 | + pos.y(pos.y() + size_.y()); |
382 | + texcoord.x(texcoord.x() - glyph_size.x()); |
383 | + texcoord.y(texcoord.y() + glyph_size.y()); |
384 | + array.push_back(pos.x()); |
385 | + array.push_back(pos.y()); |
386 | + array.push_back(texcoord.x()); |
387 | + array.push_back(texcoord.y()); |
388 | + |
389 | + /* Upper right */ |
390 | + pos.x(pos.x() + size_.x()); |
391 | + texcoord.x(texcoord.x() + glyph_size.x()); |
392 | + array.push_back(pos.x()); |
393 | + array.push_back(pos.y()); |
394 | + array.push_back(texcoord.x()); |
395 | + array.push_back(texcoord.y()); |
396 | + |
397 | + /* Prepare for the next glyph */ |
398 | + pos.y(pos.y() - size_.y()); |
399 | + |
400 | + /* Emit the element indices for this glyph quad */ |
401 | + elem_array.push_back(4 * i); |
402 | + elem_array.push_back(4 * i + 1); |
403 | + elem_array.push_back(4 * i + 2); |
404 | + elem_array.push_back(4 * i + 2); |
405 | + elem_array.push_back(4 * i + 1); |
406 | + elem_array.push_back(4 * i + 3); |
407 | + } |
408 | + |
409 | + /* Load the data into the corresponding VBOs */ |
410 | + glBufferData(GL_ARRAY_BUFFER, array.size() * sizeof(float), |
411 | + &array[0], GL_DYNAMIC_DRAW); |
412 | + |
413 | + glBufferData(GL_ELEMENT_ARRAY_BUFFER, elem_array.size() * sizeof(GLushort), |
414 | + &elem_array[0], GL_DYNAMIC_DRAW); |
415 | +} |
416 | + |
417 | +/** |
418 | + * Gets the texcoords of a glyph in the glyph texture atlas. |
419 | + * |
420 | + * @param c the character to get the glyph texcoords of |
421 | + * |
422 | + * @return the texcoords |
423 | + */ |
424 | +vec2 |
425 | +TextRenderer::get_glyph_coords(char c) |
426 | +{ |
427 | + static const unsigned int glyphs_per_row(texture_size / glyph_size_pixels.x()); |
428 | + |
429 | + /* We only support the ASCII printable characters */ |
430 | + if (c < 32 || c >= 127) |
431 | + c = 32; |
432 | + |
433 | + int n = c - 32; |
434 | + int row = n / glyphs_per_row; |
435 | + int col = n % glyphs_per_row; |
436 | + |
437 | + return vec2(col * glyph_size.x(), 1.0 - (row + 1) * glyph_size.y()); |
438 | +} |
439 | + |
440 | |
441 | === added file 'src/text-renderer.h' |
442 | --- src/text-renderer.h 1970-01-01 00:00:00 +0000 |
443 | +++ src/text-renderer.h 2012-01-05 09:43:24 +0000 |
444 | @@ -0,0 +1,60 @@ |
445 | +/* |
446 | + * Copyright © 2011 Linaro Limited |
447 | + * |
448 | + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. |
449 | + * |
450 | + * glmark2 is free software: you can redistribute it and/or modify it under the |
451 | + * terms of the GNU General Public License as published by the Free Software |
452 | + * Foundation, either version 3 of the License, or (at your option) any later |
453 | + * version. |
454 | + * |
455 | + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY |
456 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
457 | + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
458 | + * details. |
459 | + * |
460 | + * You should have received a copy of the GNU General Public License along with |
461 | + * glmark2. If not, see <http://www.gnu.org/licenses/>. |
462 | + * |
463 | + * Authors: |
464 | + * Alexandros Frantzis (glmark2) |
465 | + */ |
466 | +#ifndef GLMARK2_TEXT_RENDERER_H_ |
467 | +#define GLMARK2_TEXT_RENDERER_H_ |
468 | + |
469 | +#include <string> |
470 | +#include "gl-headers.h" |
471 | +#include "vec.h" |
472 | +#include "program.h" |
473 | +#include "canvas.h" |
474 | + |
475 | +/** |
476 | + * Renders text using OpenGL textures. |
477 | + */ |
478 | +class TextRenderer |
479 | +{ |
480 | +public: |
481 | + TextRenderer(Canvas& canvas); |
482 | + ~TextRenderer(); |
483 | + |
484 | + void text(const std::string& t); |
485 | + void position(LibMatrix::vec2& p); |
486 | + void size(float s); |
487 | + |
488 | + void render(); |
489 | + |
490 | +private: |
491 | + void create_geometry(); |
492 | + LibMatrix::vec2 get_glyph_coords(char c); |
493 | + |
494 | + Canvas& canvas_; |
495 | + bool dirty_; |
496 | + std::string text_; |
497 | + LibMatrix::vec2 position_; |
498 | + LibMatrix::vec2 size_; |
499 | + Program program_; |
500 | + GLuint vbo_[2]; |
501 | + GLuint texture_; |
502 | +}; |
503 | + |
504 | +#endif |