www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

commit 0d467384f3cf7b5543cb3c7e75a478558e41bd0e
parent f5cc3dc243b1d2be7e736f5156edcd73b020f13d
Author: Georges Dupéron <jahvascriptmaniac+github@free.fr>
Date:   Mon, 28 Nov 2011 11:42:44 +0100

Premier affichage 3D.

Diffstat:
MMakefile | 7++++---
Mall_includes.hh | 6++++++
Mmain.cpp | 19++++++++++++++-----
Mrules/batiment.cpp | 10++++++----
Mrules/batiment.hh | 2+-
Mrules/carrefour.cpp | 9+++++----
Mrules/carrefour.hh | 4++--
Mrules/chose.cpp | 24+++++++++++++++---------
Mrules/chose.hh | 5++---
Mrules/rectangleroutes.cpp | 21++++++++++++---------
Mrules/rectangleroutes.hh | 4++--
Mrules/route.cpp | 9+++++----
Mrules/route.hh | 4++--
Mtriangle.cpp | 14+++++++++++++-
Mtriangle.hh | 3+++
Aview.cpp | 131+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aview.hh | 35+++++++++++++++++++++++++++++++++++
17 files changed, 258 insertions(+), 49 deletions(-)

diff --git a/Makefile b/Makefile @@ -4,7 +4,8 @@ CCWARN=-Wall -Wextra -Werror # -flto (nécessite GCC 4.5) -m32 ou -m64 CFLAGS=-O3 -g3 -I. $(CCWARN) -OBJECTS = main.o hash.o segment.o vertex.o triangle.o rules/chose.o rules/rectangleroutes.o rules/route.o rules/carrefour.o rules/batiment.o +OBJECTS = main.o view.o hash.o segment.o vertex.o triangle.o rules/chose.o rules/rectangleroutes.o rules/route.o rules/carrefour.o rules/batiment.o +LIBS = -lm -lGL -lGLU -lSDL -lGLEW EXECUTABLE = city .PHONY: test @@ -18,8 +19,8 @@ all: $(EXECUTABLE) clean: rm -f $(EXECUTABLE) $(OBJECTS) $(OBJECTS:.o=.d) -city: $(OBJECTS) - $(CXX) -lm $^ -o $@ +$(EXECUTABLE): $(OBJECTS) + $(CXX) $(LIBS) $^ -o $@ -include $(OBJECTS:.o=.d) diff --git a/all_includes.hh b/all_includes.hh @@ -8,11 +8,17 @@ class Chose; #include <cmath> #include <vector> +#include <SDL/SDL.h> +#include <GL/glew.h> +#include <GL/glu.h> +#include <GL/gl.h> + #include "vertex.hh" #include "segment.hh" #include "triangle.hh" #include "directions.hh" #include "hash.hh" +#include "view.hh" #include "rules/chose.hh" #include "rules/batiment.hh" diff --git a/main.cpp b/main.cpp @@ -1,18 +1,27 @@ #include "all_includes.hh" -// TODO : bâtiments. -// TODO : split route en 2 triangles. // TODO : split bâtiment en faces, puis en triangles. // TODO : probabilités des différents types de bâtiments. // TODO : midpoint displacement sur les probabilités des différents types de bâtiments. // TODO : largeur des routes : ??? +void recursiveSubdivide(Chose* c) { + if (c->subdivide()) { + std::vector<Chose*>::iterator it; + for (it = c->children.begin(); it != c->children.end(); ++it) { + recursiveSubdivide(*it); + } + } +} + int main() { // Générer une tile de base - Vertex ne(100, 100, 0); + Vertex ne(1000, 1000, 0); Vertex sw(0, 0, 0); - RectangleRoutes r(ne, sw); - r.subdivide(); + RectangleRoutes* r = new RectangleRoutes(ne, sw); + recursiveSubdivide(r); + + new View(r); // tile.subdivide tant qu'on n'a pas le niveau de détail désiré. return 0; } diff --git a/rules/batiment.cpp b/rules/batiment.cpp @@ -1,19 +1,21 @@ #include "all_includes.hh" -Batiment::Batiment(Vertex ne, Vertex sw) : ne(ne), sw(sw) { - std::cout << this << std::endl; +Batiment::Batiment(Vertex ne, Vertex sw) : Chose(), ne(ne), sw(sw) { + addEntropy(ne, sw); + triangulation(); } int Batiment::width() { return this->ne.x - this->sw.x; } int Batiment::height() { return this->ne.y - this->sw.y; } -void Batiment::subdivide() { +bool Batiment::subdivide() { // TODO : rien ? + return false; } void Batiment::triangulation() { - initTriangles(12); + triangles.reserve(12); // abcd sont les quatre coins du bâtiment. Vertex a = this->ne; diff --git a/rules/batiment.hh b/rules/batiment.hh @@ -13,7 +13,7 @@ public: Batiment(Vertex ne, Vertex sw); int width(); int height(); - virtual void subdivide(); + virtual bool subdivide(); virtual void triangulation(); }; diff --git a/rules/carrefour.cpp b/rules/carrefour.cpp @@ -1,15 +1,16 @@ #include "carrefour.hh" -Carrefour::Carrefour(Vertex ne, Vertex se, Vertex sw, Vertex nw) { +Carrefour::Carrefour(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose() { corners[NE]=ne; corners[SE]=se; corners[SW]=sw; corners[NW]=nw; - std::cout << this << std::endl; + triangulation(); } -void Carrefour::subdivide() { +bool Carrefour::subdivide() { // TODO + return false; } std::ostream& operator<<(std::ostream& os, const Carrefour* c) { @@ -21,7 +22,7 @@ std::ostream& operator<<(std::ostream& os, const Carrefour& c) { } void Carrefour::triangulation() { - initTriangles(2); + triangles.reserve(2); addTriangle(new Triangle(corners[SW], corners[NW], corners[NE])); addTriangle(new Triangle(corners[SW], corners[SE], corners[NE])); } diff --git a/rules/carrefour.hh b/rules/carrefour.hh @@ -3,12 +3,12 @@ #include "all_includes.hh" -class Carrefour : Chose { +class Carrefour : public Chose { public: Vertex corners[4]; public: Carrefour(Vertex ne, Vertex se, Vertex sw, Vertex nw); - virtual void subdivide(); + virtual bool subdivide(); virtual void triangulation(); public: friend std::ostream& operator<<(std::ostream& os, const Carrefour& c); diff --git a/rules/chose.cpp b/rules/chose.cpp @@ -1,6 +1,6 @@ #include "all_includes.hh" -Chose::Chose() : seed(initialSeed) {} +Chose::Chose() : seed(initialSeed), children() {} std::ostream& operator<<(std::ostream& os, const Chose* r) { return os << *r; @@ -11,14 +11,6 @@ std::ostream& operator<<(std::ostream& os, const Chose& r) { return os << "Chose"; } -void Chose::initChildren(int n) { - children = std::vector<Chose*>(n); -} - -void Chose::initTriangles(int n) { - triangles = std::vector<Triangle*>(n); -} - void Chose::addChild(Chose* c) { children.push_back(c); // TODO : Ajouter c dans une file d'attente des éléments pouvant être split. @@ -28,3 +20,17 @@ void Chose::addTriangle(Triangle* t) { triangles.push_back(t); // TODO : Ajouter t dans la liste des triangles à envoyer au GPU. } + +void Chose::display() { + if (children.size() > 0) { + std::vector<Chose*>::iterator it; + for (it = children.begin(); it != children.end(); ++it) { + (*it)->display(); + } + } else { + std::vector<Triangle*>::iterator it; + for (it = triangles.begin(); it != triangles.end(); ++it) { + (*it)->display(); + } + } +} diff --git a/rules/chose.hh b/rules/chose.hh @@ -20,12 +20,11 @@ public: inline void addEntropy(Vertex v1, Vertex v2) { addEntropy(v1); addEntropy(v2); } inline void addEntropy(Vertex v1, Vertex v2, Vertex v3) { addEntropy(v1, v2); addEntropy(v3); } inline void addEntropy(Vertex v1, Vertex v2, Vertex v3, Vertex v4) { addEntropy(v1, v2); addEntropy(v3, v4); } - void initChildren(int n); - void initTriangles(int n); void addChild(Chose* c); void addTriangle(Triangle* t); - virtual void subdivide() = 0; + virtual bool subdivide() = 0; virtual void triangulation() = 0; + void display(); }; std::ostream& operator<<(std::ostream& os, const Chose& r); diff --git a/rules/rectangleroutes.cpp b/rules/rectangleroutes.cpp @@ -1,25 +1,23 @@ #include "all_includes.hh" -RectangleRoutes::RectangleRoutes(Vertex ne, Vertex sw) : ne(ne), sw(sw) { - addEntropy(ne); - addEntropy(sw); - std::cout << this << std::endl; +RectangleRoutes::RectangleRoutes(Vertex ne, Vertex sw) : Chose(), ne(ne), sw(sw) { + addEntropy(ne, sw); + triangulation(); } int RectangleRoutes::width() { return std::abs(this->ne.x - this->sw.x); } int RectangleRoutes::height() { return std::abs(this->ne.y - this->sw.y); } -void RectangleRoutes::subdivide() { - initChildren(9); - +bool RectangleRoutes::subdivide() { + children.reserve(9); Vertex split( hashInRange(this->seed, 0, this->sw.x + this->width()*1/4, this->sw.x + this->width()*3/4), hashInRange(this->seed, 1, this->sw.y + this->height()*1/4, this->sw.y + this->height()*3/4), 0 // TODO ); // TODO : addChild(…); - new Carrefour(split + Vertex(1,1,0), split + Vertex(1,-1,0), split + Vertex(-1,-1,0), split + Vertex(-1,1,0)); + addChild(new Carrefour(split + Vertex(1,1,0), split + Vertex(1,-1,0), split + Vertex(-1,-1,0), split + Vertex(-1,1,0))); // routes au NESW du carrefour // TODO : la plupart des zéros en z sont faux… Vertex roadEndN(split.x, this->ne.y, 0); @@ -31,15 +29,20 @@ void RectangleRoutes::subdivide() { Route* re = new Route(roadEndE + Vertex(0,+1,0), roadEndE + Vertex(0,-1,0), split + Vertex(+1,-1,0), split + Vertex(+1,+1,0)); // E Route* rs = new Route(roadEndS + Vertex(+1,0,0), roadEndS + Vertex(-1,0,0), split + Vertex(-1,-1,0), split + Vertex(+1,-1,0)); // S Route* rw = new Route(roadEndW + Vertex(0,-1,0), roadEndW + Vertex(0,+1,0), split + Vertex(-1,+1,0), split + Vertex(-1,-1,0)); // W + addChild(rn); + addChild(re); + addChild(rs); + addChild(rw); // Sous-quartiers addChild(sub(rn->corners[NE], re->corners[NE])); // sous-quartier NE addChild(sub(re->corners[SE], rs->corners[SE])); // sous-quartier SE addChild(sub(rs->corners[SW], rw->corners[SW])); // sous-quartier SW addChild(sub(rw->corners[NW], rn->corners[NW])); // sous-quartier NW + return true; } void RectangleRoutes::triangulation() { - initTriangles(2); + triangles.reserve(2); Vertex nw(this->sw.x, this->ne.y, 0); Vertex se(this->ne.x, this->sw.y, 0); addTriangle(new Triangle(this->sw, nw, this->ne)); diff --git a/rules/rectangleroutes.hh b/rules/rectangleroutes.hh @@ -4,7 +4,7 @@ #include "all_includes.hh" // RectangleRoutes est un quadrilatère de routes avec des angles aux coins égaux à 90°. -class RectangleRoutes : Chose { +class RectangleRoutes : public Chose { public: Vertex ne; Vertex sw; @@ -12,7 +12,7 @@ public: RectangleRoutes(Vertex ne, Vertex sw); int width(); int height(); - virtual void subdivide(); + virtual bool subdivide(); virtual void triangulation(); private: Chose* sub(Vertex ne, Vertex sw); diff --git a/rules/route.cpp b/rules/route.cpp @@ -2,16 +2,17 @@ #include "../vertex.hh" #include "../directions.hh" -Route::Route(Vertex ne, Vertex se, Vertex sw, Vertex nw) { +Route::Route(Vertex ne, Vertex se, Vertex sw, Vertex nw) : Chose() { corners[NE]=ne; corners[SE]=se; corners[SW]=sw; corners[NW]=nw; - std::cout << this << std::endl; + triangulation(); } -void Route::subdivide() { +bool Route::subdivide() { // TODO + return false; } std::ostream& operator<<(std::ostream& os, const Route* r) { @@ -23,7 +24,7 @@ std::ostream& operator<<(std::ostream& os, const Route& r) { } void Route::triangulation() { - initTriangles(2); + triangles.reserve(2); addTriangle(new Triangle(corners[SW], corners[NW], corners[NE])); addTriangle(new Triangle(corners[SW], corners[SE], corners[NE])); } diff --git a/rules/route.hh b/rules/route.hh @@ -3,12 +3,12 @@ #include "all_includes.hh" -class Route : Chose { +class Route : public Chose { public: Vertex corners[4]; public: Route(Vertex ne, Vertex se, Vertex sw, Vertex nw); - virtual void subdivide(); + virtual bool subdivide(); virtual void triangulation(); public: friend std::ostream& operator<<(std::ostream& os, const Route& r); diff --git a/triangle.cpp b/triangle.cpp @@ -1,9 +1,21 @@ #include "all_includes.hh" Triangle::Triangle(Vertex a, Vertex b, Vertex c): a(a), b(b), c(c) { - std::cout << this << std::endl; + // TODO : calcul de la normale. + normal = Vertex(0,0,1); +} + +std::ostream& operator<<(std::ostream& os, const Triangle* t) { + return os << *t; } std::ostream& operator<<(std::ostream& os, const Triangle& t) { return os << "Triangle " << t.a << "--" << t.b << "--" << t.c << "-- cycle"; } + +void Triangle::display() { + glNormal3d(normal.x,normal.y,normal.z); + glVertex3d(a.x,a.y,a.z); + glVertex3d(b.x,b.y,b.z); + glVertex3d(c.x,c.y,c.z); +} diff --git a/triangle.hh b/triangle.hh @@ -8,9 +8,12 @@ public: Vertex a; Vertex b; Vertex c; + Vertex normal; public: Triangle(Vertex a, Vertex b, Vertex c); + void display(); public: + friend std::ostream& operator<<(std::ostream& os, const Triangle* t); friend std::ostream& operator<<(std::ostream& os, const Triangle& t); }; diff --git a/view.cpp b/view.cpp @@ -0,0 +1,131 @@ +#include "all_includes.hh" + +View::View(Chose* root) : root(root), cameraDist(300), xSight(0), ySight(0), zSight(0), xAngle(0), yAngle(0), moveDist(10) { + initWindow(); + mainLoop(); +} + +void View::initWindow() { + SDL_Init(SDL_INIT_VIDEO); + SDL_WM_SetCaption("Sortie terrain OpenGL",NULL); + SDL_SetVideoMode(windowWidth, windowHeight, 32, SDL_OPENGL); + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + gluPerspective(70,(double)windowWidth/windowHeight,1,10000); + glEnable(GL_DEPTH_TEST); + glewInit(); + + float MatSpec[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + float MatDif[4] = {0.0f, 0.5f, 0.0f, 1.0f}; + float MatAmb[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + + float Light1Pos[4] = {0.0f, 1.0f, 0.0f, 0.0f}; + float Light1Dif[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + float Light1Spec[4] = {0.0f, 0.0f, 0.0f, 1.0f}; + float Light1Amb[4] = {0.4f, 0.4f, 0.4f, 1.0f}; + float shininess = 128.0f; + + glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,MatSpec); + glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,MatDif); + glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,MatAmb); + glMaterialfv(GL_FRONT,GL_SHININESS,&shininess); + + glLightfv(GL_LIGHT0, GL_DIFFUSE, Light1Dif); + glLightfv(GL_LIGHT0, GL_SPECULAR, Light1Spec); + glLightfv(GL_LIGHT0, GL_AMBIENT, Light1Amb); + glLightfv(GL_LIGHT0, GL_POSITION, Light1Pos); + + glEnable(GL_LIGHTING); // Active l'éclairage + glEnable(GL_LIGHT0); // Active la lumière 0; +} + +void View::displayAxes() { + glDisable(GL_LIGHTING); + glDisable(GL_TEXTURE_2D); + glBegin(GL_LINES); + glColor3ub(255,0,0); + glVertex3f(0.0f, 0.0f, 0.0f); // origin of the line + glVertex3f(2500.0f, 0.0f, 0.0f); // ending point of the line + glEnd( ); + + glBegin(GL_LINES); + glColor3ub(0,255,0); + glVertex3f(0.0f, 0.0f, 0.0f); // origin of the line + glVertex3f(0.0f, 2500.0f, 0.0f); // ending point of the line + glEnd( ); + + glBegin(GL_LINES); + glColor3ub(0,0,255); + glVertex3f(0.0f, 0.0f, 0.0f); // origin of the line + glVertex3f(0.0f, 0.0f, -2500.0f); // ending point of the line + glEnd( ); + glEnable(GL_LIGHTING); +} + +void View::renderScene() { + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + //gluLookAt(1024,512,1356,1024,512,0,0,1,0); + + //glClearColor(1,1,1,1); // pour un fond blanc + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ; + + //gluLookAt(0,0,cameraDist, 0, 0, 0,0,1,0); + glTranslated(-xSight,-ySight,-(zSight+cameraDist)); + glRotatef(-yAngle,1,0,0); + glRotatef(-xAngle,0,0,1); + + displayAxes(); + glBegin(GL_TRIANGLES); + root->display(); + glEnd(); + + glFlush(); + SDL_GL_SwapBuffers(); +} + + +void View::mainLoop() { + short continuer = 1; + SDL_Event event; + + while (continuer) { + SDL_WaitEvent(&event); + switch(event.type) { + case SDL_QUIT: + continuer = 0; + break; + case SDL_KEYDOWN: + switch(event.key.keysym.sym) { + case SDLK_DOWN: + ySight -= moveDist; + break; + case SDLK_UP: + ySight += moveDist; + break; + case SDLK_LEFT: + xSight -= moveDist; + break; + case SDLK_RIGHT: + xSight += moveDist; + break; + + default: + break; + } + break; + + case SDL_MOUSEMOTION: + xAngle = ((event.motion.x-windowWidth/2)*340/(windowWidth)); + yAngle = (event.motion.y-windowHeight/2)*340/(windowHeight); + break; + + default: + break; + } + + renderScene(); + } + + SDL_Quit(); +} diff --git a/view.hh b/view.hh @@ -0,0 +1,35 @@ +#ifndef _VIEW_HH_ +#define _VIEW_HH_ + +#include "all_includes.hh" + +// TODO : +// flycam : le centre ne bouge pas, la souris contrôle l'angle de vue x & y +// les flèches avant/arrière permettent d'avancer/reculer. +// Calcul correct des normales dans triangle.cpp +// Prendre en compte tous les évènements X en attente avant de relancer le rendu. + +class View { +private: + Chose* root; + + static const int windowWidth = 1024; + static const int windowHeight = 768; + int cameraDist; + + int xSight; + int ySight; + int zSight; + + float xAngle; + float yAngle; + int moveDist; +public: + View(Chose* root); + void initWindow(); + void mainLoop(); + void renderScene(); + void displayAxes(); +}; + +#endif