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