//--------------------------------------------------------------------- // Priklad cislo 18 // Autor: Pavel Tisnovsky // // Vykresleni trojrozmernych objektu vytvorenych v knihovne GLUT. //--------------------------------------------------------------------- #include <math.h> #include <GL/glut.h> float materialAmbient[]={0.3, 0.2, 0.2, 1.0}; // ambientni slozka materialu float materialDiffuse[]={0.9, 0.1, 0.1, 1.0}; // difuzni slozka materialu float materialSpecular[]={0.0, 1.0, 1.0, 0.5}; // barva odlesku float lightAmbient[]= {0.5, 0.5, 0.5, 1.0}; // ambientni slozka svetla float lightDiffuse[]= {0.9, 0.9, 0.9, 1.0}; // difuzni slozka svetla float lightSpecular[]={0.0, 0.0, 0.0, 1.0}; // barva odlesku float lightPosition[]={1.0, 1.0, 1.0, 0.0}; // definice pozice svetla int newX=0, newY=0, newZ=0; // soucasna pozice, ze ktere se pocitaji rotace a posuny int oldZ=0; // minula pozice, ze ktere se pocitaji posuny int mouseX=0, mouseY=0, mouseZ=0; // body, ve kterych se nachazi kurzor mysi int mouseStatus=0; // stav tlacitek mysi float fieldOfView=45.0; // zorny uhel - field of view float nearClippingPlane=0.1; // blizsi orezavaci rovina float farClippingPlane=200.0; // vzdalenejsi orezavaci rovina int objectType=9; // typ vykreslovaneho objektu //--------------------------------------------------------------------- // Tato funkce provede zakladni nastaveni vykreslovani teles //--------------------------------------------------------------------- void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); // barva pro mazani color-bufferu glShadeModel(GL_SMOOTH); // nastaveni Gouraudova stinovani glClearDepth(1.0f); // barva pro mazani Z-bufferu glEnable(GL_DEPTH_TEST); // nastaveni funkce pro testovani hodnot v Z-bufferu glDepthFunc(GL_LESS); // nastaveni porovnavaci funkce pro Z-buffer glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);// vylepseni zobrazovani pri vypoctu perspektivy glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // stav vykresleni vyplnenych polygonu glPointSize(5.0); // velikost vykreslovanych bodu glLineWidth(3.0); // sirka vykreslovanych car glEnable(GL_POINT_SMOOTH); // povoleni antialiasingu bodu glEnable(GL_LINE_SMOOTH); // povoleni antialiasingu car glLightfv(GL_LIGHT0,GL_AMBIENT,lightAmbient); // nastaveni parametru svetla glLightfv(GL_LIGHT0,GL_DIFFUSE,lightDiffuse); glLightfv(GL_LIGHT0,GL_POSITION,lightPosition); glEnable(GL_LIGHTING); // povoleni osvetleni glEnable(GL_LIGHT0); // zapnuti prvniho svetla glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,materialAmbient);// nastaveni vlastnosti materialu glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,materialDiffuse); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,materialSpecular); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0); } //--------------------------------------------------------------------- // Nastaveni souradneho systemu v zavislosti na velikosti okna //--------------------------------------------------------------------- void onResize(int w, int h) { glViewport(0, 0, w, h); // viditelna oblast glMatrixMode(GL_PROJECTION); // zmena projekcni matice glLoadIdentity(); // nastaveni perspektivni projekce gluPerspective(fieldOfView, (double)w/(double)h, nearClippingPlane, farClippingPlane); glMatrixMode(GL_MODELVIEW); // zmena modelove matice } //--------------------------------------------------------------------- // Tato funkce je volana pri kazdem prekresleni okna //--------------------------------------------------------------------- void onDisplay(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // vymazani barvoveho bufferu glMatrixMode(GL_MODELVIEW); // bude se menit modelova matice glLoadIdentity(); // nahrat jednotkovou matici glTranslatef(0.0f, 0.0f, -50.0f); // posun modelu dale od kamery glTranslatef(0.0f, 0.0f, newZ); glRotatef(newY, 1.0, 0.0, 0.0); // rotace objektu podle pohybu kurzoru mysi glRotatef(newX, 0.0, 1.0, 0.0); switch (objectType) { // vykresleni vybraneho objektu case 0: glutWireCube(5); break; case 1: glutWireSphere(5, 16, 16); break; case 2: glutWireCone(5, 5, 16, 16); break; case 3: glutWireTorus(2, 5, 16, 16); break; case 4: glScalef(3,3,3); glutWireDodecahedron(); break; case 5: glScalef(3,3,3); glutWireOctahedron(); break; case 6: glScalef(3,3,3); glutWireTetrahedron(); break; case 7: glScalef(3,3,3); glutWireIcosahedron(); break; case 8: glutWireTeapot(5); break; case 9: glutSolidCube(5); break; case 10: glutSolidSphere(5,16,16); break; case 11: glutSolidCone(5,5,16,16); break; case 12: glutSolidTorus(2,5,16,16); break; case 13: glScalef(3,3,3); glutSolidDodecahedron(); break; case 14: glScalef(3,3,3); glutSolidOctahedron(); break; case 15: glScalef(3,3,3); glutSolidTetrahedron(); break; case 16: glScalef(3,3,3); glutSolidIcosahedron(); break; case 17: glutSolidTeapot(5); break; } glFlush(); // provedeni vsech prikazu glutSwapBuffers(); // a prohozeni bufferu } //--------------------------------------------------------------------- // Tato funkce je volana pri stlaceni ASCII klavesy //--------------------------------------------------------------------- void onKeyboard(unsigned char key, int x, int y) { key=(key>'A' && key<='Z') ? key+'a'-'A':key; // prevod na mala pismena switch (key) { // rozeskok podle stlacene klavesy case 27: // klavesa Escape exit(0); // ukonceni programu break; case 'f': glutFullScreen(); // prepnuti na celou obrazovku break; case 'w': glutReshapeWindow(500, 500); // prepnuti zpet do okna glutPositionWindow(50, 50); break; default: break; } } //--------------------------------------------------------------------- // Tato funkce je volana pri zmene stavu tlacitek mysi //--------------------------------------------------------------------- void onMouseClick(int button, int state, int x, int y) { if (button==GLUT_RIGHT_BUTTON) { // prave tlacitko aktivuje posun od pozorovatele if (state==GLUT_DOWN) { // pri stlaceni mouseStatus=1; // nastaveni pro funkci motion mouseZ=y; // zapamatovat pozici kurzoru mysi } else { mouseStatus=0; oldZ=newZ; // zapamatovat novy pocatek } } glutPostRedisplay(); // prekresleni sceny } //--------------------------------------------------------------------- // Tato funkce je volana pri posunu mysi se stlacenym tlacitkem //--------------------------------------------------------------------- void onMouseDrag(int x, int y) { if (mouseStatus==1) { // provadi se presun newZ=oldZ+y-mouseZ; // vypocitat novou pozici glutPostRedisplay(); // a prekreslit scenu } } //--------------------------------------------------------------------- // Tato funkce je volana pri posunu mysi bez stlaceneho tlacitka //--------------------------------------------------------------------- void onMouseMove(int x, int y) { newX=x; // zapamatovat si pozici kurzoru newY=y; // pro otaceni glutPostRedisplay(); // prekreslit scenu } //--------------------------------------------------------------------- // Tato funkce je zavolana pri vyberu polozky z menu //--------------------------------------------------------------------- void onCommand(int command) { if (command<18) // byla vybrana polozka s nazvem objektu objectType=command; switch (command) { case 18: // zobrazovat se budou pouze vrcholy polygonu glPolygonMode(GL_FRONT,GL_POINT); glPolygonMode(GL_BACK,GL_POINT); break; case 19: // zobrazovat se budou pouze hrany polygonu glPolygonMode(GL_FRONT,GL_LINE); glPolygonMode(GL_BACK,GL_LINE); break; case 20: // zobrazovat se budou vyplnene polygony glPolygonMode(GL_FRONT,GL_FILL); glPolygonMode(GL_BACK,GL_FILL); break; case 21: // ukonceni aplikace exit(0); default: break; } glutPostRedisplay(); // prekreslit scenu } //--------------------------------------------------------------------- // Tato funkce vytvori menu a navaze ho na leve tlacitko mysi //--------------------------------------------------------------------- void createMenu(void) { int i, j, k, l; i=glutCreateMenu(onCommand); // vytvoreni submenu a registrace callback funkce glutAddMenuEntry("Wireframe cube", 0); glutAddMenuEntry("Wireframe sphere", 1); glutAddMenuEntry("Wireframe cone", 2); glutAddMenuEntry("Wireframe torus", 3); glutAddMenuEntry("Wireframe dodecahedron", 4); glutAddMenuEntry("Wireframe octahedron", 5); glutAddMenuEntry("Wireframe tetrahedron", 6); glutAddMenuEntry("Wireframe icosahedron", 7); glutAddMenuEntry("Wireframe teapot", 8); j=glutCreateMenu(onCommand); // vytvoreni submenu a registrace callback funkce glutAddMenuEntry("Solid cube", 9); glutAddMenuEntry("Solid sphere", 10); glutAddMenuEntry("Solid cone", 11); glutAddMenuEntry("Solid torus", 12); glutAddMenuEntry("Solid dodecahedron", 13); glutAddMenuEntry("Solid octahedron", 14); glutAddMenuEntry("Solid tetrahedron", 15); glutAddMenuEntry("Solid icosahedron", 16); glutAddMenuEntry("Solid teapot", 17); k=glutCreateMenu(onCommand); // vytvoreni submenu a registrace callback funkce glutAddMenuEntry("Points", 18); glutAddMenuEntry("Lines", 19); glutAddMenuEntry("Fill", 20); l=glutCreateMenu(onCommand); // vytvoreni submenu a registrace callback funkce glutAddMenuEntry("Yes", 21); glutAddMenuEntry("No", 22); glutCreateMenu(onCommand); // vytvoreni menu glutAddSubMenu("Wireframe objects", i); glutAddSubMenu("Solid objects", j); glutAddSubMenu("Polygon mode", k); glutAttachMenu(GLUT_LEFT_BUTTON); } //--------------------------------------------------------------------- // Hlavni funkce konzolove aplikace //--------------------------------------------------------------------- int main(int argc, char *argv[]) { glutInit(&argc, argv); // inicializace knihovny GLUT glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH); // graficky mod okna glutInitWindowSize(500, 500); // pocatecni velikost okna glutInitWindowPosition(10, 10); // pocatecni pozice okna glutCreateWindow("Priklad cislo 18"); // vytvoreni okna pro kresleni glutReshapeWindow(500, 500); // nastaveni velikosti 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 ASCII klavesy glutMouseFunc(onMouseClick); // registrace funkce volane pri stlaceni nebo pusteni tlacitka mysi glutMotionFunc(onMouseDrag); // registrace funkce volane pri posunu mysi se stlacenym tlacitkem glutPassiveMotionFunc(onMouseMove); // registrace funkce volane pri posunu mysi bez stlaceneho tlacitka init(); // inicializace vykreslovani createMenu(); // vytvoreni menu s vyberem telesa glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane funkce return 0; // navratova hodnota vracena operacnimu systemu } //--------------------------------------------------------------------- // Konec zdrojoveho souboru //---------------------------------------------------------------------