diff options
author | Jesse Barker <jesse.barker@linaro.org> | 2012-10-22 09:17:26 -0700 |
---|---|---|
committer | Jesse Barker <jesse.barker@linaro.org> | 2012-10-22 09:17:26 -0700 |
commit | 7c261a377a5567cfaadb802fe297c2c10047201c (patch) | |
tree | 3f8322e2a1e9d1e02c5ae26888c2c10ac74f07ee | |
parent | 149d52c460b32ca2d93cb66a8bf8dd2939deca06 (diff) | |
download | glmark2-7c261a377a5567cfaadb802fe297c2c10047201c.tar.gz |
SceneShadow: Add sufficient setup, update, and draw code to get the "normal"
view of the horse going.
-rw-r--r-- | src/scene-shadow.cpp | 170 |
1 files changed, 165 insertions, 5 deletions
diff --git a/src/scene-shadow.cpp b/src/scene-shadow.cpp index 18f2cb5..975f842 100644 --- a/src/scene-shadow.cpp +++ b/src/scene-shadow.cpp @@ -20,19 +20,172 @@ // Jesse Barker // #include "scene.h" +#include "model.h" #include "util.h" #include "log.h" +#include "shader-source.h" +#include "stack.h" using std::string; +using std::vector; +using std::map; +using LibMatrix::Stack4; +using LibMatrix::mat4; +using LibMatrix::vec4; +using LibMatrix::vec3; + +static const vec4 lightPosition(0.0f, 3.0f, 2.0f, 1.0f); class ShadowPrivate { + Canvas& canvas_; + Program program_; + Stack4 modelview_; + Stack4 projection_; + Mesh mesh_; + vec3 centerVec_; + float radius_; + float rotation_; + float rotationSpeed_; + bool useVbo_; + +public: + ShadowPrivate(Canvas& canvas) : + canvas_(canvas), + radius_(0.0), + rotation_(0.0), + rotationSpeed_(36.0), + useVbo_(true) {} + ~ShadowPrivate() {} + + bool setup(map<string, Scene::Option>& options); + void teardown(); + void update(double elapsedTime); + void draw(); }; +bool +ShadowPrivate::setup(map<string, Scene::Option>& options) +{ + // Program object setup + static const string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert"); + static const string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.frag"); + static const vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f); + + ShaderSource vtx_source(vtx_shader_filename); + ShaderSource frg_source(frg_shader_filename); + + vtx_source.add_const("LightSourcePosition", lightPosition); + vtx_source.add_const("MaterialDiffuse", materialDiffuse); + + if (!Scene::load_shaders_from_strings(program_, vtx_source.str(), frg_source.str())) { + return false; + } + + // Model setup + Model::find_models(); + Model model; + bool modelLoaded = model.load("horse"); + + if(!modelLoaded) { + return false; + } + + model.calculate_normals(); + + // Mesh setup + vector<std::pair<Model::AttribType, int> > attribs; + attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypePosition, 3)); + attribs.push_back(std::pair<Model::AttribType, int>(Model::AttribTypeNormal, 3)); + model.convert_to_mesh(mesh_, attribs); + + useVbo_ = (options["use-vbo"].value == "true"); + bool interleave = (options["interleave"].value == "true"); + mesh_.vbo_update_method(Mesh::VBOUpdateMethodMap); + mesh_.interleave(interleave); + + if (useVbo_) { + mesh_.build_vbo(); + } + else { + mesh_.build_array(); + } + + // Calculate a projection matrix that is a good fit for the model + vec3 maxVec = model.maxVec(); + vec3 minVec = model.minVec(); + vec3 diffVec = maxVec - minVec; + centerVec_ = maxVec + minVec; + centerVec_ /= 2.0; + float diameter = diffVec.length(); + radius_ = diameter / 2; + float fovy = 2.0 * atanf(radius_ / (2.0 + radius_)); + fovy /= M_PI; + fovy *= 180.0; + float aspect(static_cast<float>(canvas_.width())/static_cast<float>(canvas_.height())); + projection_.perspective(fovy, aspect, 2.0, 2.0 + diameter); + + return true; +} + + +void +ShadowPrivate::teardown() +{ + program_.stop(); + program_.release(); + mesh_.reset(); +} + +void +ShadowPrivate::update(double elapsedTime) +{ + rotation_ = rotationSpeed_ * elapsedTime; +} + +void +ShadowPrivate::draw() +{ + // Draw the "normal" view of the horse + modelview_.push(); + modelview_.translate(-centerVec_.x(), -centerVec_.y(), -(centerVec_.z() + 2.0 + radius_)); + modelview_.rotate(rotation_, 0.0f, 1.0f, 0.0f); + mat4 mvp(projection_.getCurrent()); + mvp *= modelview_.getCurrent(); + + program_.start(); + program_["ModelViewProjectionMatrix"] = mvp; + + // Load the NormalMatrix uniform in the shader. The NormalMatrix is the + // inverse transpose of the model view matrix. + LibMatrix::mat4 normal_matrix(modelview_.getCurrent()); + normal_matrix.inverse().transpose(); + program_["NormalMatrix"] = normal_matrix; + vector<GLint> attrib_locations; + attrib_locations.push_back(program_["position"].location()); + attrib_locations.push_back(program_["normal"].location()); + mesh_.set_attrib_locations(attrib_locations); + if (useVbo_) { + mesh_.render_vbo(); + } + else { + mesh_.render_array(); + } + + // Per-frame cleanup + modelview_.pop(); +} + SceneShadow::SceneShadow(Canvas& canvas) : Scene(canvas, "shadow"), priv_(0) { + options_["use-vbo"] = Scene::Option("use-vbo", "true", + "Whether to use VBOs for rendering", + "false,true"); + options_["interleave"] = Scene::Option("interleave", "false", + "Whether to interleave vertex attribute data", + "false,true"); } SceneShadow::~SceneShadow() @@ -46,10 +199,8 @@ SceneShadow::supported(bool show_errors) static const string oes_depth_texture("GL_OES_depth_texture"); static const string arb_depth_texture("GL_ARB_depth_texture"); if (!GLExtensions::support(oes_depth_texture) && - !GLExtensions::support(arb_depth_texture)) - { - if (show_errors) - { + !GLExtensions::support(arb_depth_texture)) { + if (show_errors) { Log::error("We do not have the depth texture extension!!!\n"); } @@ -79,7 +230,13 @@ SceneShadow::setup() return false; } - priv_ = new ShadowPrivate(); + priv_ = new ShadowPrivate(canvas_); + if (!priv_->setup(options_)) { + delete priv_; + priv_ = 0; + return false; + } + // Set core scene timing after actual initialization so we don't measure // set up time. startTime_ = Util::get_timestamp_us() / 1000000.0; @@ -93,6 +250,7 @@ void SceneShadow::teardown() { // Add scene-specific teardown here + priv_->teardown(); Scene::teardown(); } @@ -101,11 +259,13 @@ SceneShadow::update() { Scene::update(); // Add scene-specific update here + priv_->update(lastUpdateTime_ - startTime_); } void SceneShadow::draw() { + priv_->draw(); } Scene::ValidationResult |