// (c) Dinko Korunic, 36355514, kreator@fly.srk.fer.hr // Zadatak broj 8-1 iz predmeta Racunalna grafika #include #include #include #include #include #include #define MAXX 640 // max x #define MAXY 480 // max y #define LPOB 8 // modifikator #define DINT 60 // zbraja intenzitetu #define MINT 1.5 // mnozi intenzitet #define MYSTEP 0.01 // stepping #define MYSLEEP 1 // sleeping time class MyDisplay { // klasa MyDisplay u kojoj se nalaze inicijalizacijske xlib // rutine, kao i postavljanje background i foreground boje, itd. XGCValues gcv; unsigned long wp, bp; int winx, winy; public: Display *disp; Window win; GC gc; XEvent ev; void MyWait(void); int winsx, winsy, screen; MyDisplay(int _winx, int _winy, int _winsx, int _winsy); ~MyDisplay(); }; MyDisplay::MyDisplay(int _winx=0, int _winy=0, int _winsx=MAXX, int _winsy=MAXY) : winx(_winx), winy(_winy), winsx(_winsx), winsy(_winsy) { // konstruktor koji sluzi za misc. inicijalizaciju cout << "Initialising graphic subsystem.." << endl; // otvaranje displaya if ((disp=XOpenDisplay(NULL))==NULL) { cerr << "I can't open display." << endl; exit(EXIT_FAILURE); } screen=DefaultScreen(disp); // stvaranje prototipnog prozora win=XCreateSimpleWindow(disp, DefaultRootWindow(disp), winx, winy, winsx, winsy, 1, wp=WhitePixel(disp, screen), bp=BlackPixel(disp, screen)); XSelectInput(disp, win, StructureNotifyMask | KeyPressMask | ExposureMask); // mapiranje prozora XMapWindow(disp, win); while(1) { // cekaj dok nije gotovo XNextEvent(disp, &ev); if (ev.type==MapNotify) break; } gcv.foreground=wp; gcv.background=bp; // stvori gc gc=XCreateGC(disp, win, GCForeground | GCBackground, &gcv); cout << "done." << endl; } MyDisplay::~MyDisplay() { // destruktor za graficki engine cout << "Shutting graphic subsystem.." << endl; XFreeGC(disp, gc); XDestroyWindow(disp, win); XCloseDisplay(disp); cout << "done." << endl; } void MyDisplay::MyWait(void) { // postavi wait na keypress XSelectInput(disp, win, KeyPressMask | ExposureMask); while(1) { XNextEvent(disp, &ev); if (ev.type==KeyPress) break; } } // vrh poligona struct Vrh { int x, y, z; // koordinate u sustavu scene double xo, yo, zo; // koordinate u sustavu oka int xp, yp, // koordinate prikaza intenzitet; // intenzitet u vrhu double vx, vy, vz; // komponente vektora koji izvire iz vrha }; // struktura u koju se ucitavaju vrhovi tijela struct Matrica { int t, // broj vrhova po katu k, // broj katova boja; Vrh **Mat; // matrica od k redaka i t stupaca }; // poligon struct Poligon { int n, // broj vrhova poligona boja, // boja 0-crvena 1-zelena 2-plava 3-siva vidljivost; float A, B, C, D; // koeficijenti ranvine u kojoj lezi poligon Vrh **Polje; // polje vrhova poligona orijentirano u smjeru // kazaljke na satu }; class MiscDraw : public MyDisplay { Colormap cmap; XColor xcolor, colorcell; int darkcolor, lightcolor, black, white; public: XImage *image; long translate[4]; /* for converting colors */ MiscDraw(); }; MiscDraw::MiscDraw() { cmap=DefaultColormap(disp, screen); if (XAllocNamedColor(disp, cmap, "red", &colorcell, &xcolor)) translate[0]=colorcell.pixel; if (XAllocNamedColor(disp, cmap, "green", &colorcell, &xcolor)) translate[1]=colorcell.pixel; if (XAllocNamedColor(disp, cmap, "blue", &colorcell, &xcolor)) translate[2]=colorcell.pixel; if (XAllocNamedColor(disp, cmap, "grey", &colorcell, &xcolor)) translate[3]=colorcell.pixel; image=XGetImage(disp, win, 0, 0, MAXX, MAXY, AllPlanes, ZPixmap); } class MyDraw8 : public MiscDraw { Matrica MyMatrica; // za smjestaj vrhova Poligon *PoljePoligona; // polje ciji elementi su strukture koje // sadrzavaju poligone int BrojPoligona, // sadrzi broj poligona od kojih je // sastavljeno tijelo rx[4], ry[4], rz[4]; Vrh Ociste, Glediste, Izvor; void Input(Matrica *); void DajIntenzitet(Vrh *); void OdrediVidljivost(Poligon *); void PridodajVrh(Poligon *); void IzracunajRavninu(Poligon *); void Topologija(Matrica *, Poligon *); void TransformirajPogled(Vrh *); void Projekcija(Vrh *); void PridodajVrhovima(Poligon *); double B(int, double); int Bezier(int *, double); public: MyDraw8(); }; MyDraw8::MyDraw8() { Input(&MyMatrica); PoljePoligona=new Poligon[BrojPoligona=2+MyMatrica.t*(MyMatrica.k-1)]; // popunjavamo polje poligona sa svim potrebnim poligonima Topologija(&MyMatrica, PoljePoligona); for (double bz=0; bz<=1; bz+=MYSTEP) { Ociste.x=Bezier(rx,bz); Ociste.y=Bezier(ry,bz); Ociste.z=Bezier(rz,bz); int i, j; // idemo po svim vrhovima i radimo transformacije for (i=0; i