=== added file 'src/benchmark.cpp'
@@ -0,0 +1,143 @@
+/*
+ * Copyright © 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 "benchmark.h"
+#include "log.h"
+#include <sstream>
+
+using std::string;
+using std::vector;
+using std::map;
+
+std::map<string, Scene *> Benchmark::mSceneMap;
+
+static void
+split(const string &s, char delim, vector<string> &elems)
+{
+ std::stringstream ss(s);
+
+ string item;
+ while(std::getline(ss, item, delim))
+ elems.push_back(item);
+}
+
+static Scene &
+get_scene_from_description(const string &s)
+{
+ vector<string> elems;
+
+ split(s, ':', elems);
+
+ const string &name = !elems.empty() ? elems[0] : "";
+
+ return Benchmark::get_scene_by_name(name);
+}
+
+static vector<Benchmark::OptionPair>
+get_options_from_description(const string &s)
+{
+ vector<Benchmark::OptionPair> options;
+ vector<string> elems;
+
+ split(s, ':', elems);
+
+ for (vector<string>::const_iterator iter = ++elems.begin();
+ iter != elems.end();
+ iter++)
+ {
+ vector<string> opt;
+
+ split(*iter, '=', opt);
+ if (opt.size() == 2)
+ options.push_back(Benchmark::OptionPair(opt[0], opt[1]));
+ else
+ Log::info("Warning: ignoring invalid option string '%s' "
+ "in benchmark description\n",
+ iter->c_str());
+ }
+
+ return options;
+}
+
+void
+Benchmark::register_scene(Scene &scene)
+{
+ mSceneMap[scene.name()] = &scene;
+}
+
+Scene &
+Benchmark::get_scene_by_name(const string &name)
+{
+ map<string, Scene *>::const_iterator iter;
+
+ if ((iter = mSceneMap.find(name)) != mSceneMap.end())
+ return *(iter->second);
+ else
+ return Scene::dummy();
+}
+
+Benchmark::Benchmark(Scene &scene, const vector<OptionPair> &options) :
+ mScene(scene), mOptions(options)
+{
+}
+
+Benchmark::Benchmark(const string &name, const vector<OptionPair> &options) :
+ mScene(Benchmark::get_scene_by_name(name)), mOptions(options)
+{
+}
+
+Benchmark::Benchmark(const string &s) :
+ mScene(get_scene_from_description(s)),
+ mOptions(get_options_from_description(s))
+{
+}
+
+Scene &
+Benchmark::setup_scene()
+{
+ mScene.reset_options();
+ load_options();
+
+ mScene.load();
+ mScene.setup();
+
+ return mScene;
+}
+
+void
+Benchmark::teardown_scene()
+{
+ mScene.teardown();
+ mScene.unload();
+}
+
+void
+Benchmark::load_options()
+{
+ for (vector<OptionPair>::iterator iter = mOptions.begin();
+ iter != mOptions.end();
+ iter++)
+ {
+ mScene.set_option(iter->first, iter->second);
+ }
+}
+
=== added file 'src/benchmark.h'
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 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)
+ */
+#ifndef GLMARK2_BENCHMARK_H_
+#define GLMARK2_BENCHMARK_H_
+
+#include <vector>
+#include <string>
+#include <map>
+
+#include "scene.h"
+
+class Benchmark
+{
+public:
+ typedef std::pair<std::string, std::string> OptionPair;
+
+ Benchmark(Scene &scene, const std::vector<OptionPair> &options);
+ Benchmark(const std::string &name, const std::vector<OptionPair> &options);
+ // Create a benchmark from a description string of the form:
+ // scene[:opt1=val1:opt2=val2...]
+ Benchmark(const std::string &s);
+
+ Scene &setup_scene();
+ void teardown_scene();
+
+ static void register_scene(Scene &scene);
+ static Scene &get_scene_by_name(const std::string &name);
+ static const std::map<std::string, Scene *> &scenes() { return mSceneMap; }
+
+private:
+ Scene &mScene;
+ std::vector<OptionPair> mOptions;
+
+ void load_options();
+
+ static std::map<std::string, Scene *> mSceneMap;
+};
+
+#endif
=== added file 'src/log.cpp'
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include <cstdio>
+#include <cstdarg>
+
+#include "options.h"
+#include "log.h"
+
+void
+Log::info(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stdout, fmt, ap);
+ va_end(ap);
+}
+
+void
+Log::debug(const char *fmt, ...)
+{
+ if (!Options::show_debug)
+ return;
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stdout, fmt, ap);
+ va_end(ap);
+}
+
+void
+Log::error(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
=== added file 'src/log.h'
@@ -0,0 +1,35 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#ifndef LOG_H_
+#define LOG_H_
+
+class Log
+{
+public:
+ static void info(const char *fmt, ...);
+ static void debug(const char *fmt, ...);
+ static void error(const char *fmt, ...);
+};
+
+#endif /* LOG_H_ */
=== modified file 'src/main.cpp'
@@ -23,6 +23,11 @@
*/
#include "oglsdl.h"
#include "scene.h"
+#include "benchmark.h"
+#include "options.h"
+#include "log.h"
+
+#include <iostream>
#if USE_GL
#include "screen-sdl-gl.h"
@@ -30,16 +35,101 @@
#include "screen-sdl-glesv2.h"
#endif
-#define UNUSED_PARAM(x) (void)(x)
+using std::vector;
+using std::map;
+using std::string;
+
+static const char *default_benchmarks[] = {
+ "build:use-vbo=false",
+ "build:use-vbo=true",
+ "texture:texture-filter=nearest",
+ "texture:texture-filter=linear",
+ "texture:texture-filter=mipmap",
+ "shading:shading=gouraud",
+ "shading:shading=phong",
+ NULL
+};
+
+bool should_keep_running()
+{
+ bool running = true;
+ SDL_Event event;
+
+ while(SDL_PollEvent(&event))
+ {
+ switch(event.type)
+ {
+ case SDL_QUIT:
+ running = false;
+ break;
+ case SDL_KEYDOWN:
+ if(event.key.keysym.sym == SDLK_ESCAPE)
+ running = false;
+ break;
+ }
+ }
+
+ return running;
+}
+
+void
+add_default_benchmarks(vector<Benchmark *> &benchmarks)
+{
+ for (const char **s = default_benchmarks; *s != NULL; s++)
+ benchmarks.push_back(new Benchmark(*s));
+}
+
+void
+add_custom_benchmarks(vector<Benchmark *> &benchmarks)
+{
+ for (vector<string>::const_iterator iter = Options::benchmarks.begin();
+ iter != Options::benchmarks.end();
+ iter++)
+ {
+ benchmarks.push_back(new Benchmark(*iter));
+ }
+}
+
+static void
+list_scenes()
+{
+ const map<string, Scene *> &scenes = Benchmark::scenes();
+
+ for (map<string, Scene *>::const_iterator scene_iter = scenes.begin();
+ scene_iter != scenes.end();
+ scene_iter++)
+ {
+ Scene *scene = scene_iter->second;
+ Log::info("[Scene] %s\n", scene->name().c_str());
+
+ const map<string, Scene::Option> &options = scene->options();
+
+ for (map<string, Scene::Option>::const_iterator opt_iter = options.begin();
+ opt_iter != options.end();
+ opt_iter++)
+ {
+ const Scene::Option &opt = opt_iter->second;
+ Log::info(" [Option] %s\n"
+ " Description : %s\n"
+ " Default Value: %s\n",
+ opt.name.c_str(),
+ opt.description.c_str(),
+ opt.default_value.c_str());
+ }
+ }
+}
int main(int argc, char *argv[])
{
- UNUSED_PARAM(argc);
- UNUSED_PARAM(argv);
-
- SDL_Event event;
- int running = 1;
- unsigned current_scene = 0;
+ unsigned score = 0;
+
+ if (!Options::parse_args(argc, argv))
+ return 1;
+
+ if (Options::show_help) {
+ Options::print_help();
+ return 0;
+ }
// Create the screen
#if USE_GL
@@ -53,80 +143,63 @@
return 1;
}
+ // Register the scenes, so they can be looked-up by name
+ Benchmark::register_scene(*new SceneBuild(screen));
+ Benchmark::register_scene(*new SceneTexture(screen));
+ Benchmark::register_scene(*new SceneShading(screen));
+
+ if (Options::list_scenes) {
+ list_scenes();
+ return 0;
+ }
+
+ // Add the benchmarks to run
+ vector<Benchmark *> benchmarks;
+
+ if (Options::benchmarks.empty())
+ add_default_benchmarks(benchmarks);
+ else
+ add_custom_benchmarks(benchmarks);
+
printf("=======================================================\n");
printf(" glmark2 %s\n", GLMARK_VERSION);
printf("=======================================================\n");
screen.print_info();
printf("=======================================================\n");
- // Create the scenes.
- Scene *scene[] = {
- new SceneBuild(screen),
- new SceneTexture(screen),
- new SceneShading(screen),
- };
-
- unsigned num_scenes = sizeof(scene) / sizeof(*scene);
-
- // Load the first scene
- if (!scene[current_scene]->load())
- return 1;
- scene[current_scene]->start();
-
- while(running)
+ // Run the benchmarks
+ for (vector<Benchmark *>::iterator bench_iter = benchmarks.begin();
+ bench_iter != benchmarks.end();
+ bench_iter++)
{
- while(SDL_PollEvent(&event))
+ bool keep_running = true;
+ Benchmark *bench = *bench_iter;
+ Scene &scene = bench->setup_scene();
+ std::cout << scene.info_string() << std::flush;
+
+ while (scene.is_running() &&
+ (keep_running = should_keep_running()))
{
- switch(event.type)
- {
- case SDL_QUIT:
- running = 0;
- break;
- case SDL_KEYDOWN:
- if(event.key.keysym.sym == SDLK_ESCAPE)
- running = 0;
- break;
- }
- }
-
- screen.clear();
-
- // Update the state of the current scene
- scene[current_scene]->update();
-
- // If the current scene is still running then draw it,
- // otherwise move to the next scene
- if (scene[current_scene]->is_running()) {
- scene[current_scene]->draw();
- }
- else {
- // Unload the current scene
- scene[current_scene]->unload();
-
- current_scene++;
-
- // Do we have another scene?
- if (current_scene < num_scenes) {
- // Load and start next scene
- if (!scene[current_scene]->load())
- return 1;
- scene[current_scene]->start();
- }
- else
- running = false;
- }
-
-
- screen.update();
+ screen.clear();
+
+ scene.draw();
+ scene.update();
+
+ screen.update();
+ }
+
+ std::cout << " FPS: " << scene.average_fps() << std::endl;
+ score += scene.average_fps();
+
+ bench->teardown_scene();
+
+ if (!keep_running)
+ break;
}
- unsigned score = 0;
- for (unsigned i = 0; i < num_scenes; i++)
- score += scene[i]->calculate_score();
-
printf("=======================================================\n");
printf(" glmark2 Score: %u \n", score);
- printf("=======================================================\n");
+ printf("=======================================================\n");
return 0;
}
=== modified file 'src/mesh.cpp'
@@ -44,8 +44,20 @@
Mesh::~Mesh()
{
+ reset();
+}
+
+void
+Mesh::reset()
+{
delete [] mVertex;
- //deleteArray
+
+ delete_vbo();
+
+ mPolygonQty = 0;
+ mVertexQty = 0;
+ mMode = GL_TRIANGLES;
+ mVertex = 0;
}
void Mesh::make_cube()
@@ -180,6 +192,14 @@
#endif
}
+void
+Mesh::delete_vbo()
+{
+ glDeleteBuffers(1, &mVBOVertices);
+ glDeleteBuffers(1, &mVBONormals);
+ glDeleteBuffers(1, &mVBOTexCoords);
+}
+
void Mesh::render_vbo()
{
// Enable the attributes
=== modified file 'src/mesh.h'
@@ -64,10 +64,12 @@
Mesh(); // Default Constructor, should set pointers to null
~Mesh();
+ void reset();
void make_cube();
void make_torus();
void render_array();
void build_vbo();
+ void delete_vbo();
void render_vbo();
};
=== modified file 'src/model.cpp'
@@ -49,6 +49,8 @@
#ifdef _DEBUG
printf("Converting model to mesh... ");
#endif
+ pMesh->reset();
+
pMesh->mVertexQty = 3 * mPolygonQty;
pMesh->mPolygonQty = mPolygonQty;
pMesh->mMode = GL_TRIANGLES;
=== added file 'src/options.cpp'
@@ -0,0 +1,93 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include <cstring>
+#include <cstdlib>
+#include <cstdio>
+#include <getopt.h>
+
+#include "options.h"
+
+std::vector<std::string> Options::benchmarks;
+bool Options::swap_buffers = true;
+bool Options::list_scenes = false;
+bool Options::show_debug = false;
+bool Options::show_help = false;
+
+static struct option long_options[] = {
+ {"benchmark", 1, 0, 0},
+ {"no-swap-buffers", 0, 0, 0},
+ {"list-scenes", 0, 0, 0},
+ {"debug", 0, 0, 0},
+ {"help", 0, 0, 0},
+ {0, 0, 0, 0}
+};
+
+void
+Options::print_help()
+{
+ printf("A benchmark for Open GL (ES) 2.0\n"
+ "\n"
+ "Options:\n"
+ " -b, --benchmark BENCH A benchmark to run: 'scene(:opt1=val1)*'\n"
+ " (the option can be used multiple times)\n"
+ " --no-swap-buffers Don't update the screen by swapping the front and\n"
+ " back buffer, use glFinish() instead\n"
+ " -l, --list-scenes Display information about the available scenes\n"
+ " and their options\n"
+ " -d, --debug Display debug messages\n"
+ " -h, --help Display help\n");
+}
+
+bool
+Options::parse_args(int argc, char **argv)
+{
+ while (1) {
+ int option_index = -1;
+ int c;
+ const char *optname = "";
+
+ c = getopt_long(argc, argv, "b:ldh",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+ if (c == ':' || c == '?')
+ return false;
+
+ if (option_index != -1)
+ optname = long_options[option_index].name;
+
+ if (c == 'b' || !strcmp(optname, "benchmark"))
+ Options::benchmarks.push_back(optarg);
+ else if (!strcmp(optname, "no-swap-buffers"))
+ Options::swap_buffers = false;
+ else if (c == 'l' || !strcmp(optname, "list-scenes"))
+ Options::list_scenes = true;
+ else if (c == 'd' || !strcmp(optname, "debug"))
+ Options::show_debug = true;
+ else if (c == 'h' || !strcmp(optname, "help"))
+ Options::show_help = true;
+ }
+
+ return true;
+}
=== added file 'src/options.h'
@@ -0,0 +1,41 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench 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.
+ *
+ * glcompbench 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 glcompbench. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ * Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ * Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#ifndef OPTIONS_H_
+#define OPTIONS_H_
+
+#include <string>
+#include <vector>
+
+struct Options {
+ static bool parse_args(int argc, char **argv);
+ static void print_help();
+
+ static std::vector<std::string> benchmarks;
+ static bool swap_buffers;
+ static bool list_scenes;
+ static bool show_debug;
+ static bool show_help;
+};
+
+#endif /* OPTIONS_H_ */
=== modified file 'src/scene.cpp'
@@ -22,32 +22,23 @@
* Alexandros Frantzis (glmark2)
*/
#include "scene.h"
-
-Scene::Scene(Screen &pScreen) :
- mScreen(pScreen)
+#include <sstream>
+
+using std::stringstream;
+using std::string;
+using std::map;
+
+Scene::Scene(Screen &pScreen, const string &name) :
+ mScreen(pScreen), mName(name),
+ mStartTime(0), mLastUpdateTime(0), mCurrentFrame(0), mAverageFPS(0),
+ mRunning(0), mDuration(0)
{
- mPartsQty = 0;
- mCurrentPart = 0;
- mPartDuration = 0;
-
- mLastTime = 0;
- mCurrentTime = 0;
- mDt = 0;
- mCurrentFrame = 0;
- mRunning = false;
-
- mAverageFPS = 0;
- mScoreScale = 0;
-
- mStartTime = 0;
- mElapsedTime = 0;
+ mOptions["duration"] = Scene::Option("duration", "10.0",
+ "The duration of each benchmark in seconds");
}
Scene::~Scene()
{
- delete [] mPartDuration;
- delete [] mAverageFPS;
- delete [] mScoreScale;
}
int Scene::load()
@@ -59,7 +50,13 @@
{
}
-void Scene::start()
+void Scene::setup()
+{
+ stringstream ss(mOptions["duration"].value);
+ ss >> mDuration;
+}
+
+void Scene::teardown()
{
}
@@ -71,14 +68,19 @@
{
}
-unsigned Scene::calculate_score()
-{
- unsigned mScore = 0;
-
- for(unsigned i = 0; i < mPartsQty; i++)
- mScore += mAverageFPS[i] * mScoreScale[i];
-
- return mScore;
+string
+Scene::info_string(const string &title)
+{
+ stringstream ss;
+
+ ss << "[" << mName << "] " << Scene::construct_title(title) << " ";
+
+ return ss.str();
+}
+
+unsigned Scene::average_fps()
+{
+ return mAverageFPS;
}
@@ -86,3 +88,49 @@
{
return mRunning;
}
+
+bool
+Scene::set_option(const string &opt, const string &val)
+{
+ map<string, Option>::iterator iter = mOptions.find(opt);
+
+ if (iter == mOptions.end())
+ return false;
+
+ iter->second.value = val;
+
+ return true;
+}
+
+void
+Scene::reset_options()
+{
+ for (map<string, Option>::iterator iter = mOptions.begin();
+ iter != mOptions.end();
+ iter++)
+ {
+ Option &opt = iter->second;
+
+ opt.value = opt.default_value;
+ }
+}
+
+
+string
+Scene::construct_title(const string &title)
+{
+ stringstream ss;
+
+ if (title == "") {
+ for (map<string, Option>::iterator iter = mOptions.begin();
+ iter != mOptions.end();
+ iter++)
+ {
+ ss << iter->first << "=" << iter->second.value << ":";
+ }
+ }
+ else
+ ss << title;
+
+ return ss.str();
+}
=== modified file 'src/scene.h'
@@ -33,46 +33,80 @@
#include <math.h>
+#include <string>
+#include <map>
+
class Scene
{
public:
- Scene(Screen &pScreen);
~Scene();
+ struct Option {
+ Option(const std::string &nam, const std::string &val, const std::string &desc) :
+ name(nam), value(val), default_value(val), description(desc) {}
+ Option() {}
+ std::string name;
+ std::string value;
+ std::string default_value;
+ std::string description;
+ };
+
+ // load() and unload() handle option-independent configuration.
+ // It should be safe to call these only once per program execution,
+ // although you may choose to do so more times to better manage
+ // resource consumption.
virtual int load();
virtual void unload();
- virtual void start();
+
+ // setup() and teardown() handle option-dependent configuration and
+ // also prepare a scene for a benchmark run.
+ // They should be called just before and after running a scene/benchmark.
+ virtual void setup();
+ virtual void teardown();
+
virtual void update();
virtual void draw();
+ virtual std::string info_string(const std::string &title = "");
- unsigned calculate_score();
+ unsigned average_fps();
bool is_running();
+ const std::string &name() { return mName; }
+ bool set_option(const std::string &opt, const std::string &val);
+ void reset_options();
+ const std::map<std::string, Option> &options() { return mOptions; }
+
+ static Scene &dummy()
+ {
+ static Scene dummy_scene(Screen::dummy(), "");
+ return dummy_scene;
+ }
+
protected:
- unsigned mPartsQty; // How many parts for the scene
- unsigned mCurrentPart; // The current part being rendered
- double *mPartDuration; // Duration per part in seconds
-
- double mLastTime, mCurrentTime, mDt;
+ Scene(Screen &pScreen, const std::string &name);
+ std::string construct_title(const std::string &title);
+
+ Screen &mScreen;
+ std::string mName;
+ std::map<std::string, Option> mOptions;
+
+ double mStartTime;
+ double mLastUpdateTime;
unsigned mCurrentFrame;
+ unsigned mAverageFPS; // Average FPS of run
+
bool mRunning;
-
- unsigned *mAverageFPS; // Average FPS per part
- float *mScoreScale;
-
- double mStartTime;
- double mElapsedTime;
-
- Screen &mScreen;
+ double mDuration; // Duration of run in seconds
};
class SceneBuild : public Scene
{
public:
- SceneBuild(Screen &pScreen) : Scene(pScreen) {}
+ SceneBuild(Screen &pScreen);
int load();
void unload();
- void start();
+ void setup();
+ void teardown();
void update();
void draw();
@@ -84,15 +118,17 @@
Mesh mMesh;
float mRotation;
float mRotationSpeed;
+ bool mUseVbo;
};
class SceneTexture : public Scene
{
public:
- SceneTexture(Screen &pScreen) : Scene(pScreen) {}
+ SceneTexture(Screen &pScreen);
int load();
void unload();
- void start();
+ void setup();
+ void teardown();
void update();
void draw();
@@ -102,7 +138,7 @@
Shader mShader;
Mesh mCubeMesh;
- GLuint mTexture[3];
+ GLuint mTexture;
Vector3f mRotation;
Vector3f mRotationSpeed;
};
@@ -110,17 +146,18 @@
class SceneShading : public Scene
{
public:
- SceneShading(Screen &pScreen) : Scene(pScreen) {}
+ SceneShading(Screen &pScreen);
int load();
void unload();
- void start();
+ void setup();
+ void teardown();
void update();
void draw();
~SceneShading();
protected:
- Shader mShader[2];
+ Shader mShader;
Mesh mMesh;
float mRotation;
=== modified file 'src/scenebuild.cpp'
@@ -23,6 +23,13 @@
*/
#include "scene.h"
+SceneBuild::SceneBuild(Screen &pScreen) :
+ Scene(pScreen, "build")
+{
+ mOptions["use-vbo"] = Scene::Option("use-vbo", "true",
+ "Whether to use VBOs for rendering [true,false]");
+}
+
SceneBuild::~SceneBuild()
{
}
@@ -37,47 +44,38 @@
model.calculate_normals();
model.convert_to_mesh(&mMesh);
- mMesh.build_vbo();
-
mShader.load(GLMARK_DATA_PATH"/shaders/light-basic.vert",
GLMARK_DATA_PATH"/shaders/light-basic.frag");
mRotationSpeed = 36.0f;
- mRotation = 0.0;
mRunning = false;
- mPartsQty = 2;
- mPartDuration = new double[mPartsQty];
- mAverageFPS = new unsigned[mPartsQty];
- mScoreScale = new float[mPartsQty];
-
- mScoreScale[0] = 1.0f / mPartsQty;
- mScoreScale[1] = 1.0f / mPartsQty;
-
- mPartDuration[0] = 10.0;
- mPartDuration[1] = 10.0;
-
- memset(mAverageFPS, 0, mPartsQty * sizeof(*mAverageFPS));
-
- mCurrentPart = 0;
-
return 1;
}
void SceneBuild::unload()
{
+ mMesh.reset();
mShader.remove();
mShader.unload();
}
-void SceneBuild::start()
+void SceneBuild::setup()
{
+ Scene::setup();
+
GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f};
GLfloat materialColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
+
+ mUseVbo = (mOptions["use-vbo"].value == "true");
+
+ if (mUseVbo)
+ mMesh.build_vbo();
+
mShader.use();
// Load lighting and material uniforms
@@ -89,43 +87,37 @@
glUniform4fv(mShader.mLocations.MaterialColor, 1, materialColor);
mCurrentFrame = 0;
+ mRotation = 0.0;
mRunning = true;
mStartTime = SDL_GetTicks() / 1000.0;
- mLastTime = mStartTime;
-
- if (mCurrentPart == 0)
- printf("[Suite] Precompilation\n");
+ mLastUpdateTime = mStartTime;
+}
+
+void
+SceneBuild::teardown()
+{
+ mShader.remove();
+
+ if (mUseVbo)
+ mMesh.delete_vbo();
+
+ Scene::teardown();
}
void SceneBuild::update()
{
- mCurrentTime = SDL_GetTicks() / 1000.0;
- mDt = mCurrentTime - mLastTime;
- mLastTime = mCurrentTime;
-
- mElapsedTime = mCurrentTime - mStartTime;
-
- if(mElapsedTime >= mPartDuration[mCurrentPart])
- {
- mAverageFPS[mCurrentPart] = mCurrentFrame / mElapsedTime;
-
- switch(mCurrentPart)
- {
- case 0:
- printf(" [Benchmark] Vertex array FPS: %u\n", mAverageFPS[mCurrentPart]);
- break;
- case 1:
- printf(" [Benchmark] Vertex buffer object FPS: %u\n", mAverageFPS[mCurrentPart]);
- break;
- }
- mCurrentPart++;
- if(mCurrentPart >= mPartsQty)
- mRunning = false;
- else
- start();
+ double current_time = SDL_GetTicks() / 1000.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;
}
- mRotation += mRotationSpeed * mDt;
+ mRotation += mRotationSpeed * dt;
mCurrentFrame++;
}
@@ -149,13 +141,8 @@
glUniformMatrix4fv(mShader.mLocations.NormalMatrix, 1,
GL_FALSE, model_view.m);
- switch(mCurrentPart)
- {
- case 0:
+ if (mUseVbo)
+ mMesh.render_vbo();
+ else
mMesh.render_array();
- break;
- case 1:
- mMesh.render_vbo();
- break;
- }
}
=== modified file 'src/sceneshading.cpp'
@@ -24,6 +24,13 @@
#include "scene.h"
#include "matrix.h"
+SceneShading::SceneShading(Screen &pScreen) :
+ Scene(pScreen, "shading")
+{
+ mOptions["shading"] = Scene::Option("shading", "gouraud",
+ "[gouraud, phong]");
+}
+
SceneShading::~SceneShading()
{
}
@@ -40,44 +47,22 @@
mMesh.build_vbo();
- mShader[0].load(GLMARK_DATA_PATH"/shaders/light-basic.vert",
- GLMARK_DATA_PATH"/shaders/light-basic.frag");
- mShader[1].load(GLMARK_DATA_PATH"/shaders/light-advanced.vert",
- GLMARK_DATA_PATH"/shaders/light-advanced.frag");
-
mRotationSpeed = 36.0f;
- mRotation = 0.0f;
mRunning = false;
- mPartsQty = 2;
- mPartDuration = new double[mPartsQty];
- mAverageFPS = new unsigned[mPartsQty];
- mScoreScale = new float[mPartsQty];
-
- mScoreScale[0] = 1.0f / mPartsQty;
- mScoreScale[1] = 1.0f / mPartsQty;
-
- mPartDuration[0] = 10.0;
- mPartDuration[1] = 10.0;
-
- memset(mAverageFPS, 0, mPartsQty * sizeof(*mAverageFPS));
-
- mCurrentPart = 0;
-
return 1;
}
void SceneShading::unload()
{
- for(unsigned i = 0; i < mPartsQty; i++) {
- mShader[i].remove();
- mShader[i].unload();
- }
+ mMesh.reset();
}
-void SceneShading::start()
+void SceneShading::setup()
{
+ Scene::setup();
+
GLfloat lightAmbient[] = {0.1f, 0.1f, 0.1f, 1.0f};
GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat lightSpecular[] = {0.8f, 0.8f, 0.8f, 1.0f};
@@ -88,67 +73,68 @@
float materialSpecular[] = {1.0f, 1.0f, 1.0f, 1.0f};
float materialColor[] = {0.0f, 0.0f, 1.0f, 1.0f};
- mShader[mCurrentPart].use();
+ const std::string &shading = mOptions["shading"].value;
+
+ if (shading == "gouraud") {
+ mShader.load(GLMARK_DATA_PATH"/shaders/light-basic.vert",
+ GLMARK_DATA_PATH"/shaders/light-basic.frag");
+ }
+ else if (shading == "phong") {
+ mShader.load(GLMARK_DATA_PATH"/shaders/light-advanced.vert",
+ GLMARK_DATA_PATH"/shaders/light-advanced.frag");
+ }
+
+ mShader.use();
// Load lighting and material uniforms
- glUniform4fv(mShader[mCurrentPart].mLocations.LightSourcePosition, 1, lightPosition);
-
- glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceAmbient, 1, lightAmbient);
- glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceDiffuse, 1, lightDiffuse);
- glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceSpecular, 1, lightSpecular);
-
- glUniform3fv(mShader[mCurrentPart].mLocations.MaterialAmbient, 1, materialAmbient);
- glUniform3fv(mShader[mCurrentPart].mLocations.MaterialDiffuse, 1, materialDiffuse);
- glUniform3fv(mShader[mCurrentPart].mLocations.MaterialSpecular, 1, materialSpecular);
- glUniform4fv(mShader[mCurrentPart].mLocations.MaterialColor, 1, materialColor);
+ glUniform4fv(mShader.mLocations.LightSourcePosition, 1, lightPosition);
+
+ glUniform3fv(mShader.mLocations.LightSourceAmbient, 1, lightAmbient);
+ glUniform3fv(mShader.mLocations.LightSourceDiffuse, 1, lightDiffuse);
+ glUniform3fv(mShader.mLocations.LightSourceSpecular, 1, lightSpecular);
+
+ glUniform3fv(mShader.mLocations.MaterialAmbient, 1, materialAmbient);
+ glUniform3fv(mShader.mLocations.MaterialDiffuse, 1, materialDiffuse);
+ glUniform3fv(mShader.mLocations.MaterialSpecular, 1, materialSpecular);
+ glUniform4fv(mShader.mLocations.MaterialColor, 1, materialColor);
// Calculate and load the half vector
Vector3f halfVector = Vector3f(lightPosition[0], lightPosition[1], lightPosition[2]);
halfVector.normalize();
halfVector += Vector3f(0.0, 0.0, 1.0);
halfVector.normalize();
- glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceHalfVector, 1,
+ glUniform3fv(mShader.mLocations.LightSourceHalfVector, 1,
(GLfloat *)&halfVector);
mCurrentFrame = 0;
+ mRotation = 0.0f;
mRunning = true;
mStartTime = SDL_GetTicks() / 1000.0;
- mLastTime = mStartTime;
-
- if (mCurrentPart == 0)
- printf("[Suite] Shading\n");
+ mLastUpdateTime = mStartTime;
+}
+
+void SceneShading::teardown()
+{
+ mShader.remove();
+ mShader.unload();
+
+ Scene::teardown();
}
void SceneShading::update()
{
- mCurrentTime = SDL_GetTicks() / 1000.0;
- mDt = mCurrentTime - mLastTime;
- mLastTime = mCurrentTime;
-
- mElapsedTime = mCurrentTime - mStartTime;
-
- if(mElapsedTime >= mPartDuration[mCurrentPart])
- {
- mAverageFPS[mCurrentPart] = mCurrentFrame / mElapsedTime;
-
- switch(mCurrentPart) {
- case 0:
- printf(" [Benchmark] GLSL per vertex lighting FPS: %u\n",
- mAverageFPS[mCurrentPart]);
- break;
- case 1:
- printf(" [Benchmark] GLSL per pixel lighting FPS: %u\n",
- mAverageFPS[mCurrentPart]);
- break;
- }
- mCurrentPart++;
- if(mCurrentPart >= mPartsQty)
- mRunning = false;
- else
- start();
+ double current_time = SDL_GetTicks() / 1000.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;
}
- mRotation += mRotationSpeed * mDt;
+ mRotation += mRotationSpeed * dt;
mCurrentFrame++;
}
@@ -163,13 +149,13 @@
model_view.rotate(2 * M_PI * mRotation / 360.0, 0.0f, 1.0f, 0.0f);
model_view_proj *= model_view;
- glUniformMatrix4fv(mShader[mCurrentPart].mLocations.ModelViewProjectionMatrix, 1,
+ glUniformMatrix4fv(mShader.mLocations.ModelViewProjectionMatrix, 1,
GL_FALSE, model_view_proj.m);
// Load the NormalMatrix uniform in the shader. The NormalMatrix is the
// inverse transpose of the model view matrix.
model_view.invert().transpose();
- glUniformMatrix4fv(mShader[mCurrentPart].mLocations.NormalMatrix, 1,
+ glUniformMatrix4fv(mShader.mLocations.NormalMatrix, 1,
GL_FALSE, model_view.m);
mMesh.render_vbo();
=== modified file 'src/scenetexture.cpp'
@@ -24,10 +24,15 @@
#include "scene.h"
#include "matrix.h"
+SceneTexture::SceneTexture(Screen &pScreen) :
+ Scene(pScreen, "texture")
+{
+ mOptions["texture-filter"] = Scene::Option("texture-filter", "nearest",
+ "[nearest, linear, mipmap]");
+}
+
SceneTexture::~SceneTexture()
{
- for(unsigned i = 0; i < 3; i++)
- glDeleteTextures(1, &mTexture[i]);
}
int SceneTexture::load()
@@ -37,9 +42,6 @@
if(!model.load_3ds(GLMARK_DATA_PATH"/models/cube.3ds"))
return 0;
- if(!load_texture(GLMARK_DATA_PATH"/textures/crate-base.bmp", mTexture))
- return 0;
-
model.calculate_normals();
model.convert_to_mesh(&mCubeMesh);
mCubeMesh.build_vbo();
@@ -51,39 +53,45 @@
mRunning = false;
- mPartsQty = 3;
- mPartDuration = new double[mPartsQty];
- mAverageFPS = new unsigned[mPartsQty];
- mScoreScale = new float[mPartsQty];
-
- mScoreScale[0] = 1.0f / mPartsQty;
- mScoreScale[1] = 1.0f / mPartsQty;
- mScoreScale[2] = 1.0f / mPartsQty;
-
- mPartDuration[0] = 10.0;
- mPartDuration[1] = 10.0;
- mPartDuration[2] = 10.0;
-
- memset(mAverageFPS, 0, mPartsQty * sizeof(*mAverageFPS));
-
- mCurrentPart = 0;
-
return 1;
}
void SceneTexture::unload()
{
- mShader.remove();
+ mCubeMesh.reset();
mShader.unload();
}
-void SceneTexture::start()
+void SceneTexture::setup()
{
+ Scene::setup();
+
GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f};
GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f};
GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f};
GLfloat 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;
+ const std::string &filter = mOptions["texture-filter"].value;
+
+ if (filter == "nearest") {
+ min_filter = GL_NEAREST;
+ mag_filter = GL_NEAREST;
+ }
+ else if (filter == "linear") {
+ min_filter = GL_LINEAR;
+ mag_filter = GL_LINEAR;
+ }
+ else if (filter == "mipmap") {
+ min_filter = GL_LINEAR_MIPMAP_LINEAR;
+ mag_filter = GL_LINEAR;
+ }
+
+ Texture::load(GLMARK_DATA_PATH"/textures/crate-base.bmp", &mTexture,
+ min_filter, mag_filter, 0);
+
mShader.use();
// Load lighting and material uniforms
@@ -95,45 +103,34 @@
glUniform4fv(mShader.mLocations.MaterialColor, 1, materialColor);
mCurrentFrame = 0;
+ mRotation = Vector3f();
mRunning = true;
mStartTime = SDL_GetTicks() / 1000.0;
- mLastTime = mStartTime;
-
- if (mCurrentPart == 0)
- printf("[Suite] Texture filtering\n");
+ mLastUpdateTime = mStartTime;
+}
+
+void SceneTexture::teardown()
+{
+ mShader.remove();
+ glDeleteTextures(1, &mTexture);
+
+ Scene::teardown();
}
void SceneTexture::update()
{
- mCurrentTime = SDL_GetTicks() / 1000.0;
- mDt = mCurrentTime - mLastTime;
- mLastTime = mCurrentTime;
-
- mElapsedTime = mCurrentTime - mStartTime;
-
- if(mElapsedTime >= mPartDuration[mCurrentPart])
- {
- mAverageFPS[mCurrentPart] = mCurrentFrame / mElapsedTime;
-
- switch(mCurrentPart) {
- case 0:
- printf(" [Benchmark] Nearest FPS: %u\n", mAverageFPS[mCurrentPart]);
- break;
- case 1:
- printf(" [Benchmark] Linear FPS: %u\n", mAverageFPS[mCurrentPart]);
- break;
- case 2:
- printf(" [Benchmark] Mipmapped FPS: %u\n", mAverageFPS[mCurrentPart]);
- break;
- }
- mCurrentPart++;
- if(mCurrentPart >= mPartsQty)
- mRunning = false;
- else
- start();
+ double current_time = SDL_GetTicks() / 1000.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;
}
- mRotation += mRotationSpeed * mDt;
+ mRotation += mRotationSpeed * dt;
mCurrentFrame++;
}
@@ -160,7 +157,7 @@
GL_FALSE, model_view.m);
glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, mTexture[mCurrentPart]);
+ glBindTexture(GL_TEXTURE_2D, mTexture);
mCubeMesh.render_vbo();
}
=== modified file 'src/screen-sdl-gl.cpp'
@@ -22,6 +22,7 @@
* Alexandros Frantzis (glmark2)
*/
#include "screen-sdl-gl.h"
+#include "options.h"
ScreenSDLGL::ScreenSDLGL(int pWidth, int pHeight, int pBpp, int pFullScreen, int pFlags)
: ScreenSDL(pWidth, pHeight, pBpp, pFullScreen, pFlags | SDL_OPENGL)
@@ -50,7 +51,10 @@
void ScreenSDLGL::update()
{
- SDL_GL_SwapBuffers();
+ if (Options::swap_buffers)
+ SDL_GL_SwapBuffers();
+ else
+ glFinish();
}
void ScreenSDLGL::print_info()
=== modified file 'src/screen-sdl-glesv2.cpp'
@@ -23,6 +23,7 @@
*/
#include "screen-sdl-glesv2.h"
#include "sdlgles/SDL_gles.h"
+#include "options.h"
ScreenSDLGLESv2::ScreenSDLGLESv2(int pWidth, int pHeight, int pBpp, int pFullScreen, int pFlags)
: ScreenSDL(pWidth, pHeight, pBpp, pFullScreen, pFlags)
@@ -96,7 +97,10 @@
void ScreenSDLGLESv2::update()
{
- SDL_GLES_SwapBuffers();
+ if (Options::swap_buffers)
+ SDL_GLES_SwapBuffers();
+ else
+ glFinish();
}
void ScreenSDLGLESv2::print_info()
=== modified file 'src/screen.h'
@@ -32,6 +32,8 @@
class Screen
{
public:
+ ~Screen() {}
+
int mWidth;
int mHeight;
int mBpp;
@@ -39,9 +41,18 @@
Matrix4f mProjection;
int mInitSuccess;
- virtual void clear() = 0;
- virtual void update() = 0;
- virtual void print_info() = 0;
+ virtual void clear() {}
+ virtual void update() {}
+ virtual void print_info() {}
+
+ static Screen &dummy()
+ {
+ static Screen dummy_screen;
+ return dummy_screen;
+ }
+
+protected:
+ Screen() {}
};
#endif
=== modified file 'src/texture.cpp'
@@ -23,13 +23,32 @@
*/
#include "texture.h"
-int load_texture(const char pFilename[], GLuint *pTexture)
+static void
+setup_texture(GLuint *tex, GLenum format, SDL_Surface *surface,
+ GLint min_filter, GLint mag_filter)
+{
+ glGenTextures(1, tex);
+ glBindTexture(GL_TEXTURE_2D, *tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter);
+ glTexImage2D(GL_TEXTURE_2D, 0, format, surface->w, surface->h, 0,
+ format, GL_UNSIGNED_BYTE, surface->pixels);
+
+ if ((min_filter != GL_NEAREST && min_filter != GL_LINEAR) ||
+ (mag_filter != GL_NEAREST && mag_filter != GL_LINEAR))
+ {
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+}
+
+int
+Texture::load(const std::string &filename, GLuint *pTexture, ...)
{
SDL_Surface *surface;
GLenum texture_format = GL_RGB;
GLint nOfColors;
- if ((surface = SDL_LoadBMP(pFilename))) {
+ if ((surface = SDL_LoadBMP(filename.c_str()))) {
if ((surface->w & (surface->w - 1)) != 0)
printf("warning: image.bmp's width is not a power of 2\n");
@@ -79,29 +98,17 @@
printf("warning: the image is not truecolor.. this will probably break\n");
}
- glGenTextures(3, pTexture);
-
- // Create Nearest Filtered Texture
- glBindTexture(GL_TEXTURE_2D, pTexture[0]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexImage2D(GL_TEXTURE_2D, 0, texture_format, surface->w, surface->h, 0,
- texture_format, GL_UNSIGNED_BYTE, surface->pixels);
-
- // Create Linear Filtered Texture
- glBindTexture(GL_TEXTURE_2D, pTexture[1]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, texture_format, surface->w, surface->h, 0,
- texture_format, GL_UNSIGNED_BYTE, surface->pixels);
-
- // Create trilinear filtered mipmapped texture
- glBindTexture(GL_TEXTURE_2D, pTexture[2]);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexImage2D(GL_TEXTURE_2D, 0, texture_format, surface->w, surface->h, 0,
- texture_format, GL_UNSIGNED_BYTE, surface->pixels);
- glGenerateMipmap(GL_TEXTURE_2D);
+ va_list ap;
+ va_start(ap, pTexture);
+ GLint arg;
+
+ while ((arg = va_arg(ap, GLint)) != 0) {
+ GLint arg2 = va_arg(ap, GLint);
+ setup_texture(pTexture, texture_format, surface, arg, arg2);
+ pTexture++;
+ }
+
+ va_end(ap);
}
else {
fprintf(stderr, "SDL could not load image.bmp: %s\n", SDL_GetError());
=== modified file 'src/texture.h'
@@ -26,8 +26,12 @@
#include "oglsdl.h"
-#include <stdio.h>
+#include <string>
-int load_texture(const char pFilename[], GLuint *pTexture);
+class Texture
+{
+public:
+ static int load(const std::string &filename, GLuint *pTexture, ...);
+};
#endif