summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-12-14 13:54:34 +0100
committerMatthias Schiffer <matthias@gamezock.de>2009-12-14 13:54:34 +0100
commitff7b7c8838f55dc0f2e76f903630f1d3d2941d5a (patch)
tree2c2f053b84251c9216a851a26edac4bc17c607bb
parentda66d49b8a7bcc808df201bee5c7cb787b6f30b7 (diff)
downloadzoom++-ff7b7c8838f55dc0f2e76f903630f1d3d2941d5a.tar
zoom++-ff7b7c8838f55dc0f2e76f903630f1d3d2941d5a.zip
Added everything... -.-
-rw-r--r--BSPTree.cpp83
-rw-r--r--BSPTree.h93
-rw-r--r--CMakeLists.txt11
-rw-r--r--FindGLPng.cmake16
-rw-r--r--Game.cpp47
-rw-r--r--Game.h6
-rw-r--r--Level.cpp260
-rw-r--r--Level.h74
-rw-r--r--Renderer.cpp34
-rw-r--r--Renderer.h26
-rw-r--r--Texture.cpp44
-rw-r--r--Texture.h40
-rw-r--r--Triangle.h90
-rw-r--r--config.h2
-rw-r--r--gl.h25
-rw-r--r--levels/level.dtd61
-rw-r--r--levels/level.xml392
-rw-r--r--tex/blue.pngbin0 -> 80980 bytes
-rw-r--r--tex/cursor.pngbin0 -> 651 bytes
-rw-r--r--tex/dark.pngbin0 -> 40686 bytes
-rw-r--r--tex/door.pngbin0 -> 110154 bytes
-rw-r--r--tex/fire.pngbin0 -> 63077 bytes
-rw-r--r--tex/green.pngbin0 -> 708834 bytes
-rw-r--r--tex/green2.pngbin0 -> 79738 bytes
-rw-r--r--tex/light.pngbin0 -> 215452 bytes
-rw-r--r--tex/lightmap.pngbin0 -> 13789 bytes
-rw-r--r--tex/lightmap2.pngbin0 -> 31318 bytes
-rw-r--r--tex/medib.pngbin0 -> 136 bytes
-rw-r--r--tex/metallic.pngbin0 -> 570955 bytes
-rw-r--r--tex/metallic2.pngbin0 -> 546156 bytes
-rw-r--r--tex/textur.pngbin0 -> 86779 bytes
-rw-r--r--tex/wall1.pngbin0 -> 435 bytes
-rw-r--r--tex/wall2.pngbin0 -> 698 bytes
-rw-r--r--tex/wall3.pngbin0 -> 1298 bytes
-rw-r--r--tex/wall4.pngbin0 -> 22161 bytes
-rw-r--r--tex/wall5.pngbin0 -> 12430 bytes
-rw-r--r--zoom.cpp24
37 files changed, 1194 insertions, 134 deletions
diff --git a/BSPTree.cpp b/BSPTree.cpp
index fa2f1c0..a94c77a 100644
--- a/BSPTree.cpp
+++ b/BSPTree.cpp
@@ -1,5 +1,23 @@
-#include "BSPTree.h"
+/*
+ * BSPTree.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "BSPTree.h"
namespace Zoom {
@@ -9,20 +27,20 @@ vmml::vec3f BSPTree::Plane::intersection(const vmml::vec3f &p, const vmml::vec3f
return p + r*dir;
}
-void BSPTree::Plane::partition(const Triangle &t, std::list<Triangle> *front, std::list<Triangle> *back) const {
+void BSPTree::Plane::partition(const TriangleRecord &t, std::list<TriangleRecord> *front, std::list<TriangleRecord> *back) const {
for(int i = 0; i < 3; ++i) {
- if(contains(t.getVertex(i))) {
- const vmml::vec3f *v[3] = {&t.getVertex(i), &t.getVertex((i+1)%3), &t.getVertex((i+2)%3)};
+ if(contains(t.triangle.getVertex(i))) {
+ const vmml::vec3f *v[3] = {&t.triangle.getVertex(i), &t.triangle.getVertex((i+1)%3), &t.triangle.getVertex((i+2)%3)};
vmml::vec3f is = intersection(*v[1], *v[2]-*v[1]);
if(isInFront(*v[1])) {
- front->push_back(Triangle(*v[0], *v[1], is, t.getColor()));
- back->push_back(Triangle(*v[0], is, *v[2], t.getColor()));
+ front->push_back(TriangleRecord(Triangle(*v[0], *v[1], is, t.triangle.getColor()), t.data));
+ back->push_back(TriangleRecord(Triangle(*v[0], is, *v[2], t.triangle.getColor()), t.data));
}
else {
- back->push_back(Triangle(*v[0], *v[1], is, t.getColor()));
- front->push_back(Triangle(*v[0], is, *v[2], t.getColor()));
+ back->push_back(TriangleRecord(Triangle(*v[0], *v[1], is, t.triangle.getColor()), t.data));
+ front->push_back(TriangleRecord(Triangle(*v[0], is, *v[2], t.triangle.getColor()), t.data));
}
return;
@@ -30,7 +48,7 @@ void BSPTree::Plane::partition(const Triangle &t, std::list<Triangle> *front, st
}
for(int i = 0; i < 3; ++i) {
- const vmml::vec3f *v[3] = {&t.getVertex(i), &t.getVertex((i+1)%3), &t.getVertex((i+2)%3)};
+ const vmml::vec3f *v[3] = {&t.triangle.getVertex(i), &t.triangle.getVertex((i+1)%3), &t.triangle.getVertex((i+2)%3)};
if((isInFront(*v[0]) && isBehind(*v[1]) && isBehind(*v[2]))
|| (isBehind(*v[0]) && isInFront(*v[1]) && isInFront(*v[2]))) {
@@ -38,14 +56,14 @@ void BSPTree::Plane::partition(const Triangle &t, std::list<Triangle> *front, st
vmml::vec3f is2 = intersection(*v[0], *v[2]-*v[0]);
if(isInFront(*v[0])) {
- front->push_back(Triangle(*v[0], is1, is2, t.getColor()));
- back->push_back(Triangle(is1, *v[1], is2, t.getColor()));
- back->push_back(Triangle(*v[1], *v[2], is2, t.getColor()));
+ front->push_back(TriangleRecord(Triangle(*v[0], is1, is2, t.triangle.getColor()), t.data));
+ back->push_back(TriangleRecord(Triangle(is1, *v[1], is2, t.triangle.getColor()), t.data));
+ back->push_back(TriangleRecord(Triangle(*v[1], *v[2], is2, t.triangle.getColor()), t.data));
}
else {
- back->push_back(Triangle(*v[0], is1, is2, t.getColor()));
- front->push_back(Triangle(is1, *v[1], is2, t.getColor()));
- front->push_back(Triangle(*v[1], *v[2], is2, t.getColor()));
+ back->push_back(TriangleRecord(Triangle(*v[0], is1, is2, t.triangle.getColor()), t.data));
+ front->push_back(TriangleRecord(Triangle(is1, *v[1], is2, t.triangle.getColor()), t.data));
+ front->push_back(TriangleRecord(Triangle(*v[1], *v[2], is2, t.triangle.getColor()), t.data));
}
return;
@@ -54,7 +72,7 @@ void BSPTree::Plane::partition(const Triangle &t, std::list<Triangle> *front, st
}
-BSPTree::BSPTree(const std::list<Triangle> &triangles) : frontTree(0), backTree(0) {
+BSPTree::BSPTree(const std::list<TriangleRecord> &triangles) : frontTree(0), backTree(0) {
const Triangle *planeT = findNearestTriangle(triangles, findCenter(triangles));
if(!planeT)
@@ -62,29 +80,26 @@ BSPTree::BSPTree(const std::list<Triangle> &triangles) : frontTree(0), backTree(
plane = Plane(*planeT);
- std::list<Triangle> front, back;
+ std::list<TriangleRecord> front, back;
- for(std::list<Triangle>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
- if(t->getNormal().squared_length() == 0)
+ for(std::list<TriangleRecord>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
+ if(t->triangle.isDegenerate())
continue;
- if(plane.contains(*t)) {
+ if(plane.contains(t->triangle)) {
this->triangles.push_back(*t);
continue;
}
- else if(plane.isInFront(*t)) {
+ else if(plane.isInFront(t->triangle)) {
front.push_back(*t);
continue;
}
- else if(plane.isBehind(*t)) {
+ else if(plane.isBehind(t->triangle)) {
back.push_back(*t);
continue;
}
- std::list<Triangle> frontPart, backPart;
- plane.partition(*t, &frontPart, &backPart);
- front.splice(front.end(), frontPart);
- back.splice(back.end(), backPart);
+ plane.partition(*t, &front, &back);
}
if(!front.empty())
@@ -117,28 +132,28 @@ BSPTree& BSPTree::operator=(const BSPTree &tree) {
return *this;
}
-vmml::vec3f BSPTree::findCenter(const std::list<Triangle> &triangles) {
+vmml::vec3f BSPTree::findCenter(const std::list<TriangleRecord> &triangles) {
vmml::vec3f v;
- for(std::list<Triangle>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
- v += t->getCenter();
+ for(std::list<TriangleRecord>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
+ v += t->triangle.getCenter();
}
return v/triangles.size();
}
-const Triangle* BSPTree::findNearestTriangle(const std::list<Triangle> &triangles, const vmml::vec3f &v) {
+const Triangle* BSPTree::findNearestTriangle(const std::list<TriangleRecord> &triangles, const vmml::vec3f &v) {
const Triangle *current = 0;
float distanceSq;
- for(std::list<Triangle>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
- if(t->getNormal().squared_length() == 0)
+ for(std::list<TriangleRecord>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
+ if(t->triangle.isDegenerate())
continue;
- float d = t->getCenter().squared_distance(v);
+ float d = t->triangle.getCenter().squared_distance(v);
if(!current || d < distanceSq) {
- current = &*t;
+ current = &t->triangle;
distanceSq = d;
}
}
diff --git a/BSPTree.h b/BSPTree.h
index 47ba411..1944ef1 100644
--- a/BSPTree.h
+++ b/BSPTree.h
@@ -1,20 +1,61 @@
+/*
+ * BSPTree.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
#ifndef ZOOM_BSPTREE_H_
#define ZOOM_BSPTREE_H_
#include "Triangle.h"
#include <list>
#include <cmath>
+
#include <vmmlib/vector.hpp>
+#include <boost/shared_ptr.hpp>
namespace Zoom {
class BSPTree {
+ public:
+ class TriangleData {
+ protected:
+ TriangleData() {}
+
+ public:
+ virtual ~TriangleData() {}
+ };
+
+ struct TriangleRecord {
+ public:
+ TriangleRecord(Triangle triangle0, boost::shared_ptr<TriangleData> data0)
+ : triangle(triangle0), data(data0) {}
+ TriangleRecord(Triangle triangle0) : triangle(triangle0) {}
+ TriangleRecord() {}
+
+ Triangle triangle;
+ boost::shared_ptr<TriangleData> data;
+ };
+
private:
class Plane {
public:
Plane() : d(0) {}
Plane(const vmml::vec3f &n, float d0) : normal(n), d(d0) {}
- Plane(const Triangle &t) : normal(t.getNormal()), d(t.getVertex(0).dot(normal)) {}
+ Plane(const Triangle &t) : normal(t.computeNormal()), d(t.getVertex(0).dot(normal)) {}
bool contains(const vmml::vec3f &v) const {
return (fabsf(normal.dot(v) - d) < 1E-6);
@@ -62,7 +103,7 @@ class BSPTree {
}
vmml::vec3f intersection(const vmml::vec3f &p, const vmml::vec3f &dir) const;
- void partition(const Triangle &t, std::list<Triangle> *front, std::list<Triangle> *back) const;
+ void partition(const TriangleRecord &t, std::list<TriangleRecord> *front, std::list<TriangleRecord> *back) const;
private:
vmml::vec3f normal;
@@ -70,7 +111,7 @@ class BSPTree {
};
public:
- BSPTree(const std::list<Triangle> &triangles);
+ BSPTree(const std::list<TriangleRecord> &triangles);
BSPTree(const BSPTree &tree) : frontTree(0), backTree(0) {
*this = tree;
@@ -87,16 +128,6 @@ class BSPTree {
BSPTree& operator=(const BSPTree &tree);
template<typename T>
- void visit(const T& visitor, const vmml::vec3f &p) {
- doVisit<const T>(visitor, p);
- }
-
- template<typename T>
- void visit(T& visitor, const vmml::vec3f &p) {
- doVisit(visitor, p);
- }
-
- template<typename T>
void visit(const T& visitor, const vmml::vec3f &p) const {
doVisit<const T>(visitor, p);
}
@@ -108,42 +139,16 @@ class BSPTree {
private:
Plane plane;
- std::list<Triangle> triangles;
+ std::list<TriangleRecord> triangles;
BSPTree *frontTree, *backTree;
template<typename T>
- void doVisit(T& visitor, const vmml::vec3f &p) {
- if(plane.isBehind(p)) {
- if(frontTree)
- frontTree->visit(visitor, p);
-
- for(std::list<Triangle>::iterator t = triangles.begin(); t != triangles.end(); ++t) {
- visitor(*t);
- }
-
- if(backTree)
- backTree->visit(visitor, p);
- }
- else {
- if(backTree)
- backTree->visit(visitor, p);
-
- for(std::list<Triangle>::iterator t = triangles.begin(); t != triangles.end(); ++t) {
- visitor(*t);
- }
-
- if(frontTree)
- frontTree->visit(visitor, p);
- }
- }
-
- template<typename T>
void doVisit(T& visitor, const vmml::vec3f &p) const {
if(plane.isBehind(p)) {
if(frontTree)
frontTree->visit(visitor, p);
- for(std::list<Triangle>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
+ for(std::list<TriangleRecord>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
visitor(*t);
}
@@ -154,7 +159,7 @@ class BSPTree {
if(backTree)
backTree->visit(visitor, p);
- for(std::list<Triangle>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
+ for(std::list<TriangleRecord>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
visitor(*t);
}
@@ -163,8 +168,8 @@ class BSPTree {
}
}
- static vmml::vec3f findCenter(const std::list<Triangle> &triangles);
- static const Triangle* findNearestTriangle(const std::list<Triangle> &triangles, const vmml::vec3f &v);
+ static vmml::vec3f findCenter(const std::list<TriangleRecord> &triangles);
+ static const Triangle* findNearestTriangle(const std::list<TriangleRecord> &triangles, const vmml::vec3f &v);
};
}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index da27b7b..6135c41 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,18 +1,25 @@
cmake_minimum_required(VERSION 2.6)
project(ZOOM)
+set(CMAKE_MODULE_PATH ${ZOOM_SOURCE_DIR})
+
+find_package(Boost REQUIRED)
find_package(OpenGL REQUIRED)
+find_package(GLPng REQUIRED)
+find_package(LibXml2 REQUIRED)
-include_directories(${OPENGL_INCLUDE_DIR})
+include_directories(${Boost_INCLUDE_DIR} ${OPENGL_INCLUDE_DIR} ${GLPNG_INCLUDE_DIR} ${LIBXML2_INCLUDE_DIR})
add_executable(zoom
BSPTree.cpp BSPTree.h
Game.cpp Game.h
config.h
gl.h
+ Level.cpp Level.h
Renderer.cpp Renderer.h
+ Texture.cpp Texture.h
Triangle.h
zoom.cpp
)
-target_link_libraries(zoom ${OPENGL_LIBRARIES})
+target_link_libraries(zoom ${Boost_LIBRARIES} ${OPENGL_LIBRARIES} ${GLPNG_LIBRARY} ${LIBXML2_LIBRARIES})
diff --git a/FindGLPng.cmake b/FindGLPng.cmake
new file mode 100644
index 0000000..f02b772
--- /dev/null
+++ b/FindGLPng.cmake
@@ -0,0 +1,16 @@
+FIND_PATH(GLPNG_INCLUDE_DIR GL/glpng.h)
+FIND_LIBRARY(GLPNG_LIBRARY NAMES glpng)
+
+IF (GLPNG_INCLUDE_DIR AND GLPNG_LIBRARY)
+ SET(GLPNG_FOUND TRUE)
+ENDIF (GLPNG_INCLUDE_DIR AND GLPNG_LIBRARY)
+
+IF (GLPNG_FOUND)
+ IF (NOT GLPng_FIND_QUIETLY)
+ MESSAGE(STATUS "Found glpng: ${GLPNG_LIBRARY}")
+ ENDIF (NOT GLPng_FIND_QUIETLY)
+ELSE (GLPNG_FOUND)
+ IF (GLPng_FIND_REQUIRED)
+ MESSAGE(FATAL_ERROR "Could not find glpng")
+ ENDIF (GLPng_FIND_REQUIRED)
+ENDIF (GLPNG_FOUND)
diff --git a/Game.cpp b/Game.cpp
index bd028c2..46f942f 100644
--- a/Game.cpp
+++ b/Game.cpp
@@ -19,6 +19,7 @@
#include "Game.h"
#include "BSPTree.h"
+#include "Level.h"
#include "Triangle.h"
#include "gl.h"
@@ -26,8 +27,9 @@ namespace Zoom {
Game::Game(bool multisample) : angle(0) {
glClearColor(0.0, 0.0, 0.0, 1.0);
- //glEnable(GL_DEPTH_TEST);
- //glDepthFunc(GL_LEQUAL);
+ glClearDepth(1.0);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LEQUAL);
//glEnable(GL_BLEND);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -37,43 +39,52 @@ Game::Game(bool multisample) : angle(0) {
glEnable(GL_MULTISAMPLE_ARB);
#endif
- /*glEnable(GL_LIGHTING);
- static const float light[] = {1, 1, 1, 0};
+ glShadeModel(GL_SMOOTH);
+
+ glEnable(GL_LIGHTING);
+ static const float light[] = {0, 0, 0, 1};
static const float lightColor[] = {1, 1, 1, 1};
glLightfv(GL_LIGHT0, GL_POSITION, light);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
- glEnable(GL_LIGHT0);*/
+ glEnable(GL_LIGHT0);
+
+ glEnable(GL_COLOR_MATERIAL);
+ glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
- //glEnable(GL_CULL_FACE);
- //glFrontFace(GL_CCW);
+ glEnable(GL_CULL_FACE);
+ glFrontFace(GL_CCW);
glLoadIdentity();
- glTranslatef(0, 0, -5);
+
+ loadLevel("level.xml");
+}
+
+bool Game::loadLevel(const std::string &name) {
+ level = Level::loadLevel(name);
+
+ return level;
}
void Game::run(int delta) {
- angle += delta*0.2;
+ angle += delta*0.01;
if(angle >= 360)
angle -= 360;
}
void Game::render() {
- std::list<Triangle> triangles;
-
- triangles.push_back(Triangle(vmml::vec3f(-1, -1, 0), vmml::vec3f(1, -1, 0), vmml::vec3f(1, 1, 0), vmml::vec3f(0, 1, 0)));
- triangles.push_back(Triangle(vmml::vec3f(-1, -1, 0), vmml::vec3f(-1, 1, 0), vmml::vec3f(1, 1, 0), vmml::vec3f(0, 1, 0)));
- triangles.push_back(Triangle(vmml::vec3f(-1, -1, -1), vmml::vec3f(1, -1, -1), vmml::vec3f(1, 1, -1), vmml::vec3f(0, 0, 1)));
- triangles.push_back(Triangle(vmml::vec3f(-1, -1, -1), vmml::vec3f(-1, 1, -1), vmml::vec3f(1, 1, -1), vmml::vec3f(0, 0, 1)));
+ std::list<BSPTree::TriangleRecord> triangles;
- BSPTree tree(triangles);
+ triangles.insert(triangles.end(), level->getRooms().front().walls.begin(), level->getRooms().front().walls.end());
- glClear(GL_COLOR_BUFFER_BIT);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle, 1, 2, 1);
+ //glRotatef(3*angle, 0, -1, 2);
+ //glRotatef(5*angle, 2, -1, 0);
- renderer.render(tree);
+ renderer.render(triangles);
glPopMatrix();
}
diff --git a/Game.h b/Game.h
index dbd129a..7960497 100644
--- a/Game.h
+++ b/Game.h
@@ -21,20 +21,26 @@
#define ZOOM_GAME_H_
#include "Renderer.h"
+#include <boost/shared_ptr.hpp>
+#include <string>
namespace Zoom {
+class Level;
class Triangle;
class Game {
public:
Game(bool multisample);
+ bool loadLevel(const std::string &name);
+
void run(int delta);
void render();
private:
Renderer renderer;
+ boost::shared_ptr<Level> level;
float angle;
};
diff --git a/Level.cpp b/Level.cpp
new file mode 100644
index 0000000..2867ab9
--- /dev/null
+++ b/Level.cpp
@@ -0,0 +1,260 @@
+/*
+ * Level.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Level.h"
+#include "Texture.h"
+#include <libxml/tree.h>
+#include <libxml/valid.h>
+
+#include <iostream>
+
+namespace Zoom {
+
+boost::shared_ptr<Level> Level::loadLevel(const std::string &filename) {
+ boost::shared_ptr<Level> level;
+
+ xmlDocPtr doc = xmlParseFile(("levels/"+filename).c_str());
+
+ if(doc) {
+ if(validateLevel(doc)) {
+ xmlNodePtr root = xmlDocGetRootElement(doc);
+ if(root && !xmlStrcmp(root->name, (xmlChar*)"level")) {
+ level = boost::shared_ptr<Level>(new Level);
+
+ for(xmlNodePtr node = root->children; node != 0; node = node->next) {
+ if(node->type != XML_ELEMENT_NODE)
+ continue;
+
+ if(!xmlStrcmp(node->name, (xmlChar*)"info")) {
+ level->loadLevelInfo(node);
+ }
+ else if(!xmlStrcmp(node->name, (xmlChar*)"rooms")) {
+ level->loadRooms(node);
+ }
+ else if(!xmlStrcmp(node->name, (xmlChar*)"textures")) {
+ level->loadTextures(node);
+ }
+ }
+
+ for(std::list<Room>::iterator room = level->rooms.begin(); room != level->rooms.end(); ++room) {
+ for(std::list<BSPTree::TriangleRecord>::iterator wall = room->walls.begin(); wall != room->walls.end(); ++wall) {
+ boost::shared_ptr<WallData> wallData = boost::dynamic_pointer_cast<WallData>(wall->data);
+
+ if(!wallData->texture.empty()) {
+ std::map<std::string, unsigned>::iterator texture = level->textures.find(wallData->texture);
+
+ if(texture != level->textures.end())
+ wall->triangle.setTexture(texture->second);
+ }
+ }
+ }
+ }
+ }
+
+ xmlFreeDoc(doc);
+ }
+
+ xmlCleanupParser();
+
+ return level;
+}
+
+void Level::loadLevelInfo(xmlNodePtr infoNode) {
+ for(xmlNodePtr node = infoNode->children; node != 0; node = node->next) {
+ if(node->type != XML_ELEMENT_NODE)
+ continue;
+
+ if(!xmlStrcmp(node->name, (xmlChar*)"name")) {
+ xmlChar *data = xmlNodeGetContent(node);
+ name = (char*)data;
+ xmlFree(data);
+ }
+ else if(!xmlStrcmp(node->name, (xmlChar*)"desc")) {
+ xmlChar *data = xmlNodeGetContent(node);
+ description = (char*)data;
+ xmlFree(data);
+ }
+ else if(!xmlStrcmp(node->name, (xmlChar*)"start")) {
+ startPoint = loadVector(node);
+ }
+ }
+}
+
+void Level::loadRooms(xmlNodePtr roomsNode) {
+ for(xmlNodePtr node = roomsNode->children; node != 0; node = node->next) {
+ if(node->type == XML_ELEMENT_NODE && !xmlStrcmp(node->name, (xmlChar*)"room")) {
+ loadRoom(node);
+ }
+ }
+}
+
+void Level::loadRoom(xmlNodePtr roomNode) {
+ rooms.push_back(Room());
+
+ xmlChar *data = xmlGetProp(roomNode, (xmlChar*)"id");
+ if(data) {
+ rooms.back().id = (char*)data;
+
+ xmlFree(data);
+ }
+
+ for(xmlNodePtr node = roomNode->children; node != 0; node = node->next) {
+ if(node->type == XML_ELEMENT_NODE && !xmlStrcmp(node->name, (xmlChar*)"triangle")) {
+ rooms.back().walls.push_back(loadWall(node));
+ }
+ }
+}
+
+void Level::loadTextures(xmlNodePtr texturesNode) {
+ for(xmlNodePtr node = texturesNode->children; node != 0; node = node->next) {
+ if(node->type == XML_ELEMENT_NODE && !xmlStrcmp(node->name, (xmlChar*)"texture")) {
+ std::string id, name;
+
+ xmlChar *data = xmlGetProp(node, (xmlChar*)"id");
+ if(data) {
+ id = (char*)data;
+ xmlFree(data);
+ }
+
+ data = xmlGetProp(node, (xmlChar*)"name");
+ if(data) {
+ name = (char*)data;
+ xmlFree(data);
+ }
+
+ if(!id.empty() && !name.empty()) {
+ unsigned texture = Texture::loadTexture(name);
+
+ if(texture) {
+ textures.insert(std::make_pair(id, texture));
+ }
+ }
+ }
+ }
+}
+
+BSPTree::TriangleRecord Level::loadWall(xmlNodePtr wallNode) {
+ boost::shared_ptr<WallData> wallData(new WallData);
+
+ BSPTree::TriangleRecord wall;
+ wall.data = wallData;
+
+
+ xmlChar *data = xmlGetProp(wallNode, (xmlChar*)"texture");
+ if(data) {
+ wallData->texture = (char*)data;
+ xmlFree(data);
+ }
+
+ int vertexNum = -1;
+
+ for(xmlNodePtr node = wallNode->children; node != 0; node = node->next) {
+ if(node->type != XML_ELEMENT_NODE)
+ continue;
+
+ if(!xmlStrcmp(node->name, (xmlChar*)"vertex")) {
+ if(++vertexNum > 2)
+ break;
+
+ wall.triangle.setVertex(vertexNum, loadVector(node));
+ }
+ else if(!xmlStrcmp(node->name, (xmlChar*)"normal")) {
+ if(vertexNum < 0)
+ continue;
+
+ wall.triangle.setNormal(vertexNum, loadVector(node));
+ }
+ else if(!xmlStrcmp(node->name, (xmlChar*)"texcoords")) {
+ if(vertexNum < 0) continue;
+
+ data = xmlGetProp(node, (xmlChar*)"s");
+ if(data) {
+ wall.triangle.getTexCoords(vertexNum)[0] = atof((char*)data);
+ xmlFree(data);
+ }
+
+ data = xmlGetProp(node, (xmlChar*)"t");
+ if(data) {
+ wall.triangle.getTexCoords(vertexNum)[1] = atof((char*)data);
+ xmlFree(data);
+ }
+ }
+ }
+
+ vmml::vec3f normal = wall.triangle.computeNormal();
+
+ if(normal.squared_length() > 0) {
+ normal.normalize();
+
+ for(int i = 0; i < 3; ++i) {
+ if(wall.triangle.getNormal(i).squared_length() == 0)
+ wall.triangle.setNormal(i, normal);
+ }
+ }
+
+
+ return wall;
+}
+
+vmml::vec3f Level::loadVector(xmlNodePtr node) {
+ vmml::vec3f ret(vmml::vec3f::ZERO);
+
+ xmlChar *data = xmlGetProp(node, (xmlChar*)"x");
+ if(data) {
+ ret.x() = atof((char*)data);
+ xmlFree(data);
+ }
+
+ data = xmlGetProp(node, (xmlChar*)"y");
+ if(data) {
+ ret.y() = atof((char*)data);
+ xmlFree(data);
+ }
+
+ data = xmlGetProp(node, (xmlChar*)"z");
+ if(data) {
+ ret.z() = atof((char*)data);
+ xmlFree(data);
+ }
+
+ return ret;
+}
+
+bool Level::validateLevel(xmlDocPtr doc) {
+ bool ret = false;
+
+ xmlDtdPtr dtd = xmlParseDTD((xmlChar*)"-//libzoom//DTD level 0.1//EN", (xmlChar*)"levels/level.dtd");
+
+ if(dtd) {
+ xmlValidCtxtPtr validCtxt = xmlNewValidCtxt();
+
+ if(validCtxt) {
+ if(xmlValidateDtd(validCtxt, doc, dtd))
+ ret = true;
+
+ xmlFreeValidCtxt(validCtxt);
+ }
+
+ xmlFreeDtd(dtd);
+ }
+
+ return ret;
+}
+
+}
diff --git a/Level.h b/Level.h
new file mode 100644
index 0000000..277b6e7
--- /dev/null
+++ b/Level.h
@@ -0,0 +1,74 @@
+/*
+ * Level.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ZOOM_LEVEL_H_
+#define ZOOM_LEVEL_H_
+
+#include "BSPTree.h"
+
+#include <string>
+#include <map>
+#include <list>
+
+#include <boost/shared_ptr.hpp>
+#include <libxml/parser.h>
+#include <vmmlib/vector.hpp>
+
+namespace Zoom {
+
+class Level {
+ public:
+ static boost::shared_ptr<Level> loadLevel(const std::string &filename);
+
+ struct WallData : public BSPTree::TriangleData {
+ std::string texture;
+ };
+
+ struct Room {
+ std::string id;
+ std::list<BSPTree::TriangleRecord> walls;
+ };
+
+ const std::list<Room> &getRooms() const {
+ return rooms;
+ }
+
+ private:
+ std::list<Room> rooms;
+ std::map<std::string, unsigned> textures;
+
+ std::string name, description;
+ vmml::vec3f startPoint;
+
+ Level() {}
+
+ void loadLevelInfo(xmlNodePtr infoNode);
+ void loadRooms(xmlNodePtr roomsNode);
+ void loadRoom(xmlNodePtr roomNode);
+ void loadTextures(xmlNodePtr texturesNode);
+
+ static BSPTree::TriangleRecord loadWall(xmlNodePtr wallNode);
+ static vmml::vec3f loadVector(xmlNodePtr node);
+
+ static bool validateLevel(xmlDocPtr doc);
+};
+
+}
+
+#endif /* ZOOM_LEVEL_H_ */
diff --git a/Renderer.cpp b/Renderer.cpp
index bf9aadb..558e415 100644
--- a/Renderer.cpp
+++ b/Renderer.cpp
@@ -19,11 +19,10 @@
#include "Renderer.h"
#include "BSPTree.h"
+#include "gl.h"
namespace Zoom {
-const Renderer::RenderVisitor Renderer::renderVisitor = Renderer::RenderVisitor();
-
void Renderer::render(const BSPTree &tree) {
vmml::mat4f transform, inverseTransform;
glGetFloatv(GL_MODELVIEW_MATRIX, transform.array);
@@ -38,14 +37,39 @@ void Renderer::render(const BSPTree &tree) {
}
+void Renderer::render(const std::list<BSPTree::TriangleRecord> &triangles) {
+ glBegin(GL_TRIANGLES);
+ for(std::list<BSPTree::TriangleRecord>::const_iterator t = triangles.begin(); t != triangles.end(); ++t) {
+ renderTriangle(t->triangle);
+ }
+ glEnd();
+}
+
void Renderer::renderTriangle(const Triangle &t) {
glColor4fv(t.getColor().array);
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, t.getColor().array);
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (t.getColor()/2).array);
- glNormal3fv(t.getNormal().array);
+ if(t.getTexture() != lastTexture) {
+ glEnd();
+
+ if(t.getTexture()) {
+ glBindTexture(GL_TEXTURE_2D, t.getTexture());
+
+ if(!lastTexture) {
+ glEnable(GL_TEXTURE_2D);
+ }
+ }
+ else {
+ glDisable(GL_TEXTURE_2D);
+ }
+
+ lastTexture = t.getTexture();
+
+ glBegin(GL_TRIANGLES);
+ }
for(int i = 0; i < 3; ++i) {
+ glTexCoord2fv(t.getTexCoords(i).array);
+ glNormal3fv(t.getNormal(i).array);
glVertex3fv(t.getVertex(i).array);
}
}
diff --git a/Renderer.h b/Renderer.h
index d64a4fe..d72b5bb 100644
--- a/Renderer.h
+++ b/Renderer.h
@@ -20,25 +20,35 @@
#ifndef ZOOM_RENDERER_H_
#define ZOOM_RENDERER_H_
-namespace Zoom {
+#include "BSPTree.h"
-class Triangle;
-class BSPTree;
+namespace Zoom {
class Renderer {
public:
+ Renderer() : lastTexture(0), renderVisitor(this) {}
+
void render(const BSPTree &tree);
+ void render(const std::list<BSPTree::TriangleRecord> &triangles);
private:
- static void renderTriangle(const Triangle &t);
+ void renderTriangle(const Triangle &t);
- struct RenderVisitor {
- void operator() (const Triangle &t) const {
- renderTriangle(t);
+ class RenderVisitor {
+ public:
+ RenderVisitor(Renderer *renderer0) : renderer(renderer0) {}
+
+ void operator() (const BSPTree::TriangleRecord &t) const {
+ renderer->renderTriangle(t.triangle);
}
+
+ private:
+ Renderer *renderer;
};
- static const RenderVisitor renderVisitor;
+ unsigned lastTexture;
+
+ const RenderVisitor renderVisitor;
};
}
diff --git a/Texture.cpp b/Texture.cpp
new file mode 100644
index 0000000..d5ec1f2
--- /dev/null
+++ b/Texture.cpp
@@ -0,0 +1,44 @@
+/*
+ * Texture.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Texture.h"
+#include "gl.h"
+#include <GL/glpng.h>
+
+namespace Zoom {
+
+std::map<std::string, unsigned> Texture::textures;
+
+unsigned Texture::loadTexture(const std::string &name) {
+ std::map<std::string, unsigned>::iterator it = textures.find(name);
+
+ if(it != textures.end())
+ return it->second;
+
+ pngInfo info;
+ unsigned texture = pngBind(("tex/" + name).c_str(), PNG_NOMIPMAP, PNG_ALPHA, &info, GL_REPEAT, GL_LINEAR, GL_LINEAR);
+
+ if(texture) {
+ textures.insert(std::make_pair(name, texture));
+ }
+
+ return texture;
+}
+
+}
diff --git a/Texture.h b/Texture.h
new file mode 100644
index 0000000..fd078f3
--- /dev/null
+++ b/Texture.h
@@ -0,0 +1,40 @@
+/*
+ * Texture.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ZOOM_TEXTURE_H_
+#define ZOOM_TEXTURE_H_
+
+#include <string>
+#include <map>
+
+namespace Zoom {
+
+class Texture {
+ public:
+ static unsigned loadTexture(const std::string &name);
+
+ private:
+ Texture();
+
+ static std::map<std::string, unsigned> textures;
+};
+
+}
+
+#endif /* ZOOM_TEXTURE_H_ */
diff --git a/Triangle.h b/Triangle.h
index 16b0d73..2b34c3f 100644
--- a/Triangle.h
+++ b/Triangle.h
@@ -1,7 +1,25 @@
+/*
+ * Triangle.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
#ifndef ZOOM_TRIANGLE_H_
#define ZOOM_TRIANGLE_H_
-#include "gl.h"
#include <vmmlib/vector.hpp>
#include <vmmlib/matrix.hpp>
@@ -9,36 +27,76 @@ namespace Zoom {
class Triangle {
public:
- Triangle() : c(vmml::vec4f::ONE) {
- v[0] = v[1] = v[2] = vmml::vec3f::ZERO;
+ Triangle() : color(vmml::vec4f::ONE), texture(0) {
+ vertices[0] = vertices[1] = vertices[2] = vmml::vec3f::ZERO;
+ normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO;
+ texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO;
}
- Triangle(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &v3, const vmml::vec4f &c0) : c(c0) {
- v[0] = v1;
- v[1] = v2;
- v[2] = v3;
+ Triangle(const vmml::vec3f &v1, const vmml::vec3f &v2, const vmml::vec3f &v3, const vmml::vec4f &color0) : color(color0), texture(0) {
+ vertices[0] = v1;
+ vertices[1] = v2;
+ vertices[2] = v3;
+
+ normals[0] = normals[1] = normals[2] = vmml::vec3f::ZERO;
+ texcoords[0] = texcoords[1] = texcoords[2] = vmml::vec2f::ZERO;
}
- const vmml::vec3f& getVertex(int i) const {return v[i];}
- const vmml::vec4f& getColor() const {return c;}
+ const vmml::vec3f& getVertex(int i) const {return vertices[i];}
+ vmml::vec3f& getVertex(int i) {return vertices[i];}
+ void setVertex(int i, vmml::vec3f v) {
+ vertices[i] = v;
+ }
+
+ const vmml::vec3f& getNormal(int i) const {return normals[i];}
+ vmml::vec3f& getNormal(int i) {return normals[i];}
+ void setNormal(int i, vmml::vec3f n) {
+ normals[i] = n;
+ }
+
+ const vmml::vec2f& getTexCoords(int i) const {return texcoords[i];}
+ vmml::vec2f& getTexCoords(int i) {return texcoords[i];}
+ void setTexCoords(int i, vmml::vec2f t) {
+ texcoords[i] = t;
+ }
+
+ unsigned getTexture() const {
+ return texture;
+ }
+ void setTexture(unsigned tex) {
+ texture = tex;
+ }
+
+ const vmml::vec4f& getColor() const {return color;}
+ vmml::vec4f& getColor() {return color;}
+ void setColor(vmml::vec4f c) {
+ color = c;
+ }
- vmml::vec3f getNormal() const {
- return v[0].compute_normal(v[1], v[2]);
+ vmml::vec3f computeNormal() const {
+ return vertices[0].compute_normal(vertices[1], vertices[2]);
}
- void transform(const vmml::mat4f &m) {
+ bool isDegenerate() const {
+ return (computeNormal().squared_length() == 0);
+ }
+
+ void transform(const vmml::mat4f &matrix) {
for(int i = 0; i < 3; ++i) {
- v[i] = m*v[i];
+ vertices[i] = matrix*vertices[i];
}
}
vmml::vec3f getCenter() const {
- return (v[0]+v[1]+v[2])/3;
+ return (vertices[0]+vertices[1]+vertices[2])/3;
}
private:
- vmml::vec3f v[3];
- vmml::vec4f c;
+ vmml::vec3f vertices[3];
+ vmml::vec3f normals[3];
+ vmml::vec2f texcoords[3];
+ vmml::vec4f color;
+ unsigned texture;
};
}
diff --git a/config.h b/config.h
index 1c2e879..9af944d 100644
--- a/config.h
+++ b/config.h
@@ -20,7 +20,7 @@
#ifndef ZOOM_CONFIG_H_
#define ZOOM_CONFIG_H_
-#define MIN_FRAME_DELTA 16
+#define MIN_FRAME_DELTA 10
#define DEFAULT_WIDTH 800
#define DEFAULT_HEIGHT 600
diff --git a/gl.h b/gl.h
index fb5face..22e0523 100644
--- a/gl.h
+++ b/gl.h
@@ -1,5 +1,24 @@
-#ifndef _GL_H_
-#define _GL_H_
+/*
+ * gl.h
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef ZOOM_GL_H_
+#define ZOOM_GL_H_
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
@@ -9,4 +28,4 @@
#include <GL/gl.h>
#include <GL/glu.h>
-#endif /* _GL_H_ */
+#endif /* ZOOM_GL_H_ */
diff --git a/levels/level.dtd b/levels/level.dtd
new file mode 100644
index 0000000..8ef0604
--- /dev/null
+++ b/levels/level.dtd
@@ -0,0 +1,61 @@
+<!ELEMENT level (info, rooms, gates, textures)>
+
+<!ELEMENT info (name, desc, start)>
+<!ELEMENT rooms (room)*>
+<!ELEMENT gates (gate)*>
+<!ELEMENT textures (texture)*>
+
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT desc (#PCDATA)>
+<!ELEMENT start EMPTY>
+<!ATTLIST start
+ x CDATA #REQUIRED
+ y CDATA #REQUIRED
+ z CDATA #REQUIRED
+>
+
+<!ELEMENT room (triangle)*>
+<!ATTLIST room
+ id ID #REQUIRED
+>
+
+<!ELEMENT gate (triangle)*>
+<!ATTLIST gate
+ room1 IDREF #REQUIRED
+ room2 IDREF #REQUIRED
+>
+
+<!ELEMENT triangle (vertex, normal?, texcoords?, vertex, normal?, texcoords?, vertex, normal?, texcoords?)>
+<!ATTLIST triangle
+ visible (true|false) "true"
+ texture IDREF #IMPLIED
+>
+
+<!ELEMENT texture EMPTY>
+<!ATTLIST texture
+ id ID #REQUIRED
+ name CDATA #REQUIRED
+>
+
+<!ELEMENT vertex EMPTY>
+<!ATTLIST vertex
+ x CDATA #REQUIRED
+ y CDATA #REQUIRED
+ z CDATA #REQUIRED
+>
+
+<!ELEMENT normal EMPTY>
+<!ATTLIST normal
+ x CDATA #REQUIRED
+ y CDATA #REQUIRED
+ z CDATA #REQUIRED
+>
+
+<!ELEMENT texcoords EMPTY>
+<!ATTLIST texcoords
+ s CDATA #REQUIRED
+ t CDATA #IMPLIED
+ r CDATA #IMPLIED
+ q CDATA #IMPLIED
+>
+
diff --git a/levels/level.xml b/levels/level.xml
new file mode 100644
index 0000000..0cbc92f
--- /dev/null
+++ b/levels/level.xml
@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE level PUBLIC "-//libzoom//DTD level 0.1//EN" "level.dtd">
+<level>
+ <info>
+ <name>Test Level</name>
+ <desc>Just a simple test level.</desc>
+ <start x="0.0" y="0.0" z="0.0"/>
+ </info>
+ <rooms>
+ <room id="r0">
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="-2.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="-2.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="-2.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="2.0" z="-6.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="6.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="-2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="6.0" y="-2.0" z="-10.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="-2.0" z="-10.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="-2.0" z="-10.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-10.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-10.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-10.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="2.0" z="-6.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-10.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="6.0" y="-2.0" z="-10.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-10.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-10.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-10.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="-10.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-10.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-10.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-10.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="6.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-6.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="6.0" y="2.0" z="-10.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="6.0" y="-2.0" z="-6.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-10.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="-2.0" z="-10.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="6.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="6.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="6.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-6.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="-2.0" z="-6.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ </room>
+ <room id="r1">
+ <triangle texture="t2">
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t2">
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="2.0" y="-2.0" z="2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="-2.0" y="-2.0" z="2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="-2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="-2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ <triangle texture="t1">
+ <vertex x="-2.0" y="2.0" z="2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ </room>
+ </rooms>
+ <gates>
+ <gate room1="r0" room2="r1">
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="2.0" y="2.0" z="-2.0"/>
+ <texcoords s="1.0" t="0.0"/>
+ <vertex x="6.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ </triangle>
+ <triangle texture="t0">
+ <vertex x="2.0" y="-2.0" z="-2.0"/>
+ <texcoords s="1.0" t="1.0"/>
+ <vertex x="6.0" y="2.0" z="-2.0"/>
+ <texcoords s="0.0" t="0.0"/>
+ <vertex x="6.0" y="-2.0" z="-2.0"/>
+ <texcoords s="0.0" t="1.0"/>
+ </triangle>
+ </gate>
+ </gates>
+ <textures>
+ <texture id="t0" name="green.png"/>
+ <texture id="t1" name="metallic2.png"/>
+ <texture id="t2" name="light.png"/>
+ </textures>
+</level>
diff --git a/tex/blue.png b/tex/blue.png
new file mode 100644
index 0000000..b730875
--- /dev/null
+++ b/tex/blue.png
Binary files differ
diff --git a/tex/cursor.png b/tex/cursor.png
new file mode 100644
index 0000000..4ee35ca
--- /dev/null
+++ b/tex/cursor.png
Binary files differ
diff --git a/tex/dark.png b/tex/dark.png
new file mode 100644
index 0000000..f87c09f
--- /dev/null
+++ b/tex/dark.png
Binary files differ
diff --git a/tex/door.png b/tex/door.png
new file mode 100644
index 0000000..0706ccd
--- /dev/null
+++ b/tex/door.png
Binary files differ
diff --git a/tex/fire.png b/tex/fire.png
new file mode 100644
index 0000000..4371c34
--- /dev/null
+++ b/tex/fire.png
Binary files differ
diff --git a/tex/green.png b/tex/green.png
new file mode 100644
index 0000000..cfc6238
--- /dev/null
+++ b/tex/green.png
Binary files differ
diff --git a/tex/green2.png b/tex/green2.png
new file mode 100644
index 0000000..87c071b
--- /dev/null
+++ b/tex/green2.png
Binary files differ
diff --git a/tex/light.png b/tex/light.png
new file mode 100644
index 0000000..3610a26
--- /dev/null
+++ b/tex/light.png
Binary files differ
diff --git a/tex/lightmap.png b/tex/lightmap.png
new file mode 100644
index 0000000..76c3b19
--- /dev/null
+++ b/tex/lightmap.png
Binary files differ
diff --git a/tex/lightmap2.png b/tex/lightmap2.png
new file mode 100644
index 0000000..97a151f
--- /dev/null
+++ b/tex/lightmap2.png
Binary files differ
diff --git a/tex/medib.png b/tex/medib.png
new file mode 100644
index 0000000..00093b4
--- /dev/null
+++ b/tex/medib.png
Binary files differ
diff --git a/tex/metallic.png b/tex/metallic.png
new file mode 100644
index 0000000..d1177b1
--- /dev/null
+++ b/tex/metallic.png
Binary files differ
diff --git a/tex/metallic2.png b/tex/metallic2.png
new file mode 100644
index 0000000..4f8977c
--- /dev/null
+++ b/tex/metallic2.png
Binary files differ
diff --git a/tex/textur.png b/tex/textur.png
new file mode 100644
index 0000000..96114d3
--- /dev/null
+++ b/tex/textur.png
Binary files differ
diff --git a/tex/wall1.png b/tex/wall1.png
new file mode 100644
index 0000000..e620a9b
--- /dev/null
+++ b/tex/wall1.png
Binary files differ
diff --git a/tex/wall2.png b/tex/wall2.png
new file mode 100644
index 0000000..2fb39bd
--- /dev/null
+++ b/tex/wall2.png
Binary files differ
diff --git a/tex/wall3.png b/tex/wall3.png
new file mode 100644
index 0000000..b30ee2a
--- /dev/null
+++ b/tex/wall3.png
Binary files differ
diff --git a/tex/wall4.png b/tex/wall4.png
new file mode 100644
index 0000000..1bec600
--- /dev/null
+++ b/tex/wall4.png
Binary files differ
diff --git a/tex/wall5.png b/tex/wall5.png
new file mode 100644
index 0000000..a6c6a73
--- /dev/null
+++ b/tex/wall5.png
Binary files differ
diff --git a/zoom.cpp b/zoom.cpp
index 9535b8a..8f01c1b 100644
--- a/zoom.cpp
+++ b/zoom.cpp
@@ -1,3 +1,22 @@
+/*
+ * zoom.cpp
+ *
+ * Copyright (C) 2009 Matthias Schiffer <matthias@gamezock.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
#include "Game.h"
#include "config.h"
#include "gl.h"
@@ -13,9 +32,8 @@
void resize(int width, int height)
{
- if(height==0)
- {
- height=1;
+ if(height == 0) {
+ height = 1;
}