diff options
Diffstat (limited to 'src/scene-ideas/lamp.cc')
-rw-r--r-- | src/scene-ideas/lamp.cc | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/src/scene-ideas/lamp.cc b/src/scene-ideas/lamp.cc new file mode 100644 index 0000000..aaf3b10 --- /dev/null +++ b/src/scene-ideas/lamp.cc @@ -0,0 +1,258 @@ +/* + * Vertex position data describing the lamp + * + * (c) Copyright 1993, Silicon Graphics, Inc. + * Copyright © 2012 Linaro Limited + * + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. + * + * glmark2 is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * glmark2. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: + * Jesse Barker + */ +#include "lamp.h" +#include "shader-source.h" +#include "log.h" +#include "scene.h" + +using std::string; +using LibMatrix::vec3; +using LibMatrix::vec4; +using LibMatrix::Stack4; + +const string Lamp::modelviewName_("modelview"); +const string Lamp::projectionName_("projection"); +const string Lamp::light0PositionName_("light0Position"); +const string Lamp::light1PositionName_("light1Position"); +const string Lamp::light2PositionName_("light2Position"); +const string Lamp::vertexAttribName_("vertex"); +const string Lamp::normalAttribName_("normal"); +const string Lamp::normalMatrixName_("normalMatrix"); + +Lamp::Lamp() : + valid_(false) +{ + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.000000, 0.000000, 1.000000)); + vertexData_.push_back(vec3(0.438371, 0.000000, 0.898794)); + vertexData_.push_back(vec3(0.379641, 0.219186, 0.898794)); + vertexData_.push_back(vec3(0.219186, 0.379641, 0.898794)); + vertexData_.push_back(vec3(0.000000, 0.438371, 0.898794)); + vertexData_.push_back(vec3(-0.219186, 0.379641, 0.898794)); + vertexData_.push_back(vec3(-0.379641, 0.219186, 0.898794)); + vertexData_.push_back(vec3(-0.438371, 0.000000, 0.898794)); + vertexData_.push_back(vec3(-0.379641, -0.219186, 0.898794)); + vertexData_.push_back(vec3(-0.219186, -0.379641, 0.898794)); + vertexData_.push_back(vec3(0.000000, -0.438371, 0.898794)); + vertexData_.push_back(vec3(0.219186, -0.379641, 0.898794)); + vertexData_.push_back(vec3(0.379641, -0.219186, 0.898794)); + vertexData_.push_back(vec3(0.438371, 0.000000, 0.898794)); + vertexData_.push_back(vec3(0.788011, 0.000000, 0.615662)); + vertexData_.push_back(vec3(0.682437, 0.394005, 0.615662)); + vertexData_.push_back(vec3(0.394005, 0.682437, 0.615662)); + vertexData_.push_back(vec3(0.000000, 0.788011, 0.615662)); + vertexData_.push_back(vec3(-0.394005, 0.682437, 0.615662)); + vertexData_.push_back(vec3(-0.682437, 0.394005, 0.615662)); + vertexData_.push_back(vec3(-0.788011, 0.000000, 0.615662)); + vertexData_.push_back(vec3(-0.682437, -0.394005, 0.615662)); + vertexData_.push_back(vec3(-0.394005, -0.682437, 0.615662)); + vertexData_.push_back(vec3(0.000000, -0.788011, 0.615662)); + vertexData_.push_back(vec3(0.394005, -0.682437, 0.615662)); + vertexData_.push_back(vec3(0.682437, -0.394005, 0.615662)); + vertexData_.push_back(vec3(0.788011, 0.000000, 0.615662)); + vertexData_.push_back(vec3(0.978148, 0.000000, 0.207912)); + vertexData_.push_back(vec3(0.847101, 0.489074, 0.207912)); + vertexData_.push_back(vec3(0.489074, 0.847101, 0.207912)); + vertexData_.push_back(vec3(0.000000, 0.978148, 0.207912)); + vertexData_.push_back(vec3(-0.489074, 0.847101, 0.207912)); + vertexData_.push_back(vec3(-0.847101, 0.489074, 0.207912)); + vertexData_.push_back(vec3(-0.978148, 0.000000, 0.207912)); + vertexData_.push_back(vec3(-0.847101, -0.489074, 0.207912)); + vertexData_.push_back(vec3(-0.489074, -0.847101, 0.207912)); + vertexData_.push_back(vec3(0.000000, -0.978148, 0.207912)); + vertexData_.push_back(vec3(0.489074, -0.847101, 0.207912)); + vertexData_.push_back(vec3(0.847101, -0.489074, 0.207912)); + vertexData_.push_back(vec3(0.978148, 0.000000, 0.207912)); + vertexData_.push_back(vec3(0.970296, 0.000000, -0.241922)); + vertexData_.push_back(vec3(0.840301, 0.485148, -0.241922)); + vertexData_.push_back(vec3(0.485148, 0.840301, -0.241922)); + vertexData_.push_back(vec3(0.000000, 0.970296, -0.241922)); + vertexData_.push_back(vec3(-0.485148, 0.840301, -0.241922)); + vertexData_.push_back(vec3(-0.840301, 0.485148, -0.241922)); + vertexData_.push_back(vec3(-0.970296, 0.000000, -0.241922)); + vertexData_.push_back(vec3(-0.840301, -0.485148, -0.241922)); + vertexData_.push_back(vec3(-0.485148, -0.840301, -0.241922)); + vertexData_.push_back(vec3(0.000000, -0.970296, -0.241922)); + vertexData_.push_back(vec3(0.485148, -0.840301, -0.241922)); + vertexData_.push_back(vec3(0.840301, -0.485148, -0.241922)); + vertexData_.push_back(vec3(0.970296, 0.000000, -0.241922)); + vertexData_.push_back(vec3(0.766044, 0.000000, -0.642788)); + vertexData_.push_back(vec3(0.663414, 0.383022, -0.642788)); + vertexData_.push_back(vec3(0.383022, 0.663414, -0.642788)); + vertexData_.push_back(vec3(0.000000, 0.766044, -0.642788)); + vertexData_.push_back(vec3(-0.383022, 0.663414, -0.642788)); + vertexData_.push_back(vec3(-0.663414, 0.383022, -0.642788)); + vertexData_.push_back(vec3(-0.766044, 0.000000, -0.642788)); + vertexData_.push_back(vec3(-0.663414, -0.383022, -0.642788)); + vertexData_.push_back(vec3(-0.383022, -0.663414, -0.642788)); + vertexData_.push_back(vec3(0.000000, -0.766044, -0.642788)); + vertexData_.push_back(vec3(0.383022, -0.663414, -0.642788)); + vertexData_.push_back(vec3(0.663414, -0.383022, -0.642788)); + vertexData_.push_back(vec3(0.766044, 0.000000, -0.642788)); + + // + // The original implementation of both the logo and the lamp represented + // the vertex and normal data in a triply-dimensioned array of floats and + // all of the calls referenced double-indexed arrays of vector data. + // To my mind, this made the code look clunky and overly verbose. + // Representing the data as a STL vector of vec3 (itself a 3-float vector + // quantity) provides both an efficient container and allows for more + // concise looking code. The slightly goofy loops (using the original 2 + // dimensional indices to compute a single offset into the STL vector) are + // a compromise to avoid rearranging the original data. + // + // - jesse 2010/10/04 + // + for (unsigned int i = 0; i < 5; i++) + { + for (unsigned int j = 0; j < 13; j++) + { + indexData_.push_back(i * 13 + j); + indexData_.push_back((i + 1) * 13 + j); + } + } + unsigned int curIndex(5 * 13); + for (unsigned int i = 0; i < 12; i++) + { + indexData_.push_back(curIndex + i); + } +} + +Lamp::~Lamp() +{ + if (valid_) + { + glDeleteBuffers(2, &bufferObjects_[0]); + } +} + +void +Lamp::init() +{ + // Make sure we don't re-initialize... + if (valid_) + { + return; + } + + // Initialize shader sources from input files and create programs from them + // The program for handling lighting... + string lit_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-lit.vert"); + string lit_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-lit.frag"); + ShaderSource lit_vtx_source(lit_vtx_filename); + ShaderSource lit_frg_source(lit_frg_filename); + if (!Scene::load_shaders_from_strings(litProgram_, lit_vtx_source.str(), + lit_frg_source.str())) + { + Log::error("No valid program for lit lamp rendering\n"); + return; + } + + // The simple program with no lighting... + string unlit_vtx_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-unlit.vert"); + string unlit_frg_filename(GLMARK_DATA_PATH"/shaders/ideas-lamp-unlit.frag"); + ShaderSource unlit_vtx_source(unlit_vtx_filename); + ShaderSource unlit_frg_source(unlit_frg_filename); + if (!Scene::load_shaders_from_strings(unlitProgram_, unlit_vtx_source.str(), + unlit_frg_source.str())) + { + Log::error("No valid program for unlit lamp rendering.\n"); + return; + } + + // We need 2 buffers for our work here. One for the vertex data. + // and one for the index data. + glGenBuffers(2, &bufferObjects_[0]); + + // First, setup the vertex data by binding the first buffer object, + // allocating its data store, and filling it in with our vertex data. + glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]); + glBufferData(GL_ARRAY_BUFFER, vertexData_.size() * sizeof(vec3), &vertexData_.front(), GL_STATIC_DRAW); + + // Now repeat for our index data. + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexData_.size() * sizeof(unsigned short), &indexData_.front(), GL_STATIC_DRAW); + + // We're ready to go. + valid_ = true; +} + +void +Lamp::draw(Stack4& modelview, Stack4& projection, const vec4* lightPositions) +{ + glBindBuffer(GL_ARRAY_BUFFER, bufferObjects_[0]); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufferObjects_[1]); + + litProgram_.start(); + int vertexIndex(litProgram_[vertexAttribName_].location()); + int normalIndex(litProgram_[normalAttribName_].location()); + glVertexAttribPointer(vertexIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); + glVertexAttribPointer(normalIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(vertexIndex); + glEnableVertexAttribArray(normalIndex); + const LibMatrix::mat4& mv = modelview.getCurrent(); + LibMatrix::mat3 normalMatrix(mv[0][0], mv[1][0], mv[2][0], + mv[0][1], mv[1][1], mv[2][1], + mv[0][2], mv[1][2], mv[2][2]); + normalMatrix.transpose().inverse(); + litProgram_[normalMatrixName_] = normalMatrix; + litProgram_[modelviewName_] = mv; + litProgram_[projectionName_] = projection.getCurrent(); + litProgram_[light0PositionName_] = lightPositions[0]; + litProgram_[light1PositionName_] = lightPositions[1]; + litProgram_[light2PositionName_] = lightPositions[2]; + static const unsigned int sus(sizeof(unsigned short)); + for (unsigned int i = 0; i < 5; i++) + { + glDrawElements(GL_TRIANGLE_STRIP, 26, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid*>(i * 26 * sus)); + } + glDisableVertexAttribArray(normalIndex); + glDisableVertexAttribArray(vertexIndex); + litProgram_.stop(); + + unlitProgram_.start(); + vertexIndex = unlitProgram_[vertexAttribName_].location(); + glVertexAttribPointer(vertexIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(vertexIndex); + unlitProgram_[modelviewName_] = mv; + unlitProgram_[projectionName_] = projection.getCurrent(); + glDrawElements(GL_TRIANGLE_FAN, 12, GL_UNSIGNED_SHORT, reinterpret_cast<const GLvoid*>(5 * 26 * sus)); + glDisableVertexAttribArray(vertexIndex); + unlitProgram_.stop(); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} |