//----------------------------------------------------------------------------- // Velmi jednoduchy prohlizec souboru typu DXF upraveny pro zobrazeni // zakladnich 3D entit - 3DFACE // // Autor: Pavel Tisnovsky // //----------------------------------------------------------------------------- #ifdef __BORLANDC__ #include #endif #include // hlavickovy soubor funkci GLUTu a OpenGL #include #include #include #include #include #define WINDOW_TITLE "simple DXF 3D viewer" // titulek okna #define WINDOW_WIDTH 800 // pocatecni velikost okna #define WINDOW_HEIGHT 600 #define MAX_LINE_LENGTH 1024 #define MAX_TEXT_LENGTH 256 void callback_begin_header(char *input); void callback_end_header(char *input); void callback_begin_blocks(char *input); void callback_end_blocks(char *input); void callback_begin_entities(char *input); void callback_end_entities(char *input); void callback_3dface_setcolor(char *input); void callback_3dface_setlayer(char *input); void callback_3dface_set_x1(char *input); void callback_3dface_set_y1(char *input); void callback_3dface_set_z1(char *input); void callback_3dface_set_x2(char *input); void callback_3dface_set_y2(char *input); void callback_3dface_set_z2(char *input); void callback_3dface_set_x3(char *input); void callback_3dface_set_y3(char *input); void callback_3dface_set_z3(char *input); void callback_3dface_set_x4(char *input); void callback_3dface_set_y4(char *input); void callback_3dface_set_z4(char *input); void callback_3dface_color(char *input); void callback_3dface_layer(char *input); void callback_3dface_x1(char *input); void callback_3dface_y1(char *input); void callback_3dface_z1(char *input); void callback_3dface_x2(char *input); void callback_3dface_y2(char *input); void callback_3dface_z2(char *input); void callback_3dface_x3(char *input); void callback_3dface_y3(char *input); void callback_3dface_z3(char *input); void callback_3dface_x4(char *input); void callback_3dface_y4(char *input); void callback_3dface_z4(char *input); void callback_3dface_store(char *input); // graficke entity {{{ typedef struct Gfx3Dface { int color; int layer; double x1; double y1; double z1; double x2; double y2; double z2; double x3; double y3; double z3; double x4; double y4; double z4; } Gfx3Dface; // }}} // linearni seznam s entitami {{{ typedef struct Item { Gfx3Dface *entity; struct Item *next; // vazba v linearnim seznamu } Item; // }}} // stavy KA {{{ typedef enum t_dxf_status { Unknown, Delimiter, Section, SecName, Header, Blocks, Entities, Face, FaceLayer, FaceColor, FaceX1, FaceY1, FaceZ1, FaceX2, FaceY2, FaceZ2, FaceX3, FaceY3, FaceZ3, FaceX4, FaceY4, FaceZ4, End } t_dxf_status; // }}} // prechod mezi stavy KA {{{ typedef struct t_transition { t_dxf_status status; char *input; t_dxf_status newStatus; void (*fce)(char *input); } t_transition; // }}} // vlastni konfigurace KA {{{ static const t_transition transitions[]={ {Unknown, " 0", Delimiter, NULL}, {Delimiter, "SECTION", Section, NULL}, {Section, " 2", SecName, NULL}, {SecName, "HEADER", Header, callback_begin_header}, {SecName, "BLOCKS", Blocks, callback_begin_blocks}, {SecName, "ENTITIES", Entities, callback_begin_entities}, {Header, " 0", Header, NULL}, {Header, "ENDSEC", Unknown, callback_end_header}, {Blocks, " 0", Blocks, NULL}, {Blocks, "ENDSEC", Unknown, callback_end_blocks}, {Entities, " 0", Entities, NULL}, {Entities, "ENDSEC", Unknown, callback_end_entities}, {Entities, "3DFACE", Face, NULL}, {Face, " 8", FaceLayer, callback_3dface_layer}, {Face, " 62", FaceColor, callback_3dface_color}, {Face, " 10", FaceX1, callback_3dface_x1}, {Face, " 20", FaceY1, callback_3dface_y1}, {Face, " 30", FaceZ1, callback_3dface_z1}, {Face, " 11", FaceX2, callback_3dface_x2}, {Face, " 21", FaceY2, callback_3dface_y2}, {Face, " 31", FaceZ2, callback_3dface_z2}, {Face, " 12", FaceX3, callback_3dface_x3}, {Face, " 22", FaceY3, callback_3dface_y3}, {Face, " 32", FaceZ3, callback_3dface_z3}, {Face, " 13", FaceX4, callback_3dface_x4}, {Face, " 23", FaceY4, callback_3dface_y4}, {Face, " 33", FaceZ4, callback_3dface_z4}, {Face, " 0", Entities, callback_3dface_store}, {End, "", End, NULL} // jen ukonceni pro pruchod stavy KA }; // }}} // informace o okne {{{ struct { int width; int height; } window={WINDOW_WIDTH, WINDOW_HEIGHT}; // }}} // informace o mysi {{{ enum { // operace, ktere se mohou provadet s mysi: ROTATE, // rotace objektu TRANSLATE, // posun objektu } operation=ROTATE; int xnew=0, ynew=0, znew=20; // soucasna pozice mysi, ze ktere se pocitaji rotace a posuvy int xold=0, yold=0, zold=20; // minula pozice mysi, ze ktere se pocitaji rotace a posuvy int xx, yy, zz; // bod, ve kterem se nachazi kurzor mysi // }}} // globalni promenne {{{ // parametry, ktere ovlivnuji osvetleni GLfloat materialAmbient[]={0.4f, 0.4f, 0.4f, 1.0f}; // ambientni slozka barvy materialu GLfloat materialDiffuse[]={0.8f, 0.4f, 0.4f, 1.0f}; // difuzni slozka barvy materialu GLfloat materialSpecular[]={1.0f, 1.0f, 1.0f, 1.0f}; // barva odlesku GLfloat materialShininess[]={50.0f}; // faktor odlesku GLfloat light_position1[]={1.0f, 0.0f, 1.0f, 1.0f}; // pozice prvniho svetla GLfloat light_position2[]={0.0f, 1.0f,100.0f, 1.0f}; // pozice druheho svetla GLfloat light_color1[]={1.0f, 1.0f, 1.0f}; // barva prvniho svetla GLfloat light_color2[]={1.0f, 1.0f, 0.0f}; // barva druheho svetla int redraw=1; void (*special_callback)(char *input)=NULL; t_dxf_status status=Unknown; // inicializace KA Item *p_first; // ukazatele v linearnim seznamu Item *p_last; Gfx3Dface g_face; // pomocne entity pro postupne naplnovani int colorStyle=1; // }}} // initItem() {{{ //----------------------------------------------------------------------------- // Inicializace linearniho seznamu //----------------------------------------------------------------------------- void initItem(void) { p_first=NULL; p_last=NULL; } // }}} // addItem() {{{ //----------------------------------------------------------------------------- // Vlozeni polozky do linearniho seznamu //----------------------------------------------------------------------------- void addItem(Gfx3Dface *entity) { Item *item=(Item*)malloc(sizeof(Item)); item->entity=entity; item->next=NULL; // prvek bude umisten na konci seznamu // seznam je prazdny if (p_first==NULL) { p_first=item; // prvni i posledni prvek p_last=item; // seznamu jsou shodne } // pridani polozky do neprazdneho seznamu else { p_last->next=item; // zretezeni prvku na konec seznamu p_last=item; // aktualizace ukazatele na posledni prvek /* Item *p=p_first; while (p->next !=NULL) p=p->next; p->next=item; */ } } // }}} // callback_begin_header() {{{ void callback_begin_header(char *input) { puts(" begin header"); } // }}} // callback_end_header() {{{ void callback_end_header(char *input) { puts(" end header"); } // }}} // callback_begin_blocks() {{{ void callback_begin_blocks(char *input) { puts(" begin blocks"); } // }}} // callback_end_blocks() {{{ void callback_end_blocks(char *input) { puts(" end blocks"); } // }}} // callback_begin_entities() {{{ void callback_begin_entities(char *input) { puts(" begin entities"); } // }}} // callback_end_entities() {{{ void callback_end_entities(char *input) { puts(" end entities"); } // }}} // callback_3dface_setcolor() {{{ void callback_3dface_setcolor(char *input) { g_face.color=atoi(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_setlayer() {{{ void callback_3dface_setlayer(char *input) { int i, j; // velmi primitivni vypocet hashe for (i=0, j=0; input[i]; i++) j+=input[i]; g_face.layer=j; special_callback=NULL; status=Face; } // }}} // callback_3dface_set_x1() {{{ void callback_3dface_set_x1(char *input) { g_face.x1=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_y1() {{{ void callback_3dface_set_y1(char *input) { g_face.y1=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_z1() {{{ void callback_3dface_set_z1(char *input) { g_face.z1=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_x2() {{{ void callback_3dface_set_x2(char *input) { g_face.x2=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_y2() {{{ void callback_3dface_set_y2(char *input) { g_face.y2=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_z2() {{{ void callback_3dface_set_z2(char *input) { g_face.z2=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_x3() {{{ void callback_3dface_set_x3(char *input) { g_face.x3=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_y3() {{{ void callback_3dface_set_y3(char *input) { g_face.y3=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_z3() {{{ void callback_3dface_set_z3(char *input) { g_face.z3=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_x4() {{{ void callback_3dface_set_x4(char *input) { g_face.x4=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_y4() {{{ void callback_3dface_set_y4(char *input) { g_face.y4=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_set_z4() {{{ void callback_3dface_set_z4(char *input) { g_face.z4=atof(input); special_callback=NULL; status=Face; } // }}} // callback_3dface_color() {{{ void callback_3dface_color(char *input) { special_callback=callback_3dface_setcolor; } // }}} // callback_3dface_layer() {{{ void callback_3dface_layer(char *input) { special_callback=callback_3dface_setlayer; } // }}} // callback_3dface_x1() {{{ void callback_3dface_x1(char *input) { special_callback=callback_3dface_set_x1; } // }}} // callback_3dface_y1() {{{ void callback_3dface_y1(char *input) { special_callback=callback_3dface_set_y1; } // }}} // callback_3dface_z1() {{{ void callback_3dface_z1(char *input) { special_callback=callback_3dface_set_z1; } // }}} // callback_3dface_x2() {{{ void callback_3dface_x2(char *input) { special_callback=callback_3dface_set_x2; } // }}} // callback_3dface_y2() {{{ void callback_3dface_y2(char *input) { special_callback=callback_3dface_set_y2; } // }}} // callback_3dface_z2() {{{ void callback_3dface_z2(char *input) { special_callback=callback_3dface_set_z2; } // }}} // callback_3dface_x3() {{{ void callback_3dface_x3(char *input) { special_callback=callback_3dface_set_x3; } // }}} // callback_3dface_y3() {{{ void callback_3dface_y3(char *input) { special_callback=callback_3dface_set_y3; } // }}} // callback_3dface_z3() {{{ void callback_3dface_z3(char *input) { special_callback=callback_3dface_set_z3; } // }}} // callback_3dface_x4() {{{ void callback_3dface_x4(char *input) { special_callback=callback_3dface_set_x4; } // }}} // callback_3dface_y4() {{{ void callback_3dface_y4(char *input) { special_callback=callback_3dface_set_y4; } // }}} // callback_3dface_z4() {{{ void callback_3dface_z4(char *input) { special_callback=callback_3dface_set_z4; } // }}} // callback_3dface_store() {{{ void callback_3dface_store(char *input) { Gfx3Dface *g=(Gfx3Dface *)malloc(sizeof(Gfx3Dface)); g->x1=g_face.x1; g->y1=g_face.y1; g->z1=g_face.z1; g->x2=g_face.x2; g->y2=g_face.y2; g->z2=g_face.z2; g->x3=g_face.x3; g->y3=g_face.y3; g->z3=g_face.z3; g->x4=g_face.x4; g->y4=g_face.y4; g->z4=g_face.z4; g->color=g_face.color; g->layer=g_face.layer; addItem(g); } // }}} // doConvert() {{{ // --------------------------------------------------------------------- // Nacteni obsahu souboru DXF a konverze do internich datovych struktur // --------------------------------------------------------------------- int doConvert(char *fileName) { #define MIN 1e-10 #define MAX 1e+10 // makra pro zjisteni maxima a minima #define SET_MIN(a, min) if ((a)<(min)) (min)=(a) #define SET_MAX(a, max) if ((a)>(max)) (max)=(a) FILE *fin; char line[MAX_LINE_LENGTH]; int lines=0; int t; Item *item; double xmin=MAX, xmax=MIN, ymin=MAX, ymax=MIN, zmin=MAX, zmax=MIN; double x0, y0, z0; fin=fopen(fileName, "rt"); // otevreni vstupniho souboru if (!fin) return 0; while (fgets(line, MAX_LINE_LENGTH, fin)) { // projit vsechny radky lines++; line[strlen(line)-1]=0; // oriznout if (special_callback!=NULL) { // specialni callback funkce -> nacteni atributu special_callback(line); } else { // normalni callback funkce -> prechod KA for (t=0; transitions[t].status!=End; t++) { if ((status==transitions[t].status) && (!strcmp(transitions[t].input, line))) { if (transitions[t].fce!=NULL) transitions[t].fce(line); status=transitions[t].newStatus; break; } } } } printf("done %d lines\n", lines); fclose(fin); // uprava stredu 3D modelu item=p_first; while (item!=NULL) { SET_MIN(item->entity->x1, xmin); SET_MAX(item->entity->x1, xmax); SET_MIN(item->entity->x2, xmin); SET_MAX(item->entity->x2, xmax); SET_MIN(item->entity->x3, xmin); SET_MAX(item->entity->x3, xmax); SET_MIN(item->entity->x4, xmin); SET_MAX(item->entity->x4, xmax); SET_MIN(item->entity->y1, ymin); SET_MAX(item->entity->y1, ymax); SET_MIN(item->entity->y2, ymin); SET_MAX(item->entity->y2, ymax); SET_MIN(item->entity->y3, ymin); SET_MAX(item->entity->y3, ymax); SET_MIN(item->entity->y4, ymin); SET_MAX(item->entity->y4, ymax); SET_MIN(item->entity->z1, zmin); SET_MAX(item->entity->z1, zmax); SET_MIN(item->entity->z2, zmin); SET_MAX(item->entity->z2, zmax); SET_MIN(item->entity->z3, zmin); SET_MAX(item->entity->z3, zmax); SET_MIN(item->entity->z4, zmin); SET_MAX(item->entity->z4, zmax); item=item->next; } printf("Boundary: [%f, %f, %f] - [%f, %f, %f]\n", xmin, ymin, zmin, xmax, ymax, zmax); // vypocet stredu objektu x0=(xmax+xmin)/2.0; y0=(ymax+ymin)/2.0; z0=(zmax+zmin)/2.0; printf("Center: [%f, %f, %f]\n", x0, y0, z0); // vycentrovani obrazku item=p_first; while (item!=NULL) { item->entity->x1-=x0; item->entity->x2-=x0; item->entity->x3-=x0; item->entity->x4-=x0; item->entity->y1-=y0; item->entity->y2-=y0; item->entity->y3-=y0; item->entity->y4-=y0; item->entity->z1-=z0; item->entity->z2-=z0; item->entity->z3-=z0; item->entity->z4-=z0; item=item->next; } return 1; } // }}} // setColor() {{{ //----------------------------------------------------------------------------- // nastaveni barvy vykreslovani //----------------------------------------------------------------------------- void setColor(int color) { // velmi zjednodusena paleta static float palette[][3]={ {1.0, 1.0, 1.0}, {0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}, {0.0, 1.0, 1.0}, {1.0, 0.0, 0.0}, {1.0, 0.0, 1.0}, {1.0, 1.0, 0.0}, {0.5, 0.5, 0.5}, }; float r, g, b; r=palette[color & 0x07][0]; g=palette[color & 0x07][1]; b=palette[color & 0x07][2]; glColor3f(r, g, b); } // }}} // setPerspectiveProjection() {{{ //--------------------------------------------------------------------- // Nastaveni perspektivni projekce //--------------------------------------------------------------------- void setPerspectiveProjection(void) { glMatrixMode(GL_PROJECTION); // zacatek modifikace projekcni matice glLoadIdentity(); // vymazani projekcni matice (=identita) gluPerspective(70.0, (double)window.width/(double)window.height, 0.1f, 10000.0f);// nastaveni perspektivni kamery glMatrixMode(GL_MODELVIEW); // bude se menit modelova matice glLoadIdentity(); // nahrat jednotkovou matici } // }}} // drawFace() {{{ //----------------------------------------------------------------------------- // vykresleni entity 3D face //----------------------------------------------------------------------------- void drawFace(Gfx3Dface *g) { if (colorStyle) setColor(g->color); else setColor(g->layer); glBegin(GL_TRIANGLES); glVertex3d(g->x1, g->y1, g->z1); glVertex3d(g->x2, g->y2, g->z2); glVertex3d(g->x3, g->y3, g->z3); glVertex3d(g->x1, g->y1, g->z1); glVertex3d(g->x3, g->y3, g->z3); glVertex3d(g->x4, g->y4, g->z4); glEnd(); } // }}} // redrawDrawing() {{{ //----------------------------------------------------------------------------- // Prekresleni vektorove kresby //----------------------------------------------------------------------------- void redrawDrawing() { Item *item=p_first; // projit celym seznamem a aplikovat v nem ulozene prikazy while (item!=NULL) { drawFace(item->entity); item=item->next; } } // }}} // onInit() {{{ //----------------------------------------------------------------------------- // Funkce volana pro inicializaci vykreslovani //----------------------------------------------------------------------------- void onInit(void) { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // barva pozadi obrazku glClearDepth(1.0f); // implicitni hloubka ulozena v pameti hloubky glDepthFunc(GL_LESS); // funkce pro testovani fragmentu glShadeModel(GL_SMOOTH); // nastaveni stinovaciho rezimu glPolygonMode(GL_FRONT, GL_FILL); // nastaveni rezimu vykresleni modelu glPolygonMode(GL_BACK, GL_FILL); // jak pro predni tak pro zadni steny glDisable(GL_CULL_FACE); // zadne hrany ani steny se nebudou odstranovat glMaterialfv(GL_FRONT, GL_AMBIENT, materialAmbient); // nastaveni ambientni slozky barvy materialu glMaterialfv(GL_FRONT, GL_DIFFUSE, materialDiffuse); // nastaveni difuzni slozky barvy materialu glMaterialfv(GL_FRONT, GL_SPECULAR, materialSpecular); // nastaveni barvy odlesku glMaterialfv(GL_FRONT, GL_SHININESS, materialShininess);// nastaveni faktoru odlesku glLightfv(GL_LIGHT0, GL_POSITION, light_position1); // nastaveni pozice prvniho svetla glLightfv(GL_LIGHT1, GL_POSITION, light_position2); // nastaveni pozice druheho svetla glLightfv(GL_LIGHT0, GL_DIFFUSE, light_color1); // nastaveni barvy prvniho svetla glLightfv(GL_LIGHT1, GL_DIFFUSE, light_color2); // nastaveni barvy druheho svetla glEnable(GL_LIGHTING); // globalni povoleni stinovani glEnable(GL_LIGHT0); // povoleni prvniho svetla glEnable(GL_LIGHT1); // povoleni prvniho svetla } // }}} // onResize() {{{ //----------------------------------------------------------------------------- // Nastaveni souradneho systemu v zavislosti na velikosti okna //----------------------------------------------------------------------------- void onResize(int w, int h) // argumenty w a h reprezentuji novou velikost okna { glViewport(0, 0, w, h); // viditelna oblast pres cele okno window.width=w; window.height=h; } // }}} // onDisplay() {{{ //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri kazdem prekresleni okna //----------------------------------------------------------------------------- void onDisplay(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // vymazani vsech bitovych rovin barvoveho bufferu setPerspectiveProjection(); // nastaveni perspektivni kamery glTranslatef(0.0f, 0.0f, -50.0f); // posun objektu dale od kamery glTranslatef(0.0f, 0.0f, znew); // priblizeni ci vzdaleni objektu podle pohybu kurzoru mysi glRotatef(ynew, 1.0f, 0.0f, 0.0f); // rotace objektu podle pohybu kurzoru mysi glRotatef(xnew, 0.0f, 1.0f, 0.0f); // glScalef(0.1, 0.1, 0.1); //glPushMatrix(); // ulozeni matice na zasobnik a zmena pozice druheho svetla //glLightfv(GL_LIGHT1, GL_POSITION, light_position2); //glPopMatrix(); redrawDrawing(); // vykresleni objektu glFlush(); // provedeni a vykresleni vsech zmen glutSwapBuffers(); // a prohozeni predniho a zadniho bufferu } // }}} // onKeyboard() {{{ //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri stlaceni ASCII klavesy //----------------------------------------------------------------------------- #ifdef __BORLANDC__ #pragma option -w-par #endif void onKeyboard(unsigned char key, int x, int y) { key=(key>='A' && key<='Z') ? key-'A'+'a': key; if (key>='0' && key<='9') { glutPostRedisplay(); } // nastaveni barvove palety switch (key) { case 27: // pokud byla stlacena klavesa ESC, konec programu case 'q': exit(0); break; // totez co klavesa ESC case 'l': colorStyle=0; glutPostRedisplay(); break; // barvy podle hashe hladiny case 'c': colorStyle=1; glutPostRedisplay(); break; // barvy podle informaci z DXF case '1': glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); glutPostRedisplay(); break; case '2': glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glutPostRedisplay(); break; case '3': glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glutPostRedisplay(); break; case '4': glEnable(GL_DEPTH_TEST); glutPostRedisplay(); break; case '5': glDisable(GL_DEPTH_TEST); glutPostRedisplay(); break; case '6': glEnable(GL_LIGHTING); glutPostRedisplay(); break; case '7': glDisable(GL_LIGHTING); glutPostRedisplay(); break; default: break; } } #ifdef __BORLANDC__ #pragma option -w+par #endif // }}} // onSpecial() {{{ //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri stlaceni non-ASCII klavesy //----------------------------------------------------------------------------- #ifdef __BORLANDC__ #pragma option -w-par #endif void onSpecial(int key, int x, int y) { // posun kresby a zmena meritka switch (key) { /* case GLUT_KEY_LEFT: xpos-=25; redraw=1; glutPostRedisplay(); break; case GLUT_KEY_RIGHT: xpos+=25; redraw=1; glutPostRedisplay(); break; case GLUT_KEY_UP: ypos+=25; redraw=1; glutPostRedisplay(); break; case GLUT_KEY_DOWN: ypos-=25; redraw=1; glutPostRedisplay(); break; case GLUT_KEY_PAGE_UP: scale*=1.1; redraw=1; glutPostRedisplay(); break; case GLUT_KEY_PAGE_DOWN: scale/=1.1; redraw=1; glutPostRedisplay(); break;*/ default: break; } } #ifdef __BORLANDC__ #pragma option -w+par #endif // }}} // onMouse() {{{ //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri stlaceni ci pusteni tlacitka mysi //----------------------------------------------------------------------------- void onMouse(int button, int state, int x, int y) { if (button==GLUT_LEFT_BUTTON) { // pri zmene stavu leveho tlacitka operation=ROTATE; if (state==GLUT_DOWN) { // pri stlaceni tlacitka xx=x; // zapamatovat pozici kurzoru mysi yy=y; } else { // pri pusteni tlacitka xold=xnew; // zapamatovat novy pocatek yold=ynew; } glutPostRedisplay(); // prekresleni sceny } if (button==GLUT_RIGHT_BUTTON) { operation=TRANSLATE; if (state==GLUT_DOWN) zz=y; // pri stlaceni tlacitka zapamatovat polohu kurzoru mysi else zold=znew; // pri pusteni tlacitka zapamatovat novy pocatek glutPostRedisplay(); // prekresleni sceny } } // }}} // onMouseMotion() {{{ //----------------------------------------------------------------------------- // Tato callback funkce je zavolana pri posunu kurzoru mysi //----------------------------------------------------------------------------- void onMouseMotion(int x, int y) { switch (operation) { case ROTATE: // stav rotace objektu xnew=xold+x-xx; // vypocitat novou pozici ynew=yold+y-yy; glutPostRedisplay(); // a prekreslit scenu break; case TRANSLATE: // stav priblizeni/oddaleni objektu znew=zold+y-zz; // vypocitat novou pozici glutPostRedisplay(); // a prekreslit scenu break; } } // }}} // main() {{{ //----------------------------------------------------------------------------- // Hlavni funkce konzolove aplikace //----------------------------------------------------------------------------- int main(int argc, char **argv) { glutInit(&argc, argv); // inicializace knihovny GLUT glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow(WINDOW_TITLE); // vytvoreni okna pro kresleni glutReshapeWindow(WINDOW_WIDTH, WINDOW_HEIGHT);// zmena velikosti okna glutPositionWindow(100, 100); // pozice leveho horniho rohu okna glutDisplayFunc(onDisplay); // registrace funkce volane pri prekreslovani okna glutReshapeFunc(onResize); // registrace funkce volane pri zmene velikosti okna glutKeyboardFunc(onKeyboard); // registrace funkce volane pri stlaceni klavesy glutSpecialFunc(onSpecial); // registrace funkce volane pri stlaceni specialni klavesy glutMouseFunc(onMouse); // funkce volana pri stlaceni tlacitka mysi glutMotionFunc(onMouseMotion); // funkce volana pri posunu mysi onInit(); // inicializace vykreslovani if (!doConvert(argv[1])) { // nacteni celeho souboru s kresbou puts("Nacteni souboru selhalo!\nUkonceni prohlizece...\n"); return 0; } glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane funkce return 0; // navratova hodnota vracena operacnimu systemu } // }}} //----------------------------------------------------------------------------- // finito //----------------------------------------------------------------------------- // vim: foldmethod=marker