=== modified file 'data/shaders/bump-normals.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
uniform sampler2D NormalMap;
uniform mat4 NormalMatrix;
=== modified file 'data/shaders/bump-poly.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
varying vec3 Normal;
void main(void)
=== modified file 'data/shaders/conditionals.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
varying vec4 dummy;
void main(void)
=== modified file 'data/shaders/desktop-blur.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
uniform sampler2D Texture0;
varying vec2 TextureCoord;
=== modified file 'data/shaders/desktop.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
uniform sampler2D MaterialTexture0;
varying vec2 TextureCoord;
=== modified file 'data/shaders/effect-2d-convolution.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
uniform sampler2D Texture0;
varying vec2 TextureCoord;
=== modified file 'data/shaders/function.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
varying vec4 dummy;
float process(float d)
=== modified file 'data/shaders/light-advanced.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
varying vec3 Normal;
void main(void)
=== modified file 'data/shaders/light-basic-tex.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
uniform sampler2D MaterialTexture0;
varying vec4 Color;
=== modified file 'data/shaders/light-basic.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
varying vec4 Color;
varying vec2 TextureCoord;
=== modified file 'data/shaders/light-phong.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
varying vec3 vertex_normal;
varying vec4 vertex_position;
=== modified file 'data/shaders/loop.frag'
@@ -1,7 +1,3 @@
-#ifdef GL_ES
-precision mediump float;
-#endif
-
varying vec4 dummy;
uniform int FragmentLoops;
=== modified file 'src/scene-build.cpp'
@@ -45,6 +45,26 @@
int SceneBuild::load()
{
+ mRotationSpeed = 36.0f;
+
+ mRunning = false;
+
+ return 1;
+}
+
+void SceneBuild::unload()
+{
+ mMesh.reset();
+
+}
+
+void SceneBuild::setup()
+{
+ using LibMatrix::vec3;
+
+ Scene::setup();
+
+ /* Set up shaders */
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);
@@ -59,28 +79,9 @@
if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
frg_source.str()))
{
- return 0;
+ return;
}
- mRotationSpeed = 36.0f;
-
- mRunning = false;
-
- return 1;
-}
-
-void SceneBuild::unload()
-{
- mProgram.stop();
- mProgram.release();
-}
-
-void SceneBuild::setup()
-{
- using LibMatrix::vec3;
-
- Scene::setup();
-
Model model;
bool modelLoaded(false);
const std::string& whichModel(mOptions["model"].value);
@@ -150,6 +151,7 @@
SceneBuild::teardown()
{
mProgram.stop();
+ mProgram.release();
mMesh.reset();
=== modified file 'src/scene-desktop.cpp'
@@ -600,16 +600,12 @@
int
SceneDesktop::load()
{
- priv_->screen.init();
- priv_->desktop.init();
return 1;
}
void
SceneDesktop::unload()
{
- priv_->desktop.release();
- priv_->screen.release();
}
void
@@ -642,6 +638,8 @@
glDepthMask(GL_FALSE);
/* Set up the screen and desktop RenderObjects */
+ priv_->screen.init();
+ priv_->desktop.init();
priv_->screen.size(LibMatrix::vec2(mCanvas.width(), mCanvas.height()));
priv_->desktop.size(LibMatrix::vec2(mCanvas.width(), mCanvas.height()));
@@ -696,6 +694,9 @@
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
+ priv_->desktop.release();
+ priv_->screen.release();
+
Scene::teardown();
}
=== modified file 'src/scene-texture.cpp'
@@ -44,11 +44,6 @@
int SceneTexture::load()
{
- 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"))
@@ -58,7 +53,27 @@
model.convert_to_mesh(mCubeMesh);
mCubeMesh.build_vbo();
+ mRotationSpeed = LibMatrix::vec3(36.0f, 36.0f, 36.0f);
+
+ mRunning = false;
+
+ return 1;
+}
+
+void SceneTexture::unload()
+{
+ mCubeMesh.reset();
+}
+
+void SceneTexture::setup()
+{
+ Scene::setup();
+
// Load shaders
+ 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);
ShaderSource vtx_source(vtx_shader_filename);
ShaderSource frg_source(frg_shader_filename);
@@ -69,7 +84,7 @@
if (!Scene::load_shaders_from_strings(mProgram, vtx_source.str(),
frg_source.str()))
{
- return 0;
+ return;
}
std::vector<GLint> attrib_locations;
@@ -78,25 +93,6 @@
attrib_locations.push_back(mProgram["texcoord"].location());
mCubeMesh.set_attrib_locations(attrib_locations);
- mRotationSpeed = LibMatrix::vec3(36.0f, 36.0f, 36.0f);
-
- mRunning = false;
-
- return 1;
-}
-
-void SceneTexture::unload()
-{
- mCubeMesh.reset();
-
- mProgram.stop();
- mProgram.release();
-}
-
-void SceneTexture::setup()
-{
- Scene::setup();
-
// Create texture according to selected filtering
GLint min_filter = GL_NONE;
GLint mag_filter = GL_NONE;
@@ -130,6 +126,8 @@
void SceneTexture::teardown()
{
mProgram.stop();
+ mProgram.release();
+
glDeleteTextures(1, &mTexture);
Scene::teardown();
=== modified file 'src/scene.cpp'
@@ -23,6 +23,7 @@
*/
#include "scene.h"
#include "log.h"
+#include "shader-source.h"
#include <sstream>
#include <cmath>
#include <sys/time.h>
@@ -38,6 +39,12 @@
{
mOptions["duration"] = Scene::Option("duration", "10.0",
"The duration of each benchmark in seconds");
+ mOptions["vertex-precision"] = Scene::Option("vertex-precision",
+ "default,default,default,default",
+ "The precision values for the vertex shader (\"int,float,sampler2d,samplercube\")");
+ mOptions["fragment-precision"] = Scene::Option("fragment-precision",
+ "default,default,default,default",
+ "The precision values for the fragment shader (\"int,float,sampler2d,samplercube\")");
}
Scene::~Scene()
@@ -57,6 +64,17 @@
{
stringstream ss(mOptions["duration"].value);
ss >> mDuration;
+
+ ShaderSource::default_precision(
+ ShaderSource::Precision(mOptions["vertex-precision"].value),
+ ShaderSource::ShaderTypeVertex
+ );
+
+ ShaderSource::default_precision(
+ ShaderSource::Precision(mOptions["fragment-precision"].value),
+ ShaderSource::ShaderTypeFragment
+ );
+
}
void Scene::teardown()
=== modified file 'src/shader-source.cpp'
@@ -29,6 +29,13 @@
#include "util.h"
/**
+ * Holds default precision values for all shader types
+ * (even the unknown type, which is hardwired to default precision values)
+ */
+std::vector<ShaderSource::Precision>
+ShaderSource::default_precision_(ShaderSource::ShaderTypeUnknown + 1);
+
+/**
* Loads the contents of a file into a string.
*
* @param filename the name of the file
@@ -351,3 +358,246 @@
add(decl, decl_function);
}
+
+/**
+ * Gets the ShaderType for this ShaderSource.
+ *
+ * If the ShaderType is unknown, an attempt is made to infer
+ * the type from the shader source contents.
+ *
+ * @return the ShaderType
+ */
+ShaderSource::ShaderType
+ShaderSource::type()
+{
+ /* Try to infer the type from the source contents */
+ if (type_ == ShaderSource::ShaderTypeUnknown) {
+ std::string source(source_.str());
+
+ if (source.find("gl_FragColor") != std::string::npos)
+ type_ = ShaderSource::ShaderTypeFragment;
+ else if (source.find("gl_Position") != std::string::npos)
+ type_ = ShaderSource::ShaderTypeVertex;
+ else
+ Log::debug("Cannot infer shader type from contents. Leaving it Unknown.\n");
+ }
+
+ return type_;
+}
+
+/**
+ * Helper function that emits a precision statement.
+ *
+ * @param ss the stringstream to add the statement to
+ * @param val the precision value
+ * @param type_str the variable type to apply the precision value to
+ */
+void
+ShaderSource::emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
+ const std::string& type_str)
+{
+ static const char *precision_map[] = {
+ "lowp", "mediump", "highp", NULL
+ };
+
+ if (val == ShaderSource::PrecisionValueHigh) {
+ if (type_ == ShaderSource::ShaderTypeFragment)
+ ss << "#ifdef GL_FRAGMENT_PRECISION_HIGH" << std::endl;
+
+ ss << "precision highp " << type_str << ";" << std::endl;
+
+ if (type_ == ShaderSource::ShaderTypeFragment) {
+ ss << "#else" << std::endl;
+ ss << "precision mediump " << type_str << ";" << std::endl;
+ ss << "#endif" << std::endl;
+ }
+ }
+ else if (val >= 0 && val < ShaderSource::PrecisionValueDefault) {
+ ss << "precision " << precision_map[val] << " ";
+ ss << type_str << ";" << std::endl;
+ }
+
+ /* There is no default precision in the fragment shader, so set it to mediump */
+ if (val == ShaderSource::PrecisionValueDefault
+ && type_str == "float" && type_ == ShaderSource::ShaderTypeFragment)
+ {
+ ss << "precision mediump float;" << std::endl;
+ }
+}
+
+/**
+ * Gets a string containing the complete shader source.
+ *
+ * Precision statements are applied at this point.
+ *
+ * @return the shader source
+ */
+std::string
+ShaderSource::str()
+{
+ /* Decide which precision values to use */
+ ShaderSource::Precision precision;
+
+ if (precision_has_been_set_)
+ precision = precision_;
+ else
+ precision = default_precision(type());
+
+ /* Create the precision statements */
+ std::stringstream ss;
+
+ emit_precision(ss, precision.int_precision, "int");
+ emit_precision(ss, precision.float_precision, "float");
+ emit_precision(ss, precision.sampler2d_precision, "sampler2D");
+ emit_precision(ss, precision.samplercube_precision, "samplerCube");
+
+ std::string precision_str(ss.str());
+ if (!precision_str.empty()) {
+ precision_str.insert(0, "#ifdef GL_ES\n");
+ precision_str.insert(precision_str.size(), "#endif\n");
+ }
+
+ return precision_str + source_.str();
+}
+
+/**
+ * Sets the precision that will be used for this shader.
+ *
+ * This overrides any default values set with ShaderSource::default_*_precision().
+ *
+ * @param precision the precision to set
+ */
+void
+ShaderSource::precision(const ShaderSource::Precision& precision)
+{
+ precision_ = precision;
+ precision_has_been_set_ = true;
+}
+
+/**
+ * Gets the precision that will be used for this shader.
+ *
+ * @return the precision
+ */
+const ShaderSource::Precision&
+ShaderSource::precision()
+{
+ return precision_;
+}
+
+/**
+ * Sets the default precision that will be used for a shaders type.
+ *
+ * If type is ShaderTypeUnknown the supplied precision is used for all
+ * shader types.
+ *
+ * This can be overriden per ShaderSource object by using ::precision().
+ *
+ * @param precision the default precision to set
+ * @param type the ShaderType to use the precision for
+ */
+void
+ShaderSource::default_precision(const ShaderSource::Precision& precision,
+ ShaderSource::ShaderType type)
+{
+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
+ type = ShaderSource::ShaderTypeUnknown;
+
+ if (type == ShaderSource::ShaderTypeUnknown) {
+ for (size_t i = 0; i < ShaderSource::ShaderTypeUnknown; i++)
+ default_precision_[i] = precision;
+ }
+ else {
+ default_precision_[type] = precision;
+ }
+}
+
+/**
+ * Gets the default precision that will be used for a shader type.
+ *
+ * It is valid to use a type of ShaderTypeUnknown. This will always
+ * return a Precision with default values.
+ *
+ * @param type the ShaderType to get the precision of
+ *
+ * @return the precision
+ */
+const ShaderSource::Precision&
+ShaderSource::default_precision(ShaderSource::ShaderType type)
+{
+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
+ type = ShaderSource::ShaderTypeUnknown;
+
+ return default_precision_[type];
+}
+
+/****************************************
+ * ShaderSource::Precision constructors *
+ ****************************************/
+
+/**
+ * Creates a ShaderSource::Precision with default precision values.
+ */
+ShaderSource::Precision::Precision() :
+ int_precision(ShaderSource::PrecisionValueDefault),
+ float_precision(ShaderSource::PrecisionValueDefault),
+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
+ samplercube_precision(ShaderSource::PrecisionValueDefault)
+{
+}
+
+/**
+ * Creates a ShaderSource::Precision using the supplied precision values.
+ */
+ShaderSource::Precision::Precision(ShaderSource::PrecisionValue int_p,
+ ShaderSource::PrecisionValue float_p,
+ ShaderSource::PrecisionValue sampler2d_p,
+ ShaderSource::PrecisionValue samplercube_p) :
+ int_precision(int_p), float_precision(float_p),
+ sampler2d_precision(sampler2d_p), samplercube_precision(samplercube_p)
+{
+}
+
+/**
+ * Creates a ShaderSource::Precision from a string representation of
+ * precision values.
+ *
+ * The string format is:
+ * "<int>,<float>,<sampler2d>,<samplercube>"
+ *
+ * Each precision value is one of "high", "medium", "low" or "default".
+ *
+ * @param precision_values the string representation of the precision values
+ */
+ShaderSource::Precision::Precision(const std::string& precision_values) :
+ int_precision(ShaderSource::PrecisionValueDefault),
+ float_precision(ShaderSource::PrecisionValueDefault),
+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
+ samplercube_precision(ShaderSource::PrecisionValueDefault)
+{
+ std::vector<std::string> elems;
+
+ Util::split(precision_values, ',', elems);
+
+ for (size_t i = 0; i < elems.size() && i < 4; i++) {
+ const std::string& pstr(elems[i]);
+ ShaderSource::PrecisionValue pval;
+
+ if (pstr == "high")
+ pval = ShaderSource::PrecisionValueHigh;
+ else if (pstr == "medium")
+ pval = ShaderSource::PrecisionValueMedium;
+ else if (pstr == "low")
+ pval = ShaderSource::PrecisionValueLow;
+ else
+ pval = ShaderSource::PrecisionValueDefault;
+
+ switch(i) {
+ case 0: int_precision = pval; break;
+ case 1: float_precision = pval; break;
+ case 2: sampler2d_precision = pval; break;
+ case 3: samplercube_precision = pval; break;
+ default: break;
+ }
+ }
+}
=== modified file 'src/shader-source.h'
@@ -32,8 +32,16 @@
class ShaderSource
{
public:
- ShaderSource() {}
- ShaderSource(const std::string &filename) { append_file(filename); }
+ enum ShaderType {
+ ShaderTypeVertex,
+ ShaderTypeFragment,
+ ShaderTypeUnknown
+ };
+
+ ShaderSource(ShaderType type = ShaderTypeUnknown) :
+ precision_has_been_set_(false), type_(type) {}
+ ShaderSource(const std::string &filename, ShaderType type = ShaderTypeUnknown) :
+ precision_has_been_set_(false), type_(type) { append_file(filename); }
void append(const std::string &str);
void append_file(const std::string &filename);
@@ -58,12 +66,46 @@
const std::string &init_function,
const std::string &decl_function = "");
- std::string str() { return source_.str(); }
+ ShaderType type();
+ std::string str();
+
+ enum PrecisionValue {
+ PrecisionValueLow,
+ PrecisionValueMedium,
+ PrecisionValueHigh,
+ PrecisionValueDefault,
+ };
+
+ struct Precision {
+ Precision();
+ Precision(PrecisionValue int_p, PrecisionValue float_p,
+ PrecisionValue sampler2d_p, PrecisionValue samplercube_p);
+ Precision(const std::string& list);
+
+ PrecisionValue int_precision;
+ PrecisionValue float_precision;
+ PrecisionValue sampler2d_precision;
+ PrecisionValue samplercube_precision;
+ };
+
+ void precision(const Precision& precision);
+ const Precision& precision();
+
+ static void default_precision(const Precision& precision,
+ ShaderType type = ShaderTypeUnknown);
+ static const Precision& default_precision(ShaderType type);
private:
void add_global(const std::string &str);
void add_local(const std::string &str, const std::string &function);
bool load_file(const std::string& filename, std::string& str);
+ void emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
+ const std::string& type_str);
std::stringstream source_;
+ Precision precision_;
+ bool precision_has_been_set_;
+ ShaderType type_;
+
+ static std::vector<Precision> default_precision_;
};