diff --git a/include/animation.h b/include/animation.h index fdbac84..7848ba5 100644 --- a/include/animation.h +++ b/include/animation.h @@ -4,6 +4,7 @@ #include "thing.h" #include +#include #ifndef PI #define PI 3.14159265f @@ -14,8 +15,28 @@ class Animation { public: Animation(); + virtual void init(); + virtual void tick(); +}; + +class StaticAnimation : public Animation { + private: + Vec* rot_diff; + Vec* pos_diff; + Vec* amb_diff; + Vec* spec_diff; + std::vector things; + float speed; + public: + StaticAnimation(); + StaticAnimation(Thing* t); void init(); void tick(); + void setRot(Vec r); + void setPos(Vec p); + void addThing(Thing* t); + void setSpeed(float s); + virtual ~StaticAnimation(); }; class UserAnimation : public Animation { @@ -40,6 +61,7 @@ void addColor(Color* t); void init(); void tick(); + virtual ~UserAnimation(); }; #endif diff --git a/include/glumodel.h b/include/glumodel.h index e13ae1f..e2eecba 100644 --- a/include/glumodel.h +++ b/include/glumodel.h @@ -41,6 +41,20 @@ void init(float _iters, float _len); }; +class SierpinskiPyramid : public GenericModel { + private: + int iter; + std::vector faces; + GLuint list; + public: + SierpinskiPyramid(Vec p, float l, int n); + void construct(int n); + void draw(); + void drawPyramid(); + void buildList(); + virtual ~SierpinskiPyramid(); +}; + class KochFractal : public Fractal { public: KochFractal(); diff --git a/include/light.h b/include/light.h index 070bb75..f21a805 100755 --- a/include/light.h +++ b/include/light.h @@ -27,9 +27,10 @@ void init(GLenum _num, Vec _pos, Material _mat); void setPosition(Vec newpos); void rotate(Vec rot); + void translate(Vec d); void show(); void hide(); - void draw(); + virtual void draw(); void trace(bool _s); }; @@ -40,7 +41,7 @@ public: void draw(); - SpotLight(GLenum _num, Vec _pos, Material _mat, float _angle); + SpotLight(GLenum _num, Vec _pos, Material _mat, float _angle); }; #endif diff --git a/include/model.h b/include/model.h index f53c4b1..cda95b1 100755 --- a/include/model.h +++ b/include/model.h @@ -19,7 +19,7 @@ public: Model(); Model(std::vector & _faces); - ~Model(); + virtual ~Model(); void setCenter(Vec& c); void setCenter(Vec* c); void setPosition(Vec c); diff --git a/sources/animation.cpp b/sources/animation.cpp index a07fcf7..4ccf371 100644 --- a/sources/animation.cpp +++ b/sources/animation.cpp @@ -10,8 +10,6 @@ #define PI 3.14159265f #endif -#define DEBUG - /* class Animation */ Animation::Animation() { @@ -118,7 +116,7 @@ } /* only do operations if we have a current object */ - if ( current > -1 && current < things.size() ) { + if ( current > -1 && current < (int)things.size() ) { /* move x */ if ( kbd[SDLK_a] ) { things.at(current)->translate(Vec(1.0f*speed, 0.0f, 0.0f)); } if ( kbd[SDLK_d] ) { things.at(current)->translate(Vec(-1.0f*speed, 0.0f, 0.0f)); } @@ -214,3 +212,55 @@ colors.push_back(c); if ( colorpt < 0 ) { colorpt = 0; } } + +UserAnimation::~UserAnimation ( ) { } + +/* class StaticAnimation */ + +StaticAnimation::StaticAnimation ( ) { +} + +StaticAnimation::StaticAnimation ( Thing* t ) { + this->addThing(t); +} + +void StaticAnimation::init ( ) { + speed = 1.0f; + rot_diff = new Vec(0,0,0); + pos_diff = new Vec(0,0,0); + amb_diff = new Vec(0,0,0); + spec_diff = new Vec(0,0,0); +} + +void StaticAnimation::addThing ( Thing* t ) { + things.push_back(t); +} + +void StaticAnimation::tick ( ) { + if ( things.size() > 0 ) { + for ( std::vector::size_type i = 0; i < things.size(); i++ ) { + things.at(i)->translate(*pos_diff*speed); + things.at(i)->rotate(*rot_diff*speed); + // TODO change color + } + } +} + +void StaticAnimation::setSpeed ( float s ) { + speed = s; +} + +void StaticAnimation::setRot ( Vec r ) { + rot_diff = r.clone(); +} + +void StaticAnimation::setPos ( Vec p ) { + pos_diff = p.clone(); +} + +StaticAnimation::~StaticAnimation ( ) { + delete rot_diff; + delete pos_diff; + delete amb_diff; + delete spec_diff; +} diff --git a/sources/glumodel.cpp b/sources/glumodel.cpp index ba50b4f..2517615 100644 --- a/sources/glumodel.cpp +++ b/sources/glumodel.cpp @@ -45,7 +45,7 @@ if (enabled) { mat->draw(); - gluSphere(gluNewQuadric(), rad, 300, 300); + gluSphere(gluNewQuadric(), rad, 300, 300); } glPopMatrix(); @@ -65,6 +65,125 @@ mult_angle = 90; } +SierpinskiPyramid::SierpinskiPyramid(Vec _pos, float _len, int _iter) { + iter = _iter; + scale = _len; + pos = _pos.clone(); + rot = new Vec(0,0,0); + + buildList(); +} + +void SierpinskiPyramid::buildList() { + + list = glGenLists(1); + glNewList(list, GL_COMPILE); + + drawPyramid(); + + glEndList(); +} + +void SierpinskiPyramid::construct(int n) { + if ( n > 0 ) { + n--; + + glPushMatrix(); + glScalef(0.5, 0.5, 0.5); + construct(n); + glPopMatrix(); + glPushMatrix(); + glScalef(0.5, 0.5, 0.5); + glTranslatef(1, 0, 0.5); + construct(n); + glPopMatrix(); + glPushMatrix(); + glScalef(0.5, 0.5, 0.5); + glTranslatef(0, 0, 1); + construct(n); + glPopMatrix(); + glPushMatrix(); + glScalef(0.5, 0.5, 0.5); + glTranslatef(0.5, 1, 0.5); + construct(n); + glPopMatrix(); + } else { + //TODO: make this parametrable + float c[] = {1.0, 0, 0}; + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, c); + + /* if available, use OpenGL lists to accelerate drawing */ + if ( list == 0 ) { + drawPyramid(); + } else { + glCallList(list); + } + } +} + +void SierpinskiPyramid::drawPyramid() { + + Vec a; + Vec b; + Vec p0 = Vec(0,0,0); + Vec p1 = Vec(1,0,0.5); + Vec p2 = Vec(0,0,1); + Vec p3 = Vec(0.5,1,0.5); + + glBegin(GL_TRIANGLES); + a = (p0)-(p1); + b = (p2)-(p1); + glNormal3fv((a.cross(b)).c); + glVertex3fv(p0.c); + glVertex3fv(p1.c); + glVertex3fv(p2.c); + + a = (p3)-(p1); + b = (p0)-(p1); + glNormal3fv((a.cross(b)).c); + glVertex3fv(p3.c); + glVertex3fv(p1.c); + glVertex3fv(p0.c); + + a = (p0)-(p2); + b = (p3)-(p2); + glNormal3fv((a.cross(b)).c); + glVertex3fv(p0.c); + glVertex3fv(p2.c); + glVertex3fv(p3.c); + + a = (p2)-(p1); + b = (p3)-(p1); + glNormal3fv((a.cross(b)).c); + glVertex3fv(p2.c); + glVertex3fv(p1.c); + glVertex3fv(p3.c); + glEnd(); +} + +void SierpinskiPyramid::draw() { + + glPushMatrix(); + + /* rotate SierpinskiPyramid */ + glRotatef(rot->x(), 1.0f, 0.0f, 0.0f); + glRotatef(rot->y(), 0.0f, 1.0f, 0.0f); + glRotatef(rot->z(), 0.0f, 0.0f, 1.0f); + + /* move it to the desired position */ + glTranslatef(pos->x(), pos->y(), pos->z()); + + /* scale it to the desired length, width and height */ + glScalef(scale, scale, scale); + + /* draw it */ + construct(iter); + + glPopMatrix(); +} + +SierpinskiPyramid::~SierpinskiPyramid ( ) { } + KochFractal::KochFractal() { Fractal::init(3, 30); multiplicity = 6; diff --git a/sources/light.cpp b/sources/light.cpp index ecf84b5..a3a4252 100755 --- a/sources/light.cpp +++ b/sources/light.cpp @@ -45,6 +45,10 @@ pos = newpos.clone(); } +void Light::translate(Vec d) { + pos->add((Vec)d); +} + void Light::rotate(Vec a) { rot->add((Vec)a); } @@ -79,28 +83,35 @@ } void SpotLight::draw() { - //save camera position - glPushMatrix(); + if ( enabled ) { + //save camera position + glPushMatrix(); - glRotatef(rot->x(), 1.0f, 0.0f, 0.0f); - glRotatef(rot->y(), 0.0f, 1.0f, 0.0f); - glRotatef(rot->z(), 0.0f, 0.0f, 1.0f); + glRotatef(rot->x(), 1.0f, 0.0f, 0.0f); + glRotatef(rot->y(), 0.0f, 1.0f, 0.0f); + glRotatef(rot->z(), 0.0f, 0.0f, 1.0f); - glTranslatef(pos->x(), pos->y(), pos->z()); - glLightf(num, GL_SPOT_CUTOFF, cutoff_angle); + glTranslatef(pos->x(), pos->y(), pos->z()); + glLightf(num, GL_SPOT_CUTOFF, cutoff_angle); - float p[] = {0.0f, 0.0f, 0.0f, 1.0f}; - glLightfv(num, GL_POSITION, p); + float p[] = {0.0f, 0.0f, 0.0f, 1.0f}; + glLightfv(num, GL_POSITION, p); - GLfloat dir[] = {0.0f, -1.0f, 0.0f, 1.0f}; - glLightfv(num, GL_SPOT_DIRECTION, dir); + GLfloat dir[] = {0.0f, -1.0f, 0.0f, 1.0f}; + glLightfv(num, GL_SPOT_DIRECTION, dir); - if (showtrace) { - //cone - glTranslatef(0,5.5,0); - glRotatef(90, 1, 0, 0); - gluCylinder (cone, 0, 1, 5, 10, 20); - - } - glPopMatrix(); + if (showtrace) { + //line + glBegin(GL_LINES); + glVertex3fv(p); + glVertex3fv(dir); + glEnd(); + //cone + glTranslatef(0,5.5,0); + glRotatef(90, 1, 0, 0); + gluCylinder (cone, 0, 1, 5, 10, 20); + + } + glPopMatrix(); + } } diff --git a/sources/main.cpp b/sources/main.cpp index 050449a..96c1a2b 100755 --- a/sources/main.cpp +++ b/sources/main.cpp @@ -236,7 +236,7 @@ anims.push_back((Animation*)userAnim); - bool wireframe = false; + int renderMode = 0; int fog = 3; @@ -244,7 +244,13 @@ Material(Color(1,1,0)), 50); - KochFractal myfrac = KochFractal(); + //KochFractal myfrac = KochFractal(); + SierpinskiPyramid* myfrac = new SierpinskiPyramid(Vec(0,0,0), 30, 6); + //myfrac.setCenter(myCen); + //myfrac.setMaterial(Color(1,0,1), Color(1,0,1)); + //myfrac.setPosition(myCen); + //myfrac.showNormals(); + //myfrac.setDelta(PI/2.0); /* begin cube */ Vec* ulh = new Vec(0 ,0 ,0 ); @@ -404,14 +410,22 @@ Material(Color(0.5,0.5,0.5), Color(1,1,1))); + userAnim->addThing((Thing*)(&light0)); + userAnim->addThing((Thing*)(&light1)); + + StaticAnimation* l0Anim = new StaticAnimation(); + l0Anim->init(); + anims.push_back((Animation*)l0Anim); + + l0Anim->addThing((Thing*)(&light0)); + l0Anim->setRot(Vec(1,0,0)); + //Vec l1_pos(-10.0f, -10.0f, -10.0f); //Color l1_col(0.0f, 0.5f, 1.0f); //DiffuseLight light1(l1_pos, l1_col, GL_LIGHT1); //glEnable(GL_COLOR_MATERIAL); - glShadeModel(GL_SMOOTH); - /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// @@ -453,10 +467,27 @@ // Do some rendering: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - if ( wireframe ) { - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - } else { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + switch ( renderMode ) { + case 0: + /* smooth */ + glShadeModel(GL_SMOOTH); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + case 1: + /* linear */ + glShadeModel(GL_LINEAR); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + case 2: + /* flat */ + glShadeModel(GL_FLAT); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + break; + case 3: + /* wireframe */ + glShadeModel(GL_SMOOTH); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + break; } @@ -478,20 +509,17 @@ light0.draw(); light1.draw(); - //TODO JAGGI t�e diz bitte ind animation - light0.rotate(Vec(1,0,0)); - //glTranslatef(0,0,-50); /* do animations */ for ( std::vector::size_type anim_ct = 0; anim_ct < anims.size(); anim_ct++ ) { - ((UserAnimation*)anims.at(anim_ct))->tick(); + ((Animation*)anims.at(anim_ct))->tick(); } /* draw some models */ for ( modelCounter = 0; modelCounter < models.size(); modelCounter++ ) { //models.at(modelCounter)->draw(); - models.at(modelCounter)->rotate(Vec(1.5f, 0.0f, 0.0f)); + //models.at(modelCounter)->rotate(Vec(1.5f, 0.0f, 0.0f)); } // //xy plane @@ -517,9 +545,9 @@ // glEnd(); //draw sphere - mysphere.draw(); + //mysphere.draw(); - myfrac.draw(); + myfrac->draw(); //draw cube //cube->draw(); @@ -551,10 +579,13 @@ react_keyevent = 10; if ( keystate[SDLK_g] ) { - wireframe = !wireframe; + renderMode++; + renderMode = renderMode % 4; + printf("Changed render mode to %d.\n", renderMode); } else { react_keyevent = 0; + } } else { react_keyevent -= 1; diff --git a/sources/model.cpp b/sources/model.cpp index c7560f3..5c2f398 100755 --- a/sources/model.cpp +++ b/sources/model.cpp @@ -141,7 +141,6 @@ } void Model::scale(float f) { - printf("model scale: %f\n", f); for (std::vector::size_type i = 0 ; i < faces.size(); i++ ) { faces.at(i)->scale(f); } diff --git a/sources/poly.cpp b/sources/poly.cpp index 8f3323a..b3c33dd 100755 --- a/sources/poly.cpp +++ b/sources/poly.cpp @@ -288,7 +288,6 @@ } Material* Poly::getMaterial() { - printf("got material %f", material); return material; } @@ -342,6 +341,5 @@ } void Poly::scale(float f) { - printf("scale: %f\n", f); scaleFactor *= f; }