/** * \file gra_app.cpp * * \brief Testapplication zu engage * * Dieses kleine Prog testet die bestehenden Funktionen von engage und * dient dazu neue Funktionen testweise einzubauen, bevor sie endgültig * in die lib kommen. * * \author Georg Steffers [gs] * * \date 16.12.2003 * * \version ..2002 [gs]: erste Implementation * \version 13.12.2003 [gs]: movable eingefügt mit Funktionen für die * wichtigsten Bewegungen (muss aber noch eine * großes cleanup und fixing her) schient aber * für die momentanen bedürfnisse zu * reichen. * \version 16.12.2003 [gs]: * \version 19.12.2003 [gs]: * \version 21.12.2003 [gs]: * \version 22.12.2003 [gs]: Beleuchtung über die in canvas_imp neu * eingebauten light_table eingebaut. */ /** * \mainpage Referenzmanual zu ENGAGE * * \author Georg Steffers [gs] * \date 22.12.2003 * \version 0.0.0: Erster Aufbau, jede Menge immer noch zu tun. * * Dies Projekt war zu anfang eine kleine app um ein wenig x-lib zu * Programmieren. Als das ein wenig langweilig wurde und zumindest * rudimentär funktionierte habe ich angefangen eine kleine 3D-Engine * dazuzuschreiben.
* Heute habe ich das Ziel dies ganze in irgendeinem Spiel zu verwenden. * Bis dahin ist allerdings noch jede Menge zu tun. * Was bislang fertig ist: * * * Was die Engine bislang (mehr oder weniger sauber implementiert) macht: * * * \bug [gs] Mein Backfaceculling funktioniert nicht, das scheint daran zu * liegen, das eine projezierte Seite die 90 Grad zu mir aber stark am * Rand des sichtbaren Bereichs ist sehr wohl von mir gesehen werden kann. * In die berechnung des cullings muss also irgendwie das Scihtfeld * bzw der Blickwinkel mit einbezogen werden. * -- Gefixed: man muss als Blickwinkel nur den vrp nehmen, dann klappts. * \bug [gs] Das Programm darf nicht mehr mit -ffast-math compiliert werden, * da dann anscheinend irgendwas bei der berechnung der inversen * Camera-Matrix kaputtoptimiert wird. * * \todo [gs] Evtl. sollte ich für den Rasterizer imlib2 oder evas * verwenden (bzw ich baue einen rasterizer der diese Libs nutzt). * Evtl. kann evas auch einen kompletten canvas für mich bilden, incl. * Rasterizer. (Auch ein GL Rasterizer sollte noch geschrieben werden. * \todo [gs] Eine menge cleanups. * \todo [gs] Java Version schreiben und hoffen das sie schnell genug ist. * \todo [gs] Natürlich noch jede Menge, Lightmapping, Texturemapping, * Schadowmapping, vorne und hinten z-clipping usw. * \todo [gs] gutes Konzept finden um z-clipping, transformieren und * projezieren zu machen (es darf z.B. nich projeziert werden, solange * das z-clipping läuft. * \todo [gs] ein gutes konzept finden ein polygon einem polyeder zuzuweisen, * und den index innerhalb des Polyeders zu bestimmen, auch wenn * das polygon bereits transformiert wurde...in diesem zusammenhang * glaube ich immer mehr, das es doch besser währe, das polygon * wuerde beim clipping doch nicht einfach ein neues Polygon erzeugen * und stattdessen sich selbst modifizieren und eine referenz auf * sich zurückgeben. (Bei den == Operatoren würde ich dann immer * checken ob es sich wirklich um eine Referenz auf die selbe Instanz * (sprich Adressen gleich) ist. * * Copyright ©2003 Georg Steffers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *


*/ #ifndef __XProto_h__ #define __XProto_h__ using namespace std; #include #include #include #include "factory.h" #include "dispatcher.h" #include "canvas.h" #include "rasterize.h" #include "math/Mmn.h" #include "math/V_K4.h" #include "math/sin_cos.h" #include "geometry/vertex.h" #include "geometry/polygon.h" #include "geometry/polyeder.h" #include #include int compf(const void* a, const void* b) { polygon* _a=(polygon*)a; polygon* _b=(polygon*)b; return (int)(_a->center_p()[Z] - _b->center_p()[Z])*-1; } class light { protected: unsigned intensity; double dist_falloff; public: light(unsigned intense=255) : intensity(intense) {} virtual unsigned get_intensity(void) { return intensity; } virtual void set_intensity(unsigned in) { intensity=in; } }; class ambient_light : public light { public: ambient_light(unsigned intense=255) : light(intense) {} }; // Diese Lampe ist ähnlich wie die Sonne, sie beleuchtet die // gesamte Scenen aus einer Richtung. Diese definiere ich einfach // als fvw des movable. class direct_light : public light, public movable { public: direct_light(unsigned intense=255) : light(intense), movable() {} const vertex& get_direction(void) { return vfw; } }; class camera : public movable { private: double lcxa; //!< (lens coverage(x) angle = Sichtfeld(x)-Winkle double lcx; //!< (lens coverage(x)) = Sichtfeld(x) double sw; //!< (screen width) = Breite des Projektionsfensters double sh; //!< (screen height) = Hoehe des Projektionsfensters double ph_ar; /**< \brief (physical aspect ratio) = Seitenverhaeltnis * des Anzeigegeraets */ double sy; //!< (scale y) = Wert um y proportional zu projezieren. double dz; //!< (delta z) = Abstand des Auges zum screen Mmn cam_trans; public: camera(double lcxa=60) : movable() { this->set_lens_coverage(lcxa); } camera(const rasterizer& scr, double lcxa=60) : movable() { this->set_lens_coverage(lcxa); this->sw=scr.get_x_size(); this->sh=scr.get_y_size(); this->ph_ar=this->sw/this->sh; this->sy=this->sh/this->sw*this->ph_ar; this->dz=(this->sh/2)/tan(RAD(this->lcxa/2)); } camera(const rasterizer& scr, double ph_ar, double lcxa) : movable() { this->set_lens_coverage(lcxa); this->sw=scr.get_x_size(); this->sh=scr.get_y_size(); this->ph_ar=ph_ar; this->sy=this->sh/this->sw*this->ph_ar; this->dz=(this->sh/2)/tan(RAD(this->lcxa/2)); } camera(double sw, double sh, double lcxa=60) : movable() { this->set_lens_coverage(lcxa); this->sw=sw; this->sh=sh; this->ph_ar=this->sw/this->sh; this->sy=this->sh/this->sw*this->ph_ar; this->dz=(this->sh/2)/tan(RAD(this->lcxa/2)); } camera(double sw, double sh, double ph_ar, double lcxa=60) : movable() { this->set_lens_coverage(lcxa); this->sw=sw; this->sh=sh; this->ph_ar=ph_ar; this->sy=this->sh/this->sw*this->ph_ar; this->dz=(this->sh/2)/tan(RAD(this->lcxa/2)); } /** * \brief Setze Sichtfeld. (zwischen 10 und 170) * * lcx ist eine Konstante die die größe der Sichtfeldes * beschreibt. Diese Funktion ermittelt diese Konstante anhand von * Werten zwischen 10 und 170 wobei das volle menschliche Sichtfeld * einem Wert von 100 entspricht. 10 ist extrem Tele und 170 extrem * Weitwinkel. * * \param angle Winkel fürs Sichtfeld (zwischen 10 und 170) * * \pre 10 < angel < 170 */ void set_lens_coverage(double angle) { lcxa=angle; if(lcxa>170) lcxa=170; if(lcxa<10) lcxa=10; lcx=0.5*(1/tan(lcxa*M_PI/(180.0*2.0))); } const Mmn& cam_trans_mat(void) { cam_trans=t_mat.inv_Ad(); if(cam_trans.is_null()) cam_trans=t_mat.gauss(INVERSE); return cam_trans; } double get_lcx(void) const { return lcx; } double get_sw(void) const { return sw; } double get_sh(void) const { return sh; } double get_ph_ar(void) const { return ph_ar; } double get_sy(void) const { return sy; } double get_dz(void) const { return dz; } }; /** * \brief Das eigentliche Programm * * Hier werden alle Teile zu einem kleinen Testprogramm zusammengefügt. */ class app { private: canvas* scr; //!< Der Canvas auf dem gezeichnet wird rasterizer* ras; //!< Der Rasterizer zu dem \ref scr dispatcher* d; //!< Der X11-Dispatcher disp_manager manager; //!< Der Dispatcher-Manager polyeder_movable p; //!< erster Polyeder polyeder_movable p2; //!< zweiter Polyeder polyeder_movable p3; //!< dritter Polyeder polyeder_movable p4; //!< und weils so lustig ist noch einer camera cam; direct_light li; direct_light li2; ambient_light li3; double winkel; int stepping; double cam_winkel; int cam_stepping; double li_winkel; int li_stepping; double li2_winkel; int li2_stepping; double clip_front; unsigned secs, secs_tmp; unsigned short ms; /** * \brief Bringt den Canvas auf den Bildschirm * * Dies ist eine Callback-Methode die zu jedem expose-event u.ä. * aufgerufen wird um den Inhalt des Canvas auf das Fenster zu * übertragen. Diese Methode wird ausschließlich vom * Dispatcher \ref d aufgerufen. * * \param es Die Quelle des Events, in diesem Fall also der canvas * \param key Wird nicht benutzt * * \pre redraw muß als callback in \ref d registriert sein. * \pre \ref scr muß ein gültiger canvas sein. */ void redraw(event_source* es, void* key) { char buffer[10]="\0"; sprintf(buffer, "%02d:%03d", secs, ms); scr->blit_screen(); scr->draw_text(5,15,buffer,strlen(buffer)); //usleep(10); } /** * \brief verarbeitet Tastendrücke im Canvas * * Dies ist eine Callback-Methode die zu jedem keypress-event * im Canvas aufgerufen wird. Hierüber ist es möglich * das Programm zu steuern. Diese Methode wird ausschließlich * vom Dispatcher \ref d aufgerufen. * * \param es Die Quelle des Events, in diesem Fall also der Canvas * \param key Der Ascii-Code der gedrückten Taste. * * \pre exitOnEsc muß als callback in \ref d registriert sein. * \pre \ref scr muß ein gültiger canvas sein. * * \post Falls ESC gedrückt wurde -> Programmende * \post Falls s oder S gedrückt wurde Dispatcher anhalten * \post Falls c oder C gedr%uuml;ckt wurde Dispatcher starten */ void exitOnEsc(event_source* es, void* key) { switch (*(char*)key) { case 27: d->trigger_event(Stop); case 'x': case 'X': d->halt(); break; case 'c': case 'C': d->cont(); break; case '+': cam_stepping=(cam_stepping+1)%11; break; case '-': cam_stepping=cam_stepping>0?(cam_stepping-1)%11:10; break; case 'q': case 'Q': clip_front=clip_front>0?clip_front-10:0; break; case 'w': case 'W': clip_front=clip_front<100?clip_front+10:100; break; case 'r': case 'R': li_stepping=(li_stepping+1)%11; break; case 'e': case 'E': li_stepping=li_stepping>0?(li_stepping-1)%11:10; break; case 'z': case 'Z': li2_stepping=(li2_stepping+1)%11; break; case 't': case 'T': li2_stepping=li2_stepping>0?(li2_stepping-1)%11:10; break; case 'd': case 'D': stepping=(stepping+1)%11; break; case 's': case 'S': stepping=0; break; case 'a': case 'A': stepping=stepping>0?(stepping-1)%11:10; default: break; } } /** * \brief Rotiert, projeziert und zeichnet die drei Polyeder * \ref p, \ref p2 und \ref p3 * * Hier werden mit Hilfe der Klassen aus \ref Mmn.h, \ref sin_cos.h und * \ref V_K4.h die Polyeder gedreht, skaliert, projeziert und * schließlich mit Hilfe der Methoden des Rasterizers \ref ras * auch noch gezeichnet. Am ende wird dann ein Expose-Event * ausgelöst, damit die Änderungen auch am Bildschirm * sichtbar werden. * * \note Im Moment wir rotate auch über disp_x11 aufgerufen, das ist * nicht notwendig, und eigentlich sogar falsch, denn es wird überhaupt * nicht auf ein X-Event reagiert. Was ich brauche ist ein weiteren * Dispatcher (disp_app) der Application-Events aufführt, * Die Rotation müsste dann quasi im idle-Fall ausgeführt werden. * Es würde sicherlich Sinn machen diesen dispatcher dann irgendwie * als thread zu implementieren. Immerhin ist X ja auch ein eigener * Prozess. (OK, der Vergleich hinkt, da ich die XEvents auch im * Hauptprozess abarbeite. * * \param es Die Quelle des Events, in diesem Fall also der canvas * \param dummy Wird nicht benutzt * * \pre redraw muß als callback in \ref d registriert sein. * \pre \ref scr muß ein gültiger canvas sein. * * \post Die Polyeder sind transformiert und auf dem Canvas * gezeichnet. Ein Expose-Event wurde ausgelöst. */ void rotate(event_source* es, void* dummy) { struct timeb tb1; struct timeb tb2; ftime(&tb1); winkel=WINKEL(winkel+stepping); cam_winkel=WINKEL(cam_winkel+cam_stepping); li_winkel=WINKEL(li_winkel-li_stepping); li2_winkel=WINKEL(li2_winkel+li2_stepping); container po_list, po_list_zclipped; //if(winkel==3) // sleep(10); p.rotate_im_g_x(45); p.translate_im_global(-30.0*sin(RAD(winkel)), 5.0*cos(RAD(winkel)), 10.0*cos(RAD(winkel))); p.rotate_im_vfw(WINKEL(2*winkel)); p2.translate_im_global(5.0*cos(RAD(winkel)), 20.0*sin(RAD(winkel)), 20.0*cos(RAD(winkel))); p2.rotate_im_l_z(WINKEL(winkel)); p2.rotate_im_l_y(WINKEL(360-winkel)); p2.translate_im_global(0,0,-5); //p3.translate_im_global(0,0,5); p4.translate_im_global(0,0,15); p4.rotate_im_g_x(WINKEL(winkel)); p4.rotate_im_g_y(WINKEL(winkel)); p4.translate_im_global(0,0,5); cam.translate_im_global(0,0,-60); cam.rotate_im_g_y(WINKEL(-cam_winkel)); cam.rotate_im_axis(WINKEL(cam_winkel), vertex(1,0,1,COORD), vertex(0,0,0,COORD)); li.translate_im_global(0,0,-10); li.rotate_im_g_y(WINKEL(45.0)); li.rotate_im_axis(WINKEL(li_winkel), vertex(1,0,-1,COORD), vertex(0,0,0,COORD)); li2.translate_im_global(0,0,-10); li2.rotate_im_g_x(WINKEL(li2_winkel)); Mmn ctm(cam.cam_trans_mat()); p.move_im(ctm); p2.move_im(ctm); p3.move_im(ctm); p4.move_im(ctm); li.move_im(ctm); li2.move_im(ctm); /* p.transform(1); p2.transform(1); p3.transform(1); p4.transform(1); cam.transform(1); */ // Zu Anfang reicht es die Vertexe für die Objektposition und // die Normalenvertexe zu transformieren, dann kommt das // backface culling und nur wenn ein polygon wirklich gezeichnet // wird mache ich die letzten transformationen und die // projektion. p.transform_normals(1); p2.transform_normals(1); p3.transform_normals(1); p4.transform_normals(1); p.movable::transform(1); p2.movable::transform(1); p3.movable::transform(1); p4.movable::transform(1); li.transform(1); li2.transform(1); /* p.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); p2.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); p3.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); p4.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); */ // Ich muss nach einem verdammt guten Weg suchen herauszufinden // zu welchem polyeder ein polygon gehoert, ich denke das beste ist // einen pointer auf den polyeder im polygon zu speichern wenn // es einem polyeder zugeordnet wird. vertex view, normal, center, norm_v; for(unsigned i=0; iclear_buffer(); double normal_X[6]; double normal_Y[6]; for(unsigned i=0; i= 0) { unsigned long col; vertex center=po_list[i].center_p(); vertex normal=po_list[i].normal_p(); vertex norm_v=normal-center; if(idx==1) col=scr->get_color(0,0,255); else col=scr->get_color(0,255,255); vertex light(li.get_direction()); unsigned in=0, in_tmp; double intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li.get_intensity()); in=in_tmp>in?in_tmp:in; light=li2.get_direction(); intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li2.get_intensity()); in=in_tmp>in?in_tmp:in; in_tmp=(unsigned)(li3.get_intensity()); in=in_tmp>in?in_tmp:in; scr->light_native(&col, in); if(po_list_zclipped[i].card() >= 3) { po_list_zclipped[i].project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); ras->draw_polygon_flat(po_list_zclipped[i], col); } } if((idx=p4.contains(po_list[i])) >= 0) { unsigned long col=scr->get_color(0,0,255); vertex center=po_list[i].center_p(); vertex normal=po_list[i].normal_p(); vertex norm_v=normal-center; vertex light(li.get_direction()); unsigned in=0, in_tmp; double intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li.get_intensity()); in=in_tmp>in?in_tmp:in; light=li2.get_direction(); intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li2.get_intensity()); in=in_tmp>in?in_tmp:in; in_tmp=(unsigned)(li3.get_intensity()); in=in_tmp>in?in_tmp:in; scr->light_native(&col, in); if(po_list_zclipped[i].card() >= 3) { po_list_zclipped[i].project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); ras->draw_polygon_flat(po_list_zclipped[i], col); //ras->draw_polygon_wire(po_list_zclipped[i], // scr->get_color(255, 255, 255)); } } if((idx=p.contains(po_list[i])) >= 0) { unsigned long col=scr->get_color(255,0,0); vertex center=po_list[i].center_p(); vertex normal=po_list[i].normal_p(); vertex norm_v=normal-center; vertex light(li.get_direction()); unsigned in=0, in_tmp; double intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li.get_intensity()); in=in_tmp>in?in_tmp:in; light=li2.get_direction(); intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li2.get_intensity()); in=in_tmp>in?in_tmp:in; in_tmp=(unsigned)(li3.get_intensity()); in=in_tmp>in?in_tmp:in; scr->light_native(&col, in); center.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), center.get_trans_stage()+1); normal.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), center.get_trans_stage()+1); if(po_list_zclipped.card() >= 3) { po_list_zclipped[i].project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); ras->draw_polygon_flat(po_list_zclipped[i], col); //ras->draw_polygon_wire(po_list_zclipped[i], // scr->get_color(255, 255, 255)); ras->line(center[X], center[Y], normal[X], normal[Y], scr->get_color(0, 0, 0)); } } if((idx=p2.contains(po_list[i])) >= 0) { unsigned long col=scr->get_color(0,255,0); vertex center=po_list[i].center_p(); vertex normal=po_list[i].normal_p(); vertex norm_v=normal-center; vertex light(li.get_direction()); unsigned in=0, in_tmp; double intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li.get_intensity()); in=in_tmp>in?in_tmp:in; light=li2.get_direction(); intense=(norm_v.norm()%light.norm())*-1; intense=intense<0.02?0.02:intense; intense=intense>1.0?1.0:intense; in_tmp=(unsigned)(intense*li2.get_intensity()); in=in_tmp>in?in_tmp:in; in_tmp=(unsigned)(li3.get_intensity()); in=in_tmp>in?in_tmp:in; scr->light_native(&col, in); center.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), center.get_trans_stage()+1); normal.project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), center.get_trans_stage()+1); if(po_list_zclipped[i].card() >= 3) { po_list_zclipped[i].project_2d(cam.get_lcx(), cam.get_sw(), cam.get_sh(), cam.get_ph_ar(), cam.get_sy(), 2); ras->draw_polygon_flat(po_list_zclipped[i], col); //ras->draw_polygon_wire(po_list_zclipped[i], // scr->get_color(255, 255, 255)); ras->line(center[X], center[Y], normal[X], normal[Y], scr->get_color(0, 0, 0)); } } } //ras->draw_polyeder_wire(p, scr->get_color(255,255,255)); //ras->draw_polyeder_wire(p2, scr->get_color(255,255,255)); p.reset(); p2.reset(); p3.reset(); p4.reset(); cam.reset(); li.reset(); li2.reset(); ftime(&tb2); secs_tmp=tb2.time-tb1.time; ms=(secs_tmp*1000+tb2.millitm)-tb1.millitm; secs=(secs_tmp>0)?ms/(secs_tmp*1000):0; ms=(secs_tmp>0)?ms%(secs_tmp*1000):ms; d->trigger_event(Draw); } public: /** * \brief Konstruktor * * Alle Grundlegenden Initialisierungen. Canvas, Dispatcher und * Rasterizer erzeugen. Callbacks registrieren und * Polyeder erzeugen. Eckwerte für die 2D-Projektion festlegen. */ app() { // Der factory_manager erzeugt mir den gewünschten // Canvas und Dispatcher. factory_manager f; // Erzeuge den Canvas, Dispatcher und Rasterizer scr=f.canvas_f->create(400, 300); d=f.dispatcher_f->create(scr); ras=scr->create_rasterizer(); // Registriere die Callbacks und trage Dispatcher in Manager ein d->register_callback(Key, mk_callback(*this, &app::exitOnEsc)); d->register_callback(Idle, mk_callback(*this, &app::rotate)); d->register_callback(Draw, mk_callback(*this, &app::redraw)); manager[0]=d; d->register_callback(Stop, mk_callback(manager, &disp_manager::stop)); // Dann wolln wir die cam mal initilisieren. cam=camera(*ras, 50.0); li2.set_intensity(127); li3.set_intensity(40); // zuerst werden alle nötigen Vertexe erzeugt vertex v[]={vertex(5,5,5,1), vertex(5,-5,5,1), vertex(-5,-5,5,1), vertex(-5,5,5,1), vertex(5,5,-5,1), vertex(5,-5,-5,1), vertex(-5,-5,-5,1), vertex(-5,5,-5,1)}; // und in einer Vertexliste gespeicher. vertex_list vl(v, 8); // ein Hilfsarray erzeugt um damit unsigned v_idx[][4]={{3,2,1,0}, // hinten {0,1,5,4}, // rechts {4,5,6,7}, // vorne {7,6,2,3}, // links {4,0,3,7}, // oben {1,5,6,2}}; // unten // die Polygone zu definieren. // (Der letzte Parameter ist die Vertexliste die das Polygon // nutzen soll. Hier kann ich NULL nehmen, da sie beim erzeugen // der Polyeders auf dessen Vertexliste gesetzt werden. // (siehe unten)) /*polygon_movable pa[]={ polygon_movable((unsigned*)v_idx[0], 4, NULL), polygon_movable((unsigned*)v_idx[1], 4, NULL), polygon_movable((unsigned*)v_idx[2], 4, NULL), polygon_movable((unsigned*)v_idx[3], 4, NULL), polygon_movable((unsigned*)v_idx[4], 4, NULL), polygon_movable((unsigned*)v_idx[5], 4, NULL)};*/ polygon pa[]={ polygon((unsigned*)v_idx[0], 4, NULL), polygon((unsigned*)v_idx[1], 4, NULL), polygon((unsigned*)v_idx[2], 4, NULL), polygon((unsigned*)v_idx[3], 4, NULL), polygon((unsigned*)v_idx[4], 4, NULL), polygon((unsigned*)v_idx[5], 4, NULL)}; // Jetzt definieren wir mit der oben erzeugten Vertexlist und // dem Array aus Polygonen 2 Polyeder, die wir beide vom // Ursprung auf der Z-Achse weg bewegen. p=polyeder(pa, 6, vl); p2=polyeder(pa, 6, vl); p4=polyeder(pa, 6, vl); p[2].set_id("DEBUG"); cout << "BLA: " << p[2].get_id() << "\n"; polygon pa3[]={polygon((unsigned*)v_idx[0], 4, NULL), polygon((unsigned*)v_idx[2], 4, NULL)}; p3=polyeder(pa3, 2, vl); winkel=0; stepping=0; cam_winkel=0; cam_stepping=0; li_winkel=WINKEL(-45.0); li_stepping=0; li2_winkel=WINKEL(90.0); li2_stepping=0; clip_front=0; //halt=false; } /** * \brief Destruktor * * freigeben und entfernen alles dynamisch erzeugten Elemente. */ ~app() { delete ras; delete d; delete scr; } /** * \brief startet den Manager und damit das Programm. */ void go(void) { manager.start(); } }; int main(int argc, char* argv[]) { app a; a.go(); // cout << "jokus\n"; return 0; } #endif