diff --git a/Makefile b/Makefile index 4f881d8..dedb313 100755 --- a/Makefile +++ b/Makefile @@ -1,21 +1,25 @@ -OBJDIR := obj SRCDIR := sources INCLUDEDIR := include BINDIR := bin DEBUG := yes +VPATH = $(SRCDIR) $(INCLUDEDIR) + +vpath %.cpp $(SRCDIR) +vpath %.h $(INCLUDEDIR) + ifdef COMSPEC # windows CXX := C:/g++ - CXXFLAGS := -Wall -I$(INCLUDEDIR) + CXXFLAGS := -Wall -I $(INCLUDEDIR) LIBS := RM := rm PROGNAME := cg.exe else # better than windows CXX := g++ - CXXFLAGS := -DUNIX -Wall `sdl-config --cflags` -I$(INCLUDEDIR) + CXXFLAGS := -DUNIX -Wall `sdl-config --cflags` -I $(INCLUDEDIR) LIBS := `sdl-config --libs` -lGL -lGLU RM := rm -f PROGNAME := cg @@ -25,17 +29,12 @@ CXXFLAGS := $(CXXFLAGS) -DDEBUG endif -all: $(OBJDIR)/main.o $(OBJDIR)/array.o - $(CXX) $(CXXFLAGS) $(LIBS) $(OBJDIR)/array.o $(OBJDIR)/main.o -o $(BINDIR)/$(PROGNAME) +OBJECTS = main.o array.o poly.o model.o light.o vec.o color.o -$(OBJDIR)/main.o: $(SRCDIR)/main.cpp - $(CXX) $(CXXFLAGS) -c $(SRCDIR)/main.cpp -o $(OBJDIR)/main.o - -$(OBJDIR)/array.o: $(SRCDIR)/array.cpp $(INCLUDEDIR)/array.h - $(CXX) $(CXXFLAGS) -c $(SRCDIR)/array.cpp -o $(OBJDIR)/array.o +all: $(OBJECTS) + $(CXX) $(CXXFLAGS) $(LIBS) $^ -o $(BINDIR)/$(PROGNAME) run: $(BINDIR)/$(PROGNAME) clean: - $(RM) $(OBJDIR)/* - $(RM) $(BINDIR)/* + $(RM) *.o diff --git a/include/array.h b/include/array.h index 20f7b85..f9a5269 100755 --- a/include/array.h +++ b/include/array.h @@ -1,3 +1,5 @@ +#ifndef _ARRAY_H +#define _ARRAY_H class Array { private: int _size; @@ -22,3 +24,4 @@ void*& operator[](int p); ~Array(); }; +#endif diff --git a/include/color.h b/include/color.h new file mode 100755 index 0000000..3a85bca --- /dev/null +++ b/include/color.h @@ -0,0 +1,13 @@ +#ifndef _COLOR_H +#define _COLOR_H +class Color { + public: + float r; + float g; + float b; + + Color(float _r, float _g, float _b); + void drawColor(); + Color* clone(); +}; +#endif diff --git a/include/light.h b/include/light.h new file mode 100755 index 0000000..6d076be --- /dev/null +++ b/include/light.h @@ -0,0 +1,14 @@ +#ifndef _LIGHT_H +#define _LIGHT_H + +#include "vec.h" + +class Light { + public: + Vec* pos; + Vec* dir; + Light(Vec* _pos, Vec* _dir); + void trace(); + void draw(); +}; +#endif diff --git a/include/model.h b/include/model.h new file mode 100755 index 0000000..33b49c6 --- /dev/null +++ b/include/model.h @@ -0,0 +1,25 @@ +#ifndef _MODEL_H +#define _MODDEL_H + +#include "array.h" +#include "vec.h" +#include "poly.h" + +class Model { + private: + Array* faces; + + Vec* position; + Vec* rotation; + + public: + Model(Array* _faces); + ~Model(); + void setCenter(Vec& c); + Vec calcCenter(); + void rotate(Vec rot); + void draw(); + void addFace(Poly* face); + int numberOfFaces(); +}; +#endif diff --git a/include/poly.h b/include/poly.h new file mode 100755 index 0000000..70c2935 --- /dev/null +++ b/include/poly.h @@ -0,0 +1,29 @@ +#ifndef _POLY_H +#define _POLY_H + +#include "array.h" +#include "vec.h" +#include "color.h" + +class Poly { + private: + Array* initpoints; + int size; + Vec* position; + Vec* rotation; + Color* color; + public: + Poly(Array* _points); + Poly(Array* _points, Color _color); + ~Poly(); + void setCenter(Vec c); + Vec getInitRotation(Vec& v); + Vec calcCenter(); + void setPosition(Vec newcenter); + void rotate(Vec rot); + Vec rotate_x(Vec& c); + Vec rotate_y(Vec& c); + Vec rotate_z(Vec& c); + void draw(); +}; +#endif diff --git a/include/vec.h b/include/vec.h new file mode 100755 index 0000000..929c1fe --- /dev/null +++ b/include/vec.h @@ -0,0 +1,26 @@ +#ifndef _VEC_H +#define _VEC_H +class Vec { + public: + float c[3]; + + Vec(float vx, float vy, float vz); + Vec(Vec* v); + float x(); + float y(); + float z(); + float* getCoords(); + Vec operator+(Vec* v); + Vec operator+(Vec c); + void add(Vec& a); + Vec operator-(Vec& v); + Vec operator*(float s); + Vec operator*(Vec& s); + Vec operator/(float s); + Vec cross(Vec* v); + Vec normalize(); + float length(); + void print(); + Vec* clone(); +}; +#endif diff --git a/sources/color.cpp b/sources/color.cpp new file mode 100755 index 0000000..c3149fa --- /dev/null +++ b/sources/color.cpp @@ -0,0 +1,18 @@ +#include "color.h" + +#include +#include + +Color::Color(float _r, float _g, float _b) { + r = _r; + g = _g; + b = _b; +} + +void Color::drawColor() { + glColor4f(r, g, b, 1.0f); +} + +Color* Color::clone() { + return new Color(r,g,b); +} diff --git a/sources/light.cpp b/sources/light.cpp new file mode 100755 index 0000000..9a99614 --- /dev/null +++ b/sources/light.cpp @@ -0,0 +1,25 @@ +#include "light.h" + +#include +#include + +Light::Light(Vec* _pos, Vec* _dir) { + pos = _pos; + dir = _dir; +} + +void Light::trace() { + glBegin (GL_LINES); + glVertex3fv(pos->getCoords()); + glVertex3fv(dir->getCoords()); + glEnd(); +} + +void Light::draw() { + //printf(GL_LIGHT0); + glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f); + float p [4] = {pos->x(), pos->y(), pos->z(), 1.0f}; + float d [4] = {dir->x(), dir->y(), dir->z(), 1.0f}; + glLightfv(GL_LIGHT0, GL_POSITION, p); + glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, d); +} diff --git a/sources/main.cpp b/sources/main.cpp index 6faacd4..961d25e 100755 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -14,8 +14,8 @@ #include // Only required under Windows :-D #endif -//#include // This file import the SDL inteface -#include // This file import the SDL inteface +#include // This file import the SDL inteface +#include // This file import the SDL inteface #include // This file import the OpenGL interface #include // This file offers some OpenGL-related utilities @@ -44,12 +44,14 @@ #endif #include "array.h" +#include "vec.h" +#include "color.h" +#include "poly.h" +#include "model.h" +#include "light.h" using namespace std; -///////////// -// #DEFINE // -///////////// // Constants hardcoded during compilation #define WINDOW_TITLE "the cube" #define WINDOW_X 800 // Window width @@ -67,357 +69,15 @@ #define DD1(x) while(firstprint) { printf("DD1: %d\n", x); firstprint = 0;}; /////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -// CLASSES - - - -class Color { - public: - float r; - float g; - float b; - Color(float _r, float _g, float _b) { - r = _r; - g = _g; - b = _b; - } - - void drawColor() { - glColor4f(r, g, b, 1.0f); - } - - Color* clone() { - return new Color(r,g,b); - } -}; - - -class Vec { - public: - float c[3]; - - Vec(float vx, float vy, float vz) { - c[0] = vx; - c[1] = vy; - c[2] = vz; - } - - Vec(Vec* v) { - Vec(v->x(), v->y(), v->z()); - } - - float x() { - return c[0]; - } - - float y() { - return c[1]; - } - - float z() { - return c[2]; - } - - float* getCoords() { - return c; - } - - Vec operator+(Vec* v) { - return Vec(x() + v->x(), y() + v->y(), z() + v->z()); - } - - Vec operator+(Vec v) { - return Vec(x() + v.x(), y() + v.y(), z() + v.z()); - } - - - void add(Vec& a) { - c[0] += a.x(); - c[1] += a.y(); - c[2] += a.z(); - } - - Vec operator-(Vec& v) { - return Vec(x() - v.x(), y() - v.y(), z() - v.z()); - } - - Vec operator*(float s) { - Vec r = Vec(x()*s, y()*s, z()*s); - return r; - } - - Vec operator*(Vec& s) { - return Vec(x()*s.x(), y()*s.y(), z()*s.z()); - } - - Vec operator/(float s) { - return Vec(x()/s, y()/s, z()/s); - } - - Vec cross(Vec* v) { - return Vec(y() * v->z() - z() * v->y(), - z() * v->x() - x() * v->z(), - x() * v->y() - y() * v->x()); - } - - Vec normalize() { - return *this * (1 / length()); - } - - float length() { - return sqrt(x()*x()+y()*y()+z()*z()); - } - - void print() { - printf (" vektor: %f, %f, %f\n", x(), y(), z()); - } - - Vec* clone() { - return new Vec(x(), y(), z()); - } -}; - - -class Poly { - private: - Array* initpoints; - int size; - - Vec* position; - Vec* rotation; - Color* color; - - public: - Poly(Array* _points) { - Poly(_points, Color(1,1,1)); - } - - Poly(Array* _points, Color _color) { - size = _points->length(); - position = new Vec(0,0,0); - rotation = new Vec(0,0,0); - color = _color.clone(); - -#ifdef DEBUG - printf("new Poly(%d)\n", size); -#endif - initpoints = new Array(_points); - - setCenter(calcCenter()); - } - - ~Poly() { - delete position; - delete rotation; - delete color; - delete initpoints; - } - - /* - * set the position where the (rotation-)center of - * the polygon is located - */ - void setCenter(Vec c) { - delete position; - position = c.clone(); - } - - /* - * initial rotation relative to rotation center - */ - Vec getInitRotation(Vec& v) { - return Vec(atan2(v.y(), v.z()), - atan2(v.x(), v.z()), - atan2(v.y(), v.x())); - } - - /* - * calculate the center relative to all vertices. - */ - Vec calcCenter() { - Vec s (0,0,0); - Vec* t; - initpoints->reset(); - while ( t = (Vec*)initpoints->next() ) { - s = s+*t; - } - return s / ((float)size); - } - - /* - * reset the position of all vertices (ie. translate your - * polygon to an absolute position) - */ - void setPosition(Vec newcenter) { - Vec diff = newcenter - (*position); - delete position; - position = newcenter.clone(); - Vec* t; - initpoints->reset(); - while ( t = (Vec*)initpoints->next() ) { - t->add(diff); - } - } - - //additional rotation in arcs - void rotate(Vec rot) { - rotation->add(rot); - } - - Vec rotate_x(Vec& c) { - Vec initrot = getInitRotation(c); - Vec rot = initrot + *rotation; - float r = Vec(0, c.y(), c.z()).length(); - return Vec (c.x(), r*cos(rot.x()), r*sin(rot.x())); - } - - Vec rotate_y(Vec& c) { - Vec initrot = getInitRotation(c); - Vec rot = initrot + *rotation; - float r = Vec(c.x(), 0, c.z()).length(); - return Vec (r*sin(rot.y()), c.y(), r*cos(rot.y())); - } - - Vec rotate_z(Vec& c) { - Vec initrot = getInitRotation(c); - Vec rot = initrot + *rotation; - float r = Vec(c.x(), c.y(), 0).length(); - return Vec (r*cos(rot.z()), r*sin(rot.z()), c.z()); - } - - void draw() { - glBegin (GL_POLYGON); - - //Vec v1 = *((Vec*)initpoints->get(2)) - *((Vec*)initpoints->get(0)); - //Vec v2 = *((Vec*)initpoints->get(1)) - *((Vec*)initpoints->get(0)); - //glNormal3fv( v1.cross(v2)+ *(Vec*)((*initpoints)[0]).c ); - //glNormal3fv( v1.cross(v2) + ((Vec*)initpoints->get(0))->c ); - - Vec* t; - Vec* mv; - initpoints->reset(); - while ( (t = (Vec*)initpoints->next()) ) { - color->drawColor(); - Vec out = (*t - *position); - out = rotate_x(out); - out = rotate_y(out); - out = rotate_z(out); - mv = (*position + out).clone(); - glVertex3fv(mv->c); - } - glEnd(); - } -}; - - -/* - * lightsource - */ -class Light { - public: - Vec* pos; - Vec* dir; - Light(Vec* _pos, Vec* _dir) { - pos = _pos; - dir = _dir; - } - - void trace() { - glBegin (GL_LINES); - glVertex3fv(pos->getCoords()); - glVertex3fv(dir->getCoords()); - glEnd(); - } - - void draw() { - //printf(GL_LIGHT0); - glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f); - float p [4] = {pos->x(), pos->y(), pos->z(), 1.0f}; - float d [4] = {dir->x(), dir->y(), dir->z(), 1.0f}; - glLightfv(GL_LIGHT0, GL_POSITION, p); - glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, d); - } -}; - -class Model { - private: - Array* faces; - - Vec* position; - Vec* rotation; - - public: - Model(Array* _faces) { - faces = new Array(*_faces); - Vec c = calcCenter(); - setCenter(c); - rotation = new Vec(0,0,0); - } - - ~Model() { - delete position; - delete rotation; - delete faces; - } - - void setCenter(Vec& c) { - delete position; - position = c.clone(); - } - - Vec calcCenter() { - Vec s(0,0,0); - Poly* t; - faces->reset(); - while ( t = (Poly*)faces->next() ) { - s = s + t->calcCenter(); - } - return s/((float)faces->length()); - } - - void rotate(Vec rot) { - rotation->add(rot); - faces->reset(); - Poly* t; - while ( t = (Poly*)faces->next() ) { - t->rotate(rot); - } - } - - void draw() { - faces->reset(); - Poly* t; - while ( t = (Poly*)faces->next() ) { - t->draw(); - } - } - - void addFace(Poly* face) { - faces->push(face); - } - - int numberOfFaces() { - return faces->length(); - } -}; - - -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////// // GLOBAL VARS int MouseX, MouseY, OldMouseX, OldMouseY; bool MouseButtonRight, MouseButtonLeft; bool done = false; // Quit application when true -const char* getNextToken(string& line) { +string getNextToken(string& line) { if ( line.length() < 1 ) { - return NULL; + return ""; } string mp; @@ -435,22 +95,26 @@ mp = line.substr(0, np); line.erase(0, np); - return mp.c_str(); + return mp; } int getNextPoint(string& line) { - const char* tch; + string tch; + int sp; tch = getNextToken(line); - if ( tch == NULL ) { + if ( tch == "" ) { return -1; } - return (int)atoi(tch); + if ( (unsigned int)(sp = tch.find("/", 0)) != string::npos ) { + tch.erase(sp); + } + return (int)atoi(tch.c_str()); } float getNextCoord(string& line) { const char* tch; - tch = getNextToken(line); - if ( tch == NULL ) { + tch = getNextToken(line).c_str(); + if ( tch == "" ) { return -1; } return (float)atof(tch); @@ -595,8 +259,8 @@ polys->push(new Poly(pp4, yellow)); polys->push(new Poly(pp5, violet)); - //Model* myModel = importModel("teapot.obj"); - // printf("imported teapot.obj : %d faces\n", myModel->numberOfFaces()); + //Model* myModel = importModel("untitled.obj"); +//printf("imported untitled.obj : %d faces\n", myModel->numberOfFaces()); Poly* t; polys->reset(); diff --git a/sources/model.cpp b/sources/model.cpp new file mode 100755 index 0000000..0deef4c --- /dev/null +++ b/sources/model.cpp @@ -0,0 +1,54 @@ +#include "model.h" + +Model::Model(Array* _faces) { + faces = new Array(*_faces); + Vec c = calcCenter(); + setCenter(c); + rotation = new Vec(0,0,0); +} + +Model::~Model() { + delete position; + delete rotation; + delete faces; +} + +void Model::setCenter(Vec& c) { + delete position; + position = c.clone(); +} + +Vec Model::calcCenter() { + Vec s(0,0,0); + Poly* t; + faces->reset(); + while ( t = (Poly*)faces->next() ) { + s = s + t->calcCenter(); + } + return s/((float)faces->length()); +} + +void Model::rotate(Vec rot) { + rotation->add(rot); + faces->reset(); + Poly* t; + while ( t = (Poly*)faces->next() ) { + t->rotate(rot); + } +} + +void Model::draw() { + faces->reset(); + Poly* t; + while ( t = (Poly*)faces->next() ) { + t->draw(); + } +} + +void Model::addFace(Poly* face) { + faces->push(face); +} + +int Model::numberOfFaces() { + return faces->length(); +} diff --git a/sources/poly.cpp b/sources/poly.cpp new file mode 100755 index 0000000..e835543 --- /dev/null +++ b/sources/poly.cpp @@ -0,0 +1,125 @@ +#include +#include + +#include +#include + +#include "poly.h" + +Poly::Poly(Array* _points) { + Poly(_points, Color(1,1,1)); +} + +Poly::Poly(Array* _points, Color _color) { + size = _points->length(); + position = new Vec(0,0,0); + rotation = new Vec(0,0,0); + color = _color.clone(); + +#ifdef DEBUG + printf("new Poly(%d)\n", size); +#endif + initpoints = new Array(_points); + + setCenter(calcCenter()); +} + +Poly::~Poly() { + delete position; + delete rotation; + delete color; + delete initpoints; +} + +/* +* set the position where the (rotation-)center of +* the polygon is located +*/ +void Poly::setCenter(Vec c) { + delete position; + position = c.clone(); +} + +/* +* initial rotation relative to rotation center +*/ +Vec Poly::getInitRotation(Vec& v) { + return Vec(atan2(v.y(), v.z()), atan2(v.x(), v.z()), atan2(v.y(), v.x())); +} + +/* +* calculate the center relative to all vertices. +*/ +Vec Poly::calcCenter() { + Vec s (0,0,0); + Vec* t; + initpoints->reset(); + while ( t = (Vec*)initpoints->next() ) { + s = s+*t; + } + return s / ((float)size); +} + +/* +* reset the position of all vertices (ie. translate your +* polygon to an absolute position) +*/ +void Poly::setPosition(Vec newcenter) { + Vec diff = newcenter - (*position); + delete position; + position = newcenter.clone(); + Vec* t; + initpoints->reset(); + while ( t = (Vec*)initpoints->next() ) { + t->add(diff); + } +} + +//additional rotation in arcs +void Poly::rotate(Vec rot) { + rotation->add(rot); +} + +Vec Poly::rotate_x(Vec& c) { + Vec initrot = getInitRotation(c); + Vec rot = initrot + *rotation; + float r = Vec(0, c.y(), c.z()).length(); + return Vec (c.x(), r*cos(rot.x()), r*sin(rot.x())); +} + +Vec Poly::rotate_y(Vec& c) { + Vec initrot = getInitRotation(c); + Vec rot = initrot + *rotation; + float r = Vec(c.x(), 0, c.z()).length(); + return Vec (r*sin(rot.y()), c.y(), r*cos(rot.y())); +} + +Vec Poly::rotate_z(Vec& c) { + Vec initrot = getInitRotation(c); + Vec rot = initrot + *rotation; + float r = Vec(c.x(), c.y(), 0).length(); + return Vec (r*cos(rot.z()), r*sin(rot.z()), c.z()); +} + +void Poly::draw() { + glBegin (GL_POLYGON); + + //Vec v1 = *((Vec*)initpoints->get(2)) - *((Vec*)initpoints->get(0)); + //Vec v2 = *((Vec*)initpoints->get(1)) - *((Vec*)initpoints->get(0)); + //glNormal3fv( v1.cross(v2)+ *(Vec*)((*initpoints)[0]).c ); + //glNormal3fv( v1.cross(v2) + ((Vec*)initpoints->get(0))->c ); + + Vec* t; + Vec* mv; + initpoints->reset(); + while ( (t = (Vec*)initpoints->next()) ) { + color->drawColor(); + Vec out = (*t - *position); + out = rotate_x(out); + out = rotate_y(out); + out = rotate_z(out); + mv = (*position + out).clone(); + glVertex3fv(mv->c); + } + glEnd(); +} diff --git a/sources/vec.cpp b/sources/vec.cpp new file mode 100755 index 0000000..0acb620 --- /dev/null +++ b/sources/vec.cpp @@ -0,0 +1,82 @@ +#include "vec.h" + +#include +#include + +Vec::Vec(float vx, float vy, float vz) { + c[0] = vx; + c[1] = vy; + c[2] = vz; +} + +Vec::Vec(Vec* v) { + Vec(v->x(), v->y(), v->z()); +} + +float Vec::x() { + return c[0]; +} + +float Vec::y() { + return c[1]; +} + +float Vec::z() { + return c[2]; +} + +float* Vec::getCoords() { + return c; +} + +Vec Vec::operator+(Vec* v) { + return Vec(x() + v->x(), y() + v->y(), z() + v->z()); +} + +Vec Vec::operator+(Vec v) { + return Vec(x() + v.x(), y() + v.y(), z() + v.z()); +} + + +void Vec::add(Vec& a) { + c[0] += a.x(); + c[1] += a.y(); + c[2] += a.z(); +} + +Vec Vec::operator-(Vec& v) { + return Vec(x() - v.x(), y() - v.y(), z() - v.z()); +} + +Vec Vec::operator*(float s) { + Vec r = Vec(x()*s, y()*s, z()*s); + return r; +} + +Vec Vec::operator*(Vec& s) { + return Vec(x()*s.x(), y()*s.y(), z()*s.z()); +} + +Vec Vec::operator/(float s) { + return Vec(x()/s, y()/s, z()/s); +} + +Vec Vec::cross(Vec* v) { + return Vec(y() * v->z() - z() * v->y(), z() * v->x() - x() * v->z(), x() * v->y() - y() * v->x()); +} + +Vec Vec::normalize() { + return *this * (1 / length()); +} + +float Vec::length() { + return sqrt(x()*x()+y()*y()+z()*z()); +} + +void Vec::print() { + printf (" vektor: %f, %f, %f\n", x(), y(), z()); +} + +Vec* Vec::clone() { + return new Vec(x(), y(), z()); +}