=== modified file 'data/shaders/bump-normals.frag'
@@ -2,8 +2,6 @@
precision mediump float;
#endif
-uniform vec4 LightSourcePosition;
-uniform vec3 LightSourceHalfVector;
uniform sampler2D NormalMap;
uniform mat4 NormalMatrix;
=== modified file 'data/shaders/bump-poly.frag'
@@ -2,9 +2,6 @@
precision mediump float;
#endif
-uniform vec4 LightSourcePosition;
-uniform vec3 LightSourceHalfVector;
-
varying vec3 Normal;
void main(void)
=== modified file 'data/shaders/light-advanced.frag'
@@ -2,9 +2,6 @@
precision mediump float;
#endif
-uniform vec4 LightSourcePosition;
-uniform vec3 LightSourceHalfVector;
-
varying vec3 Normal;
void main(void)
=== modified file 'data/shaders/light-basic.vert'
@@ -4,8 +4,6 @@
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 NormalMatrix;
-uniform vec4 LightSourcePosition;
-uniform vec4 MaterialColor;
varying vec4 Color;
varying vec2 TextureCoord;
@@ -21,7 +19,7 @@
// Multiply the diffuse value by the vertex color (which is fixed in this case)
// to get the actual color that we will use to draw this vertex with
float diffuse = max(dot(N, L), 0.0);
- Color = diffuse * MaterialColor;
+ Color = diffuse * MaterialDiffuse;
// Set the texture coordinates as a varying
TextureCoord = texcoord;
=== modified file 'data/shaders/light-phong.frag'
@@ -2,8 +2,6 @@
precision mediump float;
#endif
-uniform vec4 LightSourcePosition;
-
varying vec3 vertex_normal;
varying vec4 vertex_position;
=== modified file 'src/scene-build.cpp'
@@ -25,6 +25,7 @@
#include "log.h"
#include "mat.h"
#include "stack.h"
+#include "shader-source.h"
#include <cmath>
SceneBuild::SceneBuild(Canvas &pCanvas) :
@@ -44,6 +45,8 @@
{
static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ static const LibMatrix::vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
Model model;
if(!model.load_3ds(GLMARK_DATA_PATH"/models/horse.3ds"))
@@ -58,8 +61,14 @@
model.convert_to_mesh(mMesh, attribs);
- if (!Scene::load_shaders_from_files(mProgram, vtx_shader_filename,
- frg_shader_filename))
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ vtx_source.add_global_const("LightSourcePosition", lightPosition);
+ vtx_source.add_global_const("MaterialDiffuse", materialDiffuse);
+
+ if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
+ frg_source.str()))
{
return 0;
}
@@ -88,10 +97,6 @@
{
Scene::setup();
- static const LibMatrix::vec4 lightAmbient(0.0f, 0.0f, 0.0f, 1.0f);
- static const LibMatrix::vec4 lightDiffuse(0.8f, 0.8f, 0.8f, 1.0f);
- static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
- static const LibMatrix::vec4 materialColor(1.0f, 1.0f, 1.0f, 1.0f);
mUseVbo = (mOptions["use-vbo"].value == "true");
bool interleave = (mOptions["interleave"].value == "true");
@@ -103,12 +108,6 @@
mProgram.start();
- // Load lighting and material uniforms
- mProgram.loadUniformVector(lightAmbient, "LightSourceAmbient");
- mProgram.loadUniformVector(lightPosition, "LightSourcePosition");
- mProgram.loadUniformVector(lightDiffuse, "LightSourceDiffuse");
- mProgram.loadUniformVector(materialColor, "MaterialColor");
-
mCurrentFrame = 0;
mRotation = 0.0;
mRunning = true;
=== modified file 'src/scene-bump.cpp'
@@ -23,6 +23,7 @@
#include "log.h"
#include "mat.h"
#include "stack.h"
+#include "shader-source.h"
#include <cmath>
SceneBump::SceneBump(Canvas &pCanvas) :
@@ -56,8 +57,15 @@
static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/bump-poly.frag");
static const std::string low_poly_filename(GLMARK_DATA_PATH"/models/asteroid-low.3ds");
static const std::string high_poly_filename(GLMARK_DATA_PATH"/models/asteroid-high.3ds");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
Model model;
+ /* Calculate the half vector */
+ LibMatrix::vec3 halfVector(lightPosition.x(), lightPosition.y(), lightPosition.z());
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
std::string poly_filename = type == "high-poly" ?
high_poly_filename : low_poly_filename;
@@ -73,8 +81,16 @@
model.convert_to_mesh(mMesh, attribs);
- if (!Scene::load_shaders_from_files(mProgram, vtx_shader_filename,
- frg_shader_filename))
+ /* Load shaders */
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ /* Add constants to shaders */
+ frg_source.add_global_const("LightSourcePosition", lightPosition);
+ frg_source.add_global_const("LightSourceHalfVector", halfVector);
+
+ if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
+ frg_source.str()))
{
return;
}
@@ -90,11 +106,18 @@
{
static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/bump-normals.vert");
static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/bump-normals.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
Model model;
if(!model.load_3ds(GLMARK_DATA_PATH"/models/asteroid-low.3ds"))
return;
+ /* Calculate the half vector */
+ LibMatrix::vec3 halfVector(lightPosition.x(), lightPosition.y(), lightPosition.z());
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
/*
* We don't care about the vertex normals. We are using a per-fragment
* normal map (in object space coordinates).
@@ -105,8 +128,16 @@
model.convert_to_mesh(mMesh, attribs);
- if (!Scene::load_shaders_from_files(mProgram, vtx_shader_filename,
- frg_shader_filename))
+ /* Load shaders */
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ /* Add constants to shaders */
+ frg_source.add_global_const("LightSourcePosition", lightPosition);
+ frg_source.add_global_const("LightSourceHalfVector", halfVector);
+
+ if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
+ frg_source.str()))
{
return;
}
@@ -131,22 +162,11 @@
else if (bump_render == "off" || bump_render == "high-poly")
setup_model_plain(bump_render);
- static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
mMesh.build_vbo();
mProgram.start();
- // Load lighting and material uniforms
- mProgram.loadUniformVector(lightPosition, "LightSourcePosition");
-
- // Calculate and load the half vector
- LibMatrix::vec3 halfVector(lightPosition.x(), lightPosition.y(), lightPosition.z());
- halfVector.normalize();
- halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
- halfVector.normalize();
- mProgram.loadUniformVector(halfVector, "LightSourceHalfVector");
-
// Load texture sampler value
mProgram.loadUniformScalar(0, "NormalMap");
=== modified file 'src/scene-conditionals.cpp'
@@ -24,6 +24,7 @@
#include "stack.h"
#include "vec.h"
#include "log.h"
+#include "shader-source.h"
#include <cmath>
#include <sstream>
@@ -52,69 +53,40 @@
{
}
-static std::string &
-replace_string(std::string &str, const std::string &remove, const std::string &insert)
-{
- std::string::size_type pos = 0;
-
- while ((pos = str.find(remove, pos)) != std::string::npos) {
- str.replace(pos, remove.size(), insert);
- pos++;
- }
-
- return str;
-}
-
static std::string
get_vertex_shader_source(int steps, bool conditionals)
{
- std::string vtx_string, step_conditional_string, step_simple_string;
-
- if (!gotSource(vtx_file, vtx_string) ||
- !gotSource(step_conditional_file, step_conditional_string) ||
- !gotSource(step_simple_file, step_simple_string))
- {
- return "";
- }
-
- std::stringstream ss_main;
+ ShaderSource source(vtx_file);
+ ShaderSource source_main;
for (int i = 0; i < steps; i++) {
if (conditionals)
- ss_main << step_conditional_string;
+ source_main.append_file(step_conditional_file);
else
- ss_main << step_simple_string;
+ source_main.append_file(step_simple_file);
}
- replace_string(vtx_string, "$MAIN$", ss_main.str());
+ source.replace("$MAIN$", source_main.str());
- return vtx_string;
+ return source.str();
}
static std::string
get_fragment_shader_source(int steps, bool conditionals)
{
- std::string frg_string, step_conditional_string, step_simple_string;
-
- if (!gotSource(frg_file, frg_string) ||
- !gotSource(step_conditional_file, step_conditional_string) ||
- !gotSource(step_simple_file, step_simple_string))
- {
- return "";
- }
-
- std::stringstream ss_main;
+ ShaderSource source(frg_file);
+ ShaderSource source_main;
for (int i = 0; i < steps; i++) {
if (conditionals)
- ss_main << step_conditional_string;
+ source_main.append_file(step_conditional_file);
else
- ss_main << step_simple_string;
+ source_main.append_file(step_simple_file);
}
- replace_string(frg_string, "$MAIN$", ss_main.str());
+ source.replace("$MAIN$", source_main.str());
- return frg_string;
+ return source.str();
}
void SceneConditionals::setup()
=== modified file 'src/scene-function.cpp'
@@ -24,6 +24,7 @@
#include "stack.h"
#include "vec.h"
#include "log.h"
+#include "shader-source.h"
#include <sstream>
@@ -56,85 +57,62 @@
{
}
-static std::string &
-replace_string(std::string &str, const std::string &remove, const std::string &insert)
-{
- std::string::size_type pos = 0;
-
- while ((pos = str.find(remove, pos)) != std::string::npos) {
- str.replace(pos, remove.size(), insert);
- pos++;
- }
-
- return str;
-}
-
static std::string
get_vertex_shader_source(int steps, bool function, std::string &complexity)
{
- std::string vtx_string, step_low_string, step_medium_string, call_string;
-
- if (!gotSource(vtx_file, vtx_string) ||
- !gotSource(step_low_file, step_low_string) ||
- !gotSource(step_medium_file, step_medium_string) ||
- !gotSource(call_file, call_string))
- {
- return "";
- }
-
- std::stringstream ss_main;
- std::string process_string;
+ ShaderSource source(vtx_file);
+ ShaderSource source_main;
+ std::string step_file;
if (complexity == "low")
- process_string = step_low_string;
+ step_file = step_low_file;
else if (complexity == "medium")
- process_string = step_medium_string;
+ step_file = step_medium_file;
for (int i = 0; i < steps; i++) {
if (function)
- ss_main << call_string;
+ source_main.append_file(call_file);
else
- ss_main << process_string;
+ source_main.append_file(step_file);
}
- replace_string(vtx_string, "$PROCESS$", function ? process_string : "");
- replace_string(vtx_string, "$MAIN$", ss_main.str());
-
- return vtx_string;
+ if (function)
+ source.replace_with_file("$PROCESS$", step_file);
+ else
+ source.replace("$PROCESS$", "");
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
}
static std::string
get_fragment_shader_source(int steps, bool function, std::string &complexity)
{
- std::string frg_string, step_low_string, step_medium_string, call_string;
-
- if (!gotSource(frg_file, frg_string) ||
- !gotSource(step_low_file, step_low_string) ||
- !gotSource(step_medium_file, step_medium_string) ||
- !gotSource(call_file, call_string))
- {
- return "";
- }
-
- std::stringstream ss_main;
- std::string process_string;
+ ShaderSource source(frg_file);
+ ShaderSource source_main;
+ std::string step_file;
if (complexity == "low")
- process_string = step_low_string;
+ step_file = step_low_file;
else if (complexity == "medium")
- process_string = step_medium_string;
+ step_file = step_medium_file;
for (int i = 0; i < steps; i++) {
if (function)
- ss_main << call_string;
+ source_main.append_file(call_file);
else
- ss_main << process_string;
+ source_main.append_file(step_file);
}
- replace_string(frg_string, "$PROCESS$", function ? process_string : "");
- replace_string(frg_string, "$MAIN$", ss_main.str());
-
- return frg_string;
+ if (function)
+ source.replace_with_file("$PROCESS$", step_file);
+ else
+ source.replace("$PROCESS$", "");
+
+ source.replace("$MAIN$", source_main.str());
+
+ return source.str();
}
void SceneFunction::setup()
=== modified file 'src/scene-loop.cpp'
@@ -24,6 +24,7 @@
#include "stack.h"
#include "vec.h"
#include "log.h"
+#include "shader-source.h"
#include <sstream>
@@ -55,87 +56,58 @@
{
}
-static std::string &
-replace_string(std::string &str, const std::string &remove, const std::string &insert)
-{
- std::string::size_type pos = 0;
-
- while ((pos = str.find(remove, pos)) != std::string::npos) {
- str.replace(pos, remove.size(), insert);
- pos++;
- }
-
- return str;
-}
-
static std::string
get_fragment_shader_source(int steps, bool loop, bool uniform)
{
- std::string frg_string, step_simple_string, step_loop_string;
-
- if (!gotSource(frg_file, frg_string) ||
- !gotSource(step_simple_file, step_simple_string) ||
- !gotSource(step_loop_file, step_loop_string))
- {
- return "";
- }
-
- std::stringstream ss_main;
+ ShaderSource source(frg_file);
+ ShaderSource source_main;
if (loop) {
+ source_main.append_file(step_loop_file);
if (uniform) {
- replace_string(step_loop_string, "$NLOOPS$", "FragmentLoops");
+ source_main.replace("$NLOOPS$", "FragmentLoops");
}
else {
std::stringstream ss_steps;
ss_steps << steps;
- replace_string(step_loop_string, "$NLOOPS$", ss_steps.str());
+ source_main.replace("$NLOOPS$", ss_steps.str());
}
- ss_main << step_loop_string;
}
else {
for (int i = 0; i < steps; i++)
- ss_main << step_simple_string;
+ source_main.append_file(step_simple_file);
}
- replace_string(frg_string, "$MAIN$", ss_main.str());
+ source.replace("$MAIN$", source_main.str());
- return frg_string;
+ return source.str();
}
static std::string
get_vertex_shader_source(int steps, bool loop, bool uniform)
{
- std::string vtx_string, step_simple_string, step_loop_string;
-
- if (!gotSource(vtx_file, vtx_string) ||
- !gotSource(step_simple_file, step_simple_string) ||
- !gotSource(step_loop_file, step_loop_string))
- {
- return "";
- }
-
- std::stringstream ss_main;
+ ShaderSource source(vtx_file);
+ ShaderSource source_main;
if (loop) {
+ source_main.append_file(step_loop_file);
if (uniform) {
- replace_string(step_loop_string, "$NLOOPS$", "VertexLoops");
+ source_main.replace("$NLOOPS$", "VertexLoops");
}
else {
std::stringstream ss_steps;
ss_steps << steps;
- replace_string(step_loop_string, "$NLOOPS$", ss_steps.str());
+ source_main.replace("$NLOOPS$", ss_steps.str());
}
- ss_main << step_loop_string;
}
else {
for (int i = 0; i < steps; i++)
- ss_main << step_simple_string;
+ source_main.append_file(step_simple_file);
}
- replace_string(vtx_string, "$MAIN$", ss_main.str());
+ source.replace("$MAIN$", source_main.str());
- return vtx_string;
+ return source.str();
}
=== modified file 'src/scene-shading.cpp'
@@ -26,6 +26,7 @@
#include "stack.h"
#include "vec.h"
#include "log.h"
+#include "shader-source.h"
#include <cmath>
@@ -77,6 +78,12 @@
static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
static const LibMatrix::vec4 materialDiffuse(0.0f, 0.0f, 1.0f, 1.0f);
+ // Calculate half vector for blinn-phong shading model
+ LibMatrix::vec3 halfVector(lightPosition[0], lightPosition[1], lightPosition[2]);
+ halfVector.normalize();
+ halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
+ halfVector.normalize();
+
std::string vtx_shader_filename;
std::string frg_shader_filename;
const std::string &shading = mOptions["shading"].value;
@@ -94,8 +101,19 @@
frg_shader_filename = GLMARK_DATA_PATH"/shaders/light-phong.frag";
}
- if (!Scene::load_shaders_from_files(mProgram, vtx_shader_filename,
- frg_shader_filename))
+ // Load shaders
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ // Add constants to shaders
+ vtx_source.add_global_const("LightSourcePosition", lightPosition);
+ vtx_source.add_global_const("MaterialDiffuse", materialDiffuse);
+
+ frg_source.add_global_const("LightSourcePosition", lightPosition);
+ frg_source.add_global_const("LightSourceHalfVector", halfVector);
+
+ if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
+ frg_source.str()))
{
return;
}
@@ -107,15 +125,6 @@
attrib_locations.push_back(mProgram.getAttribIndex("normal"));
mMesh.set_attrib_locations(attrib_locations);
- // Load lighting and material uniforms
- mProgram.loadUniformVector(lightPosition, "LightSourcePosition");
- mProgram.loadUniformVector(materialDiffuse, "MaterialColor");
- LibMatrix::vec3 halfVector(lightPosition[0], lightPosition[1], lightPosition[2]);
- halfVector.normalize();
- halfVector += LibMatrix::vec3(0.0, 0.0, 1.0);
- halfVector.normalize();
- mProgram.loadUniformVector(halfVector, "LightSourceHalfVector");
-
mCurrentFrame = 0;
mRotation = 0.0f;
mRunning = true;
=== modified file 'src/scene-texture.cpp'
@@ -26,8 +26,9 @@
#include "stack.h"
#include "vec.h"
#include "log.h"
-
#include "program.h"
+#include "shader-source.h"
+
#include <cmath>
SceneTexture::SceneTexture(Canvas &pCanvas) :
@@ -45,6 +46,9 @@
{
static const std::string vtx_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic.vert");
static const std::string frg_shader_filename(GLMARK_DATA_PATH"/shaders/light-basic-tex.frag");
+ static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
+ static const LibMatrix::vec4 materialDiffuse(1.0f, 1.0f, 1.0f, 1.0f);
+
Model model;
if(!model.load_3ds(GLMARK_DATA_PATH"/models/cube.3ds"))
@@ -54,8 +58,16 @@
model.convert_to_mesh(mCubeMesh);
mCubeMesh.build_vbo();
- if (!Scene::load_shaders_from_files(mProgram, vtx_shader_filename,
- frg_shader_filename))
+ // Load shaders
+ ShaderSource vtx_source(vtx_shader_filename);
+ ShaderSource frg_source(frg_shader_filename);
+
+ // Add constants to shaders
+ vtx_source.add_global_const("LightSourcePosition", lightPosition);
+ vtx_source.add_global_const("MaterialDiffuse", materialDiffuse);
+
+ if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
+ frg_source.str()))
{
return 0;
}
@@ -85,11 +97,6 @@
{
Scene::setup();
- static const LibMatrix::vec4 lightAmbient(0.0f, 0.0f, 0.0f, 1.0f);
- static const LibMatrix::vec4 lightDiffuse(0.8f, 0.8f, 0.8f, 1.0f);
- static const LibMatrix::vec4 lightPosition(20.0f, 20.0f, 10.0f, 1.0f);
- static const LibMatrix::vec4 materialColor(1.0f, 1.0f, 1.0f, 1.0f);
-
// Create texture according to selected filtering
GLint min_filter = GL_NONE;
GLint mag_filter = GL_NONE;
@@ -113,12 +120,6 @@
mProgram.start();
- // Load lighting and material uniforms
- mProgram.loadUniformVector(lightAmbient, "LightSourceAmbient");
- mProgram.loadUniformVector(lightPosition, "LightSourcePosition");
- mProgram.loadUniformVector(lightDiffuse, "LightSourceDiffuse");
- mProgram.loadUniformVector(materialColor, "MaterialColor");
-
mCurrentFrame = 0;
mRotation = LibMatrix::vec3();
mRunning = true;
=== added file 'src/shader-source.cpp'
@@ -0,0 +1,190 @@
+/*
+ * 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:
+ * Alexandros Frantzis (glmark2)
+ */
+
+#include <fstream>
+
+#include "shader-source.h"
+#include "log.h"
+#include "vec.h"
+
+/**
+ * Loads the contents of a file into a string.
+ *
+ * @param filename the name of the file
+ * @param str the string to put the contents of the file into
+ */
+bool
+ShaderSource::load_file(const std::string& filename, std::string& str)
+{
+ using std::ifstream;
+ ifstream inputFile(filename.c_str());
+ if (!inputFile)
+ {
+ Log::error("Failed to open \"%s\"\n", filename.c_str());
+ return false;
+ }
+
+ std::string curLine;
+ while (getline(inputFile, curLine))
+ {
+ str += curLine;
+ str += '\n';
+ }
+
+ return true;
+}
+
+
+/**
+ * Appends a string to the shader source.
+ *
+ * @param str the string to append
+ */
+void
+ShaderSource::append(const std::string &str)
+{
+ source_ << str;
+}
+
+/**
+ * Appends the contents of a file to the shader source.
+ *
+ * @param filename the name of the file to append
+ */
+void
+ShaderSource::append_file(const std::string &filename)
+{
+ std::string source;
+ if (load_file(filename, source))
+ source_ << source;
+}
+
+/**
+ * Replaces a string in the source with another string.
+ *
+ * @param remove the string to replace
+ * @param insert the string to replace with
+ */
+void
+ShaderSource::replace(const std::string &remove, const std::string &insert)
+{
+ std::string::size_type pos = 0;
+ std::string str(source_.str());
+
+ while ((pos = str.find(remove, pos)) != std::string::npos) {
+ str.replace(pos, remove.size(), insert);
+ pos++;
+ }
+
+ source_.clear();
+ source_.str(str);
+}
+
+/**
+ * Replaces a string in the source with the contents of a file.
+ *
+ * @param remove the string to replace
+ * @param filename the name of the file to read from
+ */
+void
+ShaderSource::replace_with_file(const std::string &remove, const std::string &filename)
+{
+ std::string source;
+ if (load_file(filename, source))
+ replace(remove, source);
+}
+
+/**
+ * Adds a string (usually containing a constant definition) at
+ * global (per shader) scope.
+ *
+ * The string is placed after any default precision qualifiers.
+ *
+ * @param str the string to add
+ */
+void
+ShaderSource::add_global(const std::string &str)
+{
+ std::string::size_type pos = 0;
+ std::string source(source_.str());
+
+ /* Find the last precision qualifier */
+ pos = source.rfind("precision");
+
+ if (pos != std::string::npos) {
+ /*
+ * Find the next #endif line of a preprocessor block that contains
+ * the precision qualifier.
+ */
+ std::string::size_type pos_if = source.find("#if", pos);
+ std::string::size_type pos_endif = source.find("#endif", pos);
+
+ if (pos_endif != std::string::npos && pos_endif < pos_if)
+ pos = pos_endif;
+
+ /* Go to the next line */
+ pos = source.find("\n", pos);
+ if (pos != std::string::npos)
+ pos++;
+ }
+ else
+ pos = 0;
+
+ source.insert(pos, str);
+
+ source_.clear();
+ source_.str(source);
+}
+
+/**
+ * Adds a global (per shader) vec3 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ */
+void
+ShaderSource::add_global_const(const std::string &name, const LibMatrix::vec3 &v)
+{
+ std::stringstream ss;
+
+ ss << "const vec3 " << name << " = vec3(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ", " << v.z() << ");" << std::endl;
+
+ add_global(ss.str());
+}
+
+/**
+ * Adds a global (per shader) vec4 constant definition.
+ *
+ * @param name the name of the constant
+ * @param v the value of the constant
+ */
+void
+ShaderSource::add_global_const(const std::string &name, const LibMatrix::vec4 &v)
+{
+ std::stringstream ss;
+
+ ss << "const vec4 " << name << " = vec4(" << std::fixed;
+ ss << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ");" << std::endl;
+
+ add_global(ss.str());
+}
=== added file 'src/shader-source.h'
@@ -0,0 +1,52 @@
+/*
+ * 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:
+ * Alexandros Frantzis (glmark2)
+ */
+
+#include <string>
+#include <sstream>
+#include "vec.h"
+
+/**
+ * Helper class for loading and manipulating shader sources.
+ */
+class ShaderSource
+{
+public:
+ ShaderSource() {}
+ ShaderSource(const std::string &filename) { append_file(filename); }
+
+ void append(const std::string &str);
+ void append_file(const std::string &filename);
+
+ void replace(const std::string &remove, const std::string &insert);
+ void replace_with_file(const std::string &remove, const std::string &filename);
+
+ void add_global(const std::string &str);
+ void add_global_const(const std::string &name, const LibMatrix::vec3 &v);
+ void add_global_const(const std::string &name, const LibMatrix::vec4 &v);
+
+ std::string str() { return source_.str(); }
+
+private:
+ bool load_file(const std::string& filename, std::string& str);
+
+ std::stringstream source_;
+};