=== added file 'data/shaders/pulsar-light.vert'
@@ -0,0 +1,31 @@
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec4 vtxcolor;
+attribute vec2 texcoord;
+
+uniform mat4 ModelViewProjectionMatrix;
+uniform mat4 NormalMatrix;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ // Transform the normal to eye coordinates
+ vec3 N = normalize(vec3(NormalMatrix * vec4(normal, 1.0)));
+
+ // The LightSourcePosition is actually its direction for directional light
+ vec3 L = normalize(LightSourcePosition.xyz);
+
+ // Multiply the diffuse value by the vertex color
+ // to get the actual color that we will use to draw this vertex with
+ float diffuse = max(abs(dot(N, L)), 0.0);
+ Color = diffuse * vtxcolor;
+
+ // Set the texture coordinates as a varying
+ TextureCoord = texcoord;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
+
=== added file 'data/shaders/pulsar.vert'
@@ -0,0 +1,19 @@
+attribute vec3 position;
+attribute vec4 vtxcolor;
+attribute vec2 texcoord;
+attribute vec3 normal;
+
+uniform mat4 ModelViewProjectionMatrix;
+
+varying vec4 Color;
+varying vec2 TextureCoord;
+
+void main(void)
+{
+ Color = vtxcolor;
+ TextureCoord = texcoord;
+
+ // Transform the position to clip coordinates
+ gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0);
+}
+
=== modified file 'src/android.cpp'
@@ -43,6 +43,7 @@
"bump:bump-render=normals",
"effect2d:kernel=0,1,0;1,-4,1;0,1,0;",
"effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",
+ "pulsar:quads=5:texture=false:light=false",
"conditionals:vertex-steps=0:fragment-steps=0",
"conditionals:vertex-steps=0:fragment-steps=5",
"conditionals:vertex-steps=5:fragment-steps=0",
@@ -83,6 +84,7 @@
Benchmark::register_scene(*new SceneLoop(*g_canvas));
Benchmark::register_scene(*new SceneBump(*g_canvas));
Benchmark::register_scene(*new SceneEffect2D(*g_canvas));
+ Benchmark::register_scene(*new ScenePulsar(*g_canvas));
add_default_benchmarks(g_benchmarks);
=== modified file 'src/main.cpp'
@@ -52,6 +52,7 @@
"bump:bump-render=normals",
"effect2d:kernel=0,1,0;1,-4,1;0,1,0;",
"effect2d:kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;",
+ "pulsar:quads=5:texture=false:light=false",
"conditionals:vertex-steps=0:fragment-steps=0",
"conditionals:vertex-steps=0:fragment-steps=5",
"conditionals:vertex-steps=5:fragment-steps=0",
@@ -229,6 +230,7 @@
Benchmark::register_scene(*new SceneLoop(canvas));
Benchmark::register_scene(*new SceneBump(canvas));
Benchmark::register_scene(*new SceneEffect2D(canvas));
+ Benchmark::register_scene(*new ScenePulsar(canvas));
if (Options::list_scenes) {
list_scenes();
=== added file 'src/scene-pulsar.cpp'
@@ -0,0 +1,294 @@
+/*
+ * Copyright © 2008 Ben Smith
+ * Copyright © 2010-2011 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:
+ * Ben Smith (original glmark benchmark)
+ * Alexandros Frantzis (glmark2)
+ * Marc Ordinas i Llopis, Collabora Ltd. (pulsar scene)
+ */
+#include "scene.h"
+#include "mat.h"
+#include "stack.h"
+#include "vec.h"
+#include "log.h"
+#include "program.h"
+#include "shader-source.h"
+
+#include <cmath>
+
+ScenePulsar::ScenePulsar(Canvas &pCanvas) :
+ Scene(pCanvas, "pulsar"),
+ mTexture(0)
+{
+ mOptions["quads"] = Scene::Option("quads", "5", "Number of quads to render");
+ mOptions["texture"] = Scene::Option("texture", "false", "Enable texturing");
+ mOptions["light"] = Scene::Option("light", "false", "Enable lighting");
+ mOptions["random"] = Scene::Option("random", "false", "Enable random rotation speeds");
+}
+
+ScenePulsar::~ScenePulsar()
+{
+}
+
+int ScenePulsar::load()
+{
+ mScale = LibMatrix::vec3(1.0, 1.0, 1.0);
+
+ mRunning = false;
+
+ return 1;
+}
+
+void ScenePulsar::unload()
+{
+}
+
+void ScenePulsar::setup()
+{
+ Scene::setup();
+
+ // Disable back-face culling
+ glDisable(GL_CULL_FACE);
+ // Enable alpha blending
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // Create a rotation for each quad.
+ std::stringstream ss;
+ ss << mOptions["quads"].value;
+ ss >> mNumQuads;
+
+ srand((unsigned)time(0));
+ for (int i = 0; i < mNumQuads; i++) {
+ mRotations.push_back(LibMatrix::vec3());
+ if (mOptions["random"].value == "true") {
+ mRotationSpeeds.push_back(LibMatrix::vec3(((float)rand() / (float)RAND_MAX) * 5.0,
+ ((float)rand() / (float)RAND_MAX) * 5.0,
+ 0.0));
+ }
+ else {
+ float integral;
+ float x_rot = std::modf((i + 1) * M_PI, &integral);
+ float y_rot = std::modf((i + 1) * M_E, &integral);
+ mRotationSpeeds.push_back(LibMatrix::vec3(x_rot * 5.0,
+ y_rot * 5.0,
+ 0.0));
+ }
+ }
+
+ // Load shaders
+ std::string vtx_shader_filename;
+ std::string frg_shader_filename;
+ static const LibMatrix::vec4 lightPosition(-20.0f, 20.0f,-20.0f, 1.0f);
+ if (mOptions["light"].value == "true") {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/pulsar-light.vert";
+ } else {
+ vtx_shader_filename = GLMARK_DATA_PATH"/shaders/pulsar.vert";
+ }
+
+ if (mOptions["texture"].value == "true") {
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic-tex.frag";
+ Texture::load(GLMARK_DATA_PATH"/textures/crate-base.png", &mTexture,
+ GL_NEAREST, GL_NEAREST, 0);
+
+ } else {
+ frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-basic.frag";
+ }
+
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+ if (mOptions["light"].value == "true") {
+ // Load the light position constant
+ vtx_source.add_const("LightSourcePosition", lightPosition);
+ }
+
+ if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
+ frg_source.str()))
+ {
+ return;
+ }
+
+ create_and_setup_mesh();
+
+ mProgram.start();
+
+ mCurrentFrame = 0;
+
+ mRunning = true;
+ mStartTime = Scene::get_timestamp_us() / 1000000.0;
+ mLastUpdateTime = mStartTime;
+}
+
+void ScenePulsar::teardown()
+{
+ mProgram.stop();
+ mProgram.release();
+
+ if (mOptions["texture"].value == "true") {
+ glDeleteTextures(1, &mTexture);
+ mTexture = 0;
+ }
+
+ // Re-enable back-face culling
+ glEnable(GL_CULL_FACE);
+ // Disable alpha blending
+ glDisable(GL_BLEND);
+
+ mPlaneMesh.reset();
+
+ Scene::teardown();
+}
+
+void ScenePulsar::update()
+{
+ double current_time = Scene::get_timestamp_us() / 1000000.0;
+ double dt = current_time - mLastUpdateTime;
+ double elapsed_time = current_time - mStartTime;
+
+ mLastUpdateTime = current_time;
+
+ if (elapsed_time >= mDuration) {
+ mAverageFPS = mCurrentFrame / elapsed_time;
+ mRunning = false;
+ }
+
+ for (int i = 0; i < mNumQuads; i++) {
+ mRotations[i] += mRotationSpeeds[i] * (dt * 60);
+ }
+
+ mScale = LibMatrix::vec3(cos(elapsed_time / 3.60) * 10.0, sin(elapsed_time / 3.60) * 10.0, 1.0);
+
+ mCurrentFrame++;
+}
+
+void ScenePulsar::draw()
+{
+ if (mOptions["texture"].value == "true") {
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
+ }
+
+ for (int i = 0; i < mNumQuads; i++) {
+ // Load the ModelViewProjectionMatrix uniform in the shader
+ LibMatrix::Stack4 model_view;
+ LibMatrix::mat4 model_view_proj(mCanvas.projection());
+ model_view.scale(mScale.x(), mScale.y(), mScale.z());
+ model_view.translate(0.0f, 0.0f, -10.0f);
+ model_view.rotate(mRotations[i].x(), 1.0f, 0.0f, 0.0f);
+ model_view.rotate(mRotations[i].y(), 0.0f, 1.0f, 0.0f);
+ model_view.rotate(mRotations[i].z(), 0.0f, 0.0f, 1.0f);
+ model_view_proj *= model_view.getCurrent();
+ mProgram.loadUniformMatrix(model_view_proj, "ModelViewProjectionMatrix");
+
+ if (mOptions["light"].value == "true") {
+ // Load the NormalMatrix uniform in the shader. The NormalMatrix is the
+ // inverse transpose of the model view matrix.
+ LibMatrix::mat4 normal_matrix(model_view.getCurrent());
+ normal_matrix.inverse().transpose();
+ mProgram.loadUniformMatrix(normal_matrix, "NormalMatrix");
+ }
+
+ mPlaneMesh.render_vbo();
+ }
+}
+
+Scene::ValidationResult
+ScenePulsar::validate()
+{
+ return ValidationUnknown;
+}
+
+void ScenePulsar::create_and_setup_mesh()
+{
+ bool texture = mOptions["texture"].value == "true";
+ bool light = mOptions["light"].value == "true";
+
+ struct PlaneMeshVertex {
+ LibMatrix::vec3 position;
+ LibMatrix::vec4 color;
+ LibMatrix::vec2 texcoord;
+ LibMatrix::vec3 normal;
+ };
+
+ PlaneMeshVertex plane_vertices[] = {
+ {
+ LibMatrix::vec3(-1.0, -1.0, 0.0),
+ LibMatrix::vec4(1.0, 0.0, 0.0, 0.4),
+ LibMatrix::vec2(0.0, 0.0),
+ LibMatrix::vec3(0.0, 0.0, 1.0)
+ },
+ {
+ LibMatrix::vec3(-1.0, 1.0, 0.0),
+ LibMatrix::vec4(0.0, 1.0, 0.0, 0.4),
+ LibMatrix::vec2(0.0, 1.0),
+ LibMatrix::vec3(0.0, 0.0, 1.0)
+ },
+ {
+ LibMatrix::vec3(1.0, 1.0, 0.0),
+ LibMatrix::vec4(0.0, 0.0, 1.0, 0.4),
+ LibMatrix::vec2(1.0, 1.0),
+ LibMatrix::vec3(0.0, 0.0, 1.0)
+ },
+ {
+ LibMatrix::vec3(1.0, -1.0, 0.0),
+ LibMatrix::vec4(1.0, 1.0, 1.0, 1.0),
+ LibMatrix::vec2(1.0, 0.0),
+ LibMatrix::vec3(0.0, 0.0, 1.0)
+ }
+ };
+
+ unsigned int vertex_index[] = {0, 1, 2, 0, 2, 3};
+
+ // Set vertex format
+ std::vector<int> vertex_format;
+ vertex_format.push_back(3); // Position
+ vertex_format.push_back(4); // Color
+ if (texture)
+ vertex_format.push_back(2); // Texcoord
+ if (light)
+ vertex_format.push_back(3); // Normal
+
+ mPlaneMesh.set_vertex_format(vertex_format);
+
+ // Build the plane mesh
+ for (size_t i = 0; i < sizeof(vertex_index) / sizeof(*vertex_index); i++) {
+ PlaneMeshVertex& vertex = plane_vertices[vertex_index[i]];
+
+ mPlaneMesh.next_vertex();
+ mPlaneMesh.set_attrib(0, vertex.position);
+ mPlaneMesh.set_attrib(1, vertex.color);
+ if (texture)
+ mPlaneMesh.set_attrib(2, vertex.texcoord);
+ if (light)
+ mPlaneMesh.set_attrib(2 + ((int)texture), vertex.normal);
+ }
+
+ mPlaneMesh.build_vbo();
+
+ // Set attribute locations
+ std::vector<GLint> attrib_locations;
+ attrib_locations.push_back(mProgram.getAttribIndex("position"));
+ attrib_locations.push_back(mProgram.getAttribIndex("vtxcolor"));
+ if (texture)
+ attrib_locations.push_back(mProgram.getAttribIndex("texcoord"));
+ if (light)
+ attrib_locations.push_back(mProgram.getAttribIndex("normal"));
+ mPlaneMesh.set_attrib_locations(attrib_locations);
+}
+
=== modified file 'src/scene.h'
@@ -20,6 +20,7 @@
* Authors:
* Ben Smith (original glmark benchmark)
* Alexandros Frantzis (glmark2)
+ * Marc Ordinas i Llopis, Collabora Ltd. (pulsar scene)
*/
#ifndef GLMARK2_SCENE_H_
#define GLMARK2_SCENE_H_
@@ -300,4 +301,34 @@
Mesh mesh_;
GLuint texture_;
};
+
+class ScenePulsar : public Scene
+{
+public:
+ ScenePulsar(Canvas &pCanvas);
+ int load();
+ void unload();
+ void setup();
+ void teardown();
+ void update();
+ void draw();
+ ValidationResult validate();
+
+ ~ScenePulsar();
+
+protected:
+ int mNumQuads;
+ Program mProgram;
+
+ Mesh mPlaneMesh;
+ LibMatrix::vec3 mScale;
+ std::vector<LibMatrix::vec3> mRotations;
+ std::vector<LibMatrix::vec3> mRotationSpeeds;
+
+ GLuint mTexture;
+
+private:
+ void create_and_setup_mesh();
+};
+
#endif