aboutsummaryrefslogtreecommitdiff
path: root/src/scene-ideas/lamp.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/scene-ideas/lamp.cc')
-rw-r--r--src/scene-ideas/lamp.cc258
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);
+}