Merge lp:~glmark2-dev/glmark2/refract into lp:glmark2/2011.11

Proposed by Jesse Barker
Status: Merged
Merged at revision: 255
Proposed branch: lp:~glmark2-dev/glmark2/refract
Merge into: lp:glmark2/2011.11
Diff against target: 728 lines (+667/-0)
8 files modified
data/shaders/light-refract.frag (+45/-0)
data/shaders/light-refract.vert (+28/-0)
src/android.cpp (+1/-0)
src/default-benchmarks.h (+1/-0)
src/main.cpp (+1/-0)
src/scene-refract.cpp (+469/-0)
src/scene-refract.h (+106/-0)
src/scene.h (+16/-0)
To merge this branch: bzr merge lp:~glmark2-dev/glmark2/refract
Reviewer Review Type Date Requested Status
Alexandros Frantzis Approve
Review via email: mp+139808@code.launchpad.net

Description of the change

SceneRefract: New scene that computes refractions through two interfaces of an object (more complex objects outside the scope of this effort), and uses the final transmitted vector to sample a background (environment) texture. A specular reflection is then computed and added to the texel for the final fragment color.

To post a comment you must log in.
lp:~glmark2-dev/glmark2/refract updated
263. By Jesse Barker

SceneRefract: Make the refractive index of the medium a command line option.
The default is 1.2, but could be anything ("believable" effects are probably in
the lower values).

264. By Alexandros Frantzis

SceneRefract: Fix potential memory leak

The memory leak occurs when using the scene for multiple benchmarks.

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

I updated the branch to fix a potential memory leak. The same leak exists in SceneShadow, but I didn't want to fix it here, in order to keep the MP focused. Ahhh, smart pointers, how do I love thee, let me count the ways: 1. std::unique_ptr, 2. std::shared_ptr :)

424 + // Now that we're successfully loaded, there are a few quirks about
425 + // some of the known models that we need to account for. The draw
426 + // logic for the scene wants to rotate the model around the Y axis.
427 + // Most of our models are described this way. Some need adjustment
428 + // (an additional rotation that gets the model into the correct
429 + // orientation).
...

472 + // Calculate a projection matrix that is a good fit for the model
....

These code snippets are present verbatim in many scenes, so it's probably worth it to put them in Model or some other utility class to deduplicate the code. (Not a blocker for this MP, but surely something to consider for a future MP.)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/shaders/light-refract.frag'
2--- data/shaders/light-refract.frag 1970-01-01 00:00:00 +0000
3+++ data/shaders/light-refract.frag 2012-12-15 09:48:22 +0000
4@@ -0,0 +1,45 @@
5+uniform sampler2D DistanceMap;
6+uniform sampler2D NormalMap;
7+uniform sampler2D ImageMap;
8+
9+varying vec3 vertex_normal;
10+varying vec4 vertex_position;
11+varying vec4 MapCoord;
12+
13+void main()
14+{
15+ const vec4 lightSpecular = vec4(0.8, 0.8, 0.8, 1.0);
16+ const vec4 matSpecular = vec4(1.0, 1.0, 1.0, 1.0);
17+ const float matShininess = 100.0;
18+ const vec2 point_five = vec2(0.5);
19+ // Need the normalized eye direction and surface normal vectors to
20+ // compute the transmitted vector through the "front" surface of the object.
21+ vec3 eye_direction = normalize(-vertex_position.xyz);
22+ vec3 normalized_normal = normalize(vertex_normal);
23+ vec3 front_refraction = refract(eye_direction, normalized_normal, RefractiveIndex);
24+ // Find our best distance approximation through the object so we can
25+ // project the transmitted vector to the back of the object to find
26+ // the exit point.
27+ vec3 mc_perspective = (MapCoord.xyz / MapCoord.w) + front_refraction;
28+ vec2 dcoord = mc_perspective.st * point_five + point_five;
29+ vec4 distance_value = texture2D(DistanceMap, dcoord);
30+ vec3 back_position = vertex_position.xyz + front_refraction * distance_value.z;
31+ // Use the exit point to index the map of back-side normals, and use the
32+ // back-side position and normal to find the transmitted vector out of the
33+ // object.
34+ vec2 normcoord = back_position.st * point_five + point_five;
35+ vec3 back_normal = texture2D(NormalMap, normcoord).xyz;
36+ vec3 back_refraction = refract(back_position, back_normal, 1.0);
37+ // Use the transmitted vector from the exit point to determine where
38+ // the vector would intersect the environment (in this case a background
39+ // image.
40+ vec2 imagecoord = back_refraction.st * point_five + point_five;
41+ vec4 texel = texture2D(ImageMap, imagecoord);
42+ // Add in specular reflection, and we have our fragment value.
43+ vec3 light_direction = normalize(vertex_position.xyz/vertex_position.w -
44+ LightSourcePosition.xyz/LightSourcePosition.w);
45+ vec3 reflection = reflect(light_direction, normalized_normal);
46+ float specularTerm = pow(max(0.0, dot(reflection, eye_direction)), matShininess);
47+ vec4 specular = (lightSpecular * matSpecular);
48+ gl_FragColor = (specular * specularTerm) + texel;
49+}
50
51=== added file 'data/shaders/light-refract.vert'
52--- data/shaders/light-refract.vert 1970-01-01 00:00:00 +0000
53+++ data/shaders/light-refract.vert 2012-12-15 09:48:22 +0000
54@@ -0,0 +1,28 @@
55+attribute vec3 position;
56+attribute vec3 normal;
57+
58+uniform mat4 ModelViewProjectionMatrix;
59+uniform mat4 NormalMatrix;
60+uniform mat4 ModelViewMatrix;
61+uniform mat4 LightMatrix;
62+
63+varying vec3 vertex_normal;
64+varying vec4 vertex_position;
65+varying vec4 MapCoord;
66+
67+void main(void)
68+{
69+ vec4 current_position = vec4(position, 1.0);
70+
71+ // Transform the normal to eye coordinates
72+ vertex_normal = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
73+
74+ // Transform the current position to eye coordinates
75+ vertex_position = ModelViewMatrix * current_position;
76+
77+ // Transform the current position for use as texture coordinates
78+ MapCoord = LightMatrix * current_position;
79+
80+ // Transform the current position to clip coordinates
81+ gl_Position = ModelViewProjectionMatrix * current_position;
82+}
83
84=== modified file 'src/android.cpp'
85--- src/android.cpp 2012-10-19 13:19:19 +0000
86+++ src/android.cpp 2012-12-15 09:48:22 +0000
87@@ -276,6 +276,7 @@
88 scenes.push_back(new SceneTerrain(canvas));
89 scenes.push_back(new SceneJellyfish(canvas));
90 scenes.push_back(new SceneShadow(canvas));
91+ scenes.push_back(new SceneRefract(canvas));
92 }
93
94
95
96=== modified file 'src/default-benchmarks.h'
97--- src/default-benchmarks.h 2012-10-19 13:19:19 +0000
98+++ src/default-benchmarks.h 2012-12-15 09:48:22 +0000
99@@ -64,6 +64,7 @@
100 benchmarks.push_back("jellyfish");
101 benchmarks.push_back("terrain");
102 benchmarks.push_back("shadow");
103+ benchmarks.push_back("refract");
104 benchmarks.push_back("conditionals:vertex-steps=0:fragment-steps=0");
105 benchmarks.push_back("conditionals:vertex-steps=0:fragment-steps=5");
106 benchmarks.push_back("conditionals:vertex-steps=5:fragment-steps=0");
107
108=== modified file 'src/main.cpp'
109--- src/main.cpp 2012-10-19 13:19:19 +0000
110+++ src/main.cpp 2012-12-15 09:48:22 +0000
111@@ -64,6 +64,7 @@
112 scenes.push_back(new SceneTerrain(canvas));
113 scenes.push_back(new SceneJellyfish(canvas));
114 scenes.push_back(new SceneShadow(canvas));
115+ scenes.push_back(new SceneRefract(canvas));
116
117 for (vector<Scene*>::const_iterator iter = scenes.begin();
118 iter != scenes.end();
119
120=== added file 'src/scene-refract.cpp'
121--- src/scene-refract.cpp 1970-01-01 00:00:00 +0000
122+++ src/scene-refract.cpp 2012-12-15 09:48:22 +0000
123@@ -0,0 +1,469 @@
124+//
125+// Copyright © 2012 Linaro Limited
126+//
127+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
128+//
129+// glmark2 is free software: you can redistribute it and/or modify it under the
130+// terms of the GNU General Public License as published by the Free Software
131+// Foundation, either version 3 of the License, or (at your option) any later
132+// version.
133+//
134+// glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
135+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
136+// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
137+// details.
138+//
139+// You should have received a copy of the GNU General Public License along with
140+// glmark2. If not, see <http://www.gnu.org/licenses/>.
141+//
142+// Authors:
143+// Jesse Barker
144+//
145+#include "scene-refract.h"
146+#include "model.h"
147+#include "texture.h"
148+#include "util.h"
149+#include "log.h"
150+#include "shader-source.h"
151+
152+using std::string;
153+using std::vector;
154+using std::map;
155+using LibMatrix::mat4;
156+using LibMatrix::vec4;
157+using LibMatrix::vec3;
158+
159+static const vec4 lightPosition(1.0f, 1.0f, 2.0f, 1.0f);
160+
161+//
162+// Public interfaces
163+//
164+
165+SceneRefract::SceneRefract(Canvas& canvas) :
166+ Scene(canvas, "refract"),
167+ priv_(0)
168+{
169+ const ModelMap& modelMap = Model::find_models();
170+ string optionValues;
171+ for (ModelMap::const_iterator modelIt = modelMap.begin();
172+ modelIt != modelMap.end();
173+ modelIt++)
174+ {
175+ static bool doSeparator(false);
176+ if (doSeparator)
177+ {
178+ optionValues += ",";
179+ }
180+ const string& curName = modelIt->first;
181+ optionValues += curName;
182+ doSeparator = true;
183+ }
184+ options_["model"] = Scene::Option("model", "bunny", "Which model to use",
185+ optionValues);
186+ optionValues = "";
187+ const TextureMap& textureMap = Texture::find_textures();
188+ for (TextureMap::const_iterator textureIt = textureMap.begin();
189+ textureIt != textureMap.end();
190+ textureIt++)
191+ {
192+ static bool doSeparator(false);
193+ if (doSeparator)
194+ {
195+ optionValues += ",";
196+ }
197+ const string& curName = textureIt->first;
198+ optionValues += curName;
199+ doSeparator = true;
200+ }
201+ options_["texture"] = Scene::Option("texture", "nasa1", "Which texture to use",
202+ optionValues);
203+ options_["index"] = Scene::Option("index", "1.2",
204+ "Index of refraction of the medium to simulate");
205+ options_["use-vbo"] = Scene::Option("use-vbo", "true",
206+ "Whether to use VBOs for rendering",
207+ "false,true");
208+ options_["interleave"] = Scene::Option("interleave", "false",
209+ "Whether to interleave vertex attribute data",
210+ "false,true");
211+}
212+
213+bool
214+SceneRefract::supported(bool show_errors)
215+{
216+ static const string oes_depth_texture("GL_OES_depth_texture");
217+ static const string arb_depth_texture("GL_ARB_depth_texture");
218+ if (!GLExtensions::support(oes_depth_texture) &&
219+ !GLExtensions::support(arb_depth_texture)) {
220+ if (show_errors) {
221+ Log::error("We do not have the depth texture extension!!!\n");
222+ }
223+
224+ return false;
225+ }
226+ return true;
227+}
228+
229+bool
230+SceneRefract::load()
231+{
232+ running_ = false;
233+ return true;
234+}
235+
236+void
237+SceneRefract::unload()
238+{
239+}
240+
241+bool
242+SceneRefract::setup()
243+{
244+ // If the scene isn't supported, don't bother to go through setup.
245+ if (!supported(false) || !Scene::setup())
246+ {
247+ return false;
248+ }
249+
250+ priv_ = new RefractPrivate(canvas_);
251+ if (!priv_->setup(options_)) {
252+ delete priv_;
253+ priv_ = 0;
254+ return false;
255+ }
256+
257+ // Set core scene timing after actual initialization so we don't measure
258+ // set up time.
259+ startTime_ = Util::get_timestamp_us() / 1000000.0;
260+ lastUpdateTime_ = startTime_;
261+ running_ = true;
262+
263+ return true;
264+}
265+
266+void
267+SceneRefract::teardown()
268+{
269+ // Add scene-specific teardown here
270+ priv_->teardown();
271+ delete priv_;
272+ Scene::teardown();
273+}
274+
275+void
276+SceneRefract::update()
277+{
278+ Scene::update();
279+ // Add scene-specific update here
280+ priv_->update(lastUpdateTime_ - startTime_);
281+}
282+
283+void
284+SceneRefract::draw()
285+{
286+ priv_->draw();
287+}
288+
289+Scene::ValidationResult
290+SceneRefract::validate()
291+{
292+ return Scene::ValidationUnknown;
293+}
294+
295+//
296+// Private interfaces
297+//
298+
299+bool
300+DistanceRenderTarget::setup(unsigned int width, unsigned int height)
301+{
302+ canvas_width_ = width;
303+ canvas_height_ = height;
304+ width_ = canvas_width_ * 2;
305+ height_ = canvas_height_ * 2;
306+
307+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/depth.vert");
308+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/depth.frag");
309+
310+ ShaderSource vtx_source(vtx_shader_filename);
311+ ShaderSource frg_source(frg_shader_filename);
312+
313+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
314+ return false;
315+ }
316+
317+ glGenTextures(2, &tex_[0]);
318+ glBindTexture(GL_TEXTURE_2D, tex_[DEPTH]);
319+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
320+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
321+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
322+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
323+ glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width_, height_, 0,
324+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 0);
325+ glBindTexture(GL_TEXTURE_2D, tex_[COLOR]);
326+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
327+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
328+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
329+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
330+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0,
331+ GL_RGBA, GL_UNSIGNED_BYTE, 0);
332+ glGenerateMipmap(GL_TEXTURE_2D);
333+ glBindTexture(GL_TEXTURE_2D, 0);
334+
335+ glGenFramebuffers(1, &fbo_);
336+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
337+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
338+ tex_[DEPTH], 0);
339+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
340+ tex_[COLOR], 0);
341+ unsigned int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
342+ if (status != GL_FRAMEBUFFER_COMPLETE) {
343+ Log::error("DepthRenderState::setup: glCheckFramebufferStatus failed (0x%x)\n", status);
344+ return false;
345+ }
346+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
347+
348+ return true;
349+}
350+
351+void
352+DistanceRenderTarget::teardown()
353+{
354+ program_.stop();
355+ program_.release();
356+ if (tex_) {
357+ glDeleteTextures(2, &tex_[0]);
358+ tex_[DEPTH] = tex_[COLOR] = 0;
359+ }
360+ if (fbo_) {
361+ glDeleteFramebuffers(1, &fbo_);
362+ fbo_ = 0;
363+ }
364+}
365+
366+void
367+DistanceRenderTarget::enable(const mat4& mvp)
368+{
369+ program_.start();
370+ program_["ModelViewProjectionMatrix"] = mvp;
371+ glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
372+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
373+ tex_[DEPTH], 0);
374+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
375+ tex_[COLOR], 0);
376+ glViewport(0, 0, width_, height_);
377+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
378+ glCullFace(GL_FRONT);
379+}
380+
381+void DistanceRenderTarget::disable()
382+{
383+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
384+ glViewport(0, 0, canvas_width_, canvas_height_);
385+ glCullFace(GL_BACK);
386+}
387+
388+bool
389+RefractPrivate::setup(map<string, Scene::Option>& options)
390+{
391+ // Program object setup
392+ static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.vert");
393+ static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-refract.frag");
394+ static const vec4 lightColor(0.4, 0.4, 0.4, 1.0);
395+
396+ ShaderSource vtx_source(vtx_shader_filename);
397+ ShaderSource frg_source(frg_shader_filename);
398+
399+ frg_source.add_const("LightColor", lightColor);
400+ frg_source.add_const("LightSourcePosition", lightPosition);
401+ float refractive_index(Util::fromString<float>(options["index"].value));
402+ frg_source.add_const("RefractiveIndex", refractive_index);
403+
404+ if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) {
405+ return false;
406+ }
407+
408+ const string& whichTexture(options["texture"].value);
409+ if (!Texture::load(whichTexture, &texture_, GL_LINEAR, GL_LINEAR, 0))
410+ return false;
411+
412+ // Model setup
413+ Model model;
414+ const string& whichModel(options["model"].value);
415+ bool modelLoaded = model.load(whichModel);
416+
417+ if(!modelLoaded)
418+ return false;
419+
420+ // Now that we're successfully loaded, there are a few quirks about
421+ // some of the known models that we need to account for. The draw
422+ // logic for the scene wants to rotate the model around the Y axis.
423+ // Most of our models are described this way. Some need adjustment
424+ // (an additional rotation that gets the model into the correct
425+ // orientation).
426+ //
427+ // Here's a summary:
428+ //
429+ // Angel rotates around the Y axis
430+ // Armadillo rotates around the Y axis
431+ // Buddha rotates around the X axis
432+ // Bunny rotates around the Y axis
433+ // Dragon rotates around the X axis
434+ // Horse rotates around the Y axis
435+ if (whichModel == "buddha" || whichModel == "dragon")
436+ {
437+ orientModel_ = true;
438+ orientationAngle_ = -90.0;
439+ orientationVec_ = vec3(1.0, 0.0, 0.0);
440+ }
441+ else if (whichModel == "armadillo")
442+ {
443+ orientModel_ = true;
444+ orientationAngle_ = 180.0;
445+ orientationVec_ = vec3(0.0, 1.0, 0.0);
446+ }
447+
448+ model.calculate_normals();
449+
450+ // Mesh setup
451+ vector<std::pair<Model::AttribType, int> > attribs;
452+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3));
453+ attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3));
454+ model.convert_to_mesh(mesh_, attribs);
455+
456+ useVbo_ = (options["use-vbo"].value == "true");
457+ bool interleave = (options["interleave"].value == "true");
458+ mesh_.vbo_update_method(Mesh::VBOUpdateMethodMap);
459+ mesh_.interleave(interleave);
460+
461+ if (useVbo_) {
462+ mesh_.build_vbo();
463+ }
464+ else {
465+ mesh_.build_array();
466+ }
467+
468+ // Calculate a projection matrix that is a good fit for the model
469+ vec3 maxVec = model.maxVec();
470+ vec3 minVec = model.minVec();
471+ vec3 diffVec = maxVec - minVec;
472+ centerVec_ = maxVec + minVec;
473+ centerVec_ /= 2.0;
474+ float diameter = diffVec.length();
475+ radius_ = diameter / 2;
476+ float fovy = 2.0 * atanf(radius_ / (2.0 + radius_));
477+ fovy /= M_PI;
478+ fovy *= 180.0;
479+ float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height()));
480+ projection_.perspective(fovy, aspect, 2.0, 2.0 + diameter);
481+
482+ // Set up the light matrix with a bias that will convert values
483+ // in the range of [-1, 1] to [0, 1)], then add in the projection
484+ // and the "look at" matrix from the light position.
485+ light_ *= LibMatrix::Mat4::translate(0.5, 0.5, 0.5);
486+ light_ *= LibMatrix::Mat4::scale(0.5, 0.5, 0.5);
487+ light_ *= projection_.getCurrent();
488+ light_ *= LibMatrix::Mat4::lookAt(lightPosition.x(), lightPosition.y(), lightPosition.z(),
489+ 0.0, 0.0, 0.0,
490+ 0.0, 1.0, 0.0);
491+
492+ if (!depthTarget_.setup(canvas_.width(), canvas_.height())) {
493+ Log::error("Failed to set up the render target for the depth pass\n");
494+ return false;
495+ }
496+
497+ return true;
498+}
499+void
500+RefractPrivate::teardown()
501+{
502+ depthTarget_.teardown();
503+ program_.stop();
504+ program_.release();
505+ mesh_.reset();
506+}
507+
508+void
509+RefractPrivate::update(double elapsedTime)
510+{
511+ rotation_ = rotationSpeed_ * elapsedTime;
512+}
513+
514+void
515+RefractPrivate::draw()
516+{
517+ // To perform the depth pass, set up the model-view transformation so
518+ // that we're looking at the horse from the light position. That will
519+ // give us the appropriate view for the shadow.
520+ modelview_.push();
521+ modelview_.loadIdentity();
522+ modelview_.lookAt(lightPosition.x(), lightPosition.y(), lightPosition.z(),
523+ 0.0, 0.0, 0.0,
524+ 0.0, 1.0, 0.0);
525+ modelview_.rotate(rotation_, 0.0f, 1.0f, 0.0f);
526+ if (orientModel_)
527+ {
528+ modelview_.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
529+ }
530+ mat4 mvp(projection_.getCurrent());
531+ mvp *= modelview_.getCurrent();
532+ modelview_.pop();
533+
534+ // Enable the depth render target with our transformation and render.
535+ depthTarget_.enable(mvp);
536+ vector<GLint> attrib_locations;
537+ attrib_locations.push_back(depthTarget_.program()["position"].location());
538+ attrib_locations.push_back(depthTarget_.program()["normal"].location());
539+ mesh_.set_attrib_locations(attrib_locations);
540+ if (useVbo_) {
541+ mesh_.render_vbo();
542+ }
543+ else {
544+ mesh_.render_array();
545+ }
546+ depthTarget_.disable();
547+
548+ // Draw the "normal" view of the horse
549+ modelview_.push();
550+ modelview_.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.0 + radius_));
551+ modelview_.rotate(rotation_, 0.0f, 1.0f, 0.0f);
552+ if (orientModel_)
553+ {
554+ modelview_.rotate(orientationAngle_, orientationVec_.x(), orientationVec_.y(), orientationVec_.z());
555+ }
556+ mvp = projection_.getCurrent();
557+ mvp *= modelview_.getCurrent();
558+
559+ program_.start();
560+ glActiveTexture(GL_TEXTURE0);
561+ glBindTexture(GL_TEXTURE_2D, depthTarget_.depthTexture());
562+ program_["DistanceMap"] = 0;
563+ glActiveTexture(GL_TEXTURE1);
564+ glBindTexture(GL_TEXTURE_2D, depthTarget_.colorTexture());
565+ program_["NormalMap"] = 1;
566+ glActiveTexture(GL_TEXTURE2);
567+ glBindTexture(GL_TEXTURE_2D, texture_);
568+ program_["ImageMap"] = 2;
569+ // Load both the modelview*projection as well as the modelview matrix itself
570+ program_["ModelViewProjectionMatrix"] = mvp;
571+ program_["ModelViewMatrix"] = modelview_.getCurrent();
572+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
573+ // inverse transpose of the model view matrix.
574+ mat4 normal_matrix(modelview_.getCurrent());
575+ normal_matrix.inverse().transpose();
576+ program_["NormalMatrix"] = normal_matrix;
577+ program_["LightMatrix"] = light_;
578+ attrib_locations.clear();
579+ attrib_locations.push_back(program_["position"].location());
580+ attrib_locations.push_back(program_["normal"].location());
581+ mesh_.set_attrib_locations(attrib_locations);
582+ if (useVbo_) {
583+ mesh_.render_vbo();
584+ }
585+ else {
586+ mesh_.render_array();
587+ }
588+
589+ // Per-frame cleanup
590+ modelview_.pop();
591+}
592+
593
594=== added file 'src/scene-refract.h'
595--- src/scene-refract.h 1970-01-01 00:00:00 +0000
596+++ src/scene-refract.h 2012-12-15 09:48:22 +0000
597@@ -0,0 +1,106 @@
598+//
599+// Copyright © 2012 Linaro Limited
600+//
601+// This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
602+//
603+// glmark2 is free software: you can redistribute it and/or modify it under the
604+// terms of the GNU General Public License as published by the Free Software
605+// Foundation, either version 3 of the License, or (at your option) any later
606+// version.
607+//
608+// glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
609+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
610+// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
611+// details.
612+//
613+// You should have received a copy of the GNU General Public License along with
614+// glmark2. If not, see <http://www.gnu.org/licenses/>.
615+//
616+// Authors:
617+// Jesse Barker
618+//
619+#ifndef SCENE_REFRACT_
620+#define SCENE_REFRACT_
621+
622+#include "scene.h"
623+#include "stack.h"
624+
625+//
626+// To create a shadow map, we need a framebuffer object set up for a
627+// depth-only pass. The render target can then be bound as a texture,
628+// and the depth values sampled from that texture can be used in the
629+// distance-from-light computations when rendering the shadow on the
630+// ground below the rendered object.
631+//
632+class DistanceRenderTarget
633+{
634+ enum
635+ {
636+ DEPTH = 0,
637+ COLOR
638+ };
639+ Program program_;
640+ unsigned int canvas_width_;
641+ unsigned int canvas_height_;
642+ unsigned int width_;
643+ unsigned int height_;
644+ unsigned int tex_[2];
645+ unsigned int fbo_;
646+public:
647+ DistanceRenderTarget() :
648+ canvas_width_(0),
649+ canvas_height_(0),
650+ width_(0),
651+ height_(0),
652+ fbo_(0)
653+ {
654+ tex_[DEPTH] = tex_[COLOR] = 0;
655+ }
656+ ~DistanceRenderTarget() {}
657+ bool setup(unsigned int width, unsigned int height);
658+ void teardown();
659+ void enable(const LibMatrix::mat4& mvp);
660+ void disable();
661+ unsigned int depthTexture() { return tex_[DEPTH]; }
662+ unsigned int colorTexture() { return tex_[COLOR]; }
663+ Program& program() { return program_; }
664+};
665+
666+class RefractPrivate
667+{
668+ Canvas& canvas_;
669+ DistanceRenderTarget depthTarget_;
670+ Program program_;
671+ LibMatrix::Stack4 modelview_;
672+ LibMatrix::Stack4 projection_;
673+ LibMatrix::mat4 light_;
674+ Mesh mesh_;
675+ LibMatrix::vec3 centerVec_;
676+ bool orientModel_;
677+ float orientationAngle_;
678+ LibMatrix::vec3 orientationVec_;
679+ float radius_;
680+ float rotation_;
681+ float rotationSpeed_;
682+ unsigned int texture_;
683+ bool useVbo_;
684+
685+public:
686+ RefractPrivate(Canvas& canvas) :
687+ canvas_(canvas),
688+ orientModel_(false),
689+ orientationAngle_(0.0),
690+ radius_(0.0),
691+ rotation_(0.0),
692+ rotationSpeed_(36.0),
693+ texture_(0),
694+ useVbo_(true) {}
695+ ~RefractPrivate() {}
696+
697+ bool setup(std::map<std::string, Scene::Option>& options);
698+ void teardown();
699+ void update(double elapsedTime);
700+ void draw();
701+};
702+
703+#endif // SCENE_REFRACT_
704
705=== modified file 'src/scene.h'
706--- src/scene.h 2012-10-19 13:19:19 +0000
707+++ src/scene.h 2012-12-15 09:48:22 +0000
708@@ -574,4 +574,20 @@
709 ValidationResult validate();
710 };
711
712+class RefractPrivate;
713+class SceneRefract : public Scene
714+{
715+ RefractPrivate* priv_;
716+public:
717+ SceneRefract(Canvas& canvas);
718+ bool supported(bool show_errors);
719+ bool load();
720+ void unload();
721+ bool setup();
722+ void teardown();
723+ void update();
724+ void draw();
725+ ValidationResult validate();
726+};
727+
728 #endif

Subscribers

People subscribed via source and target branches

to all changes: