//--------------------------------------------------------------------- // Ukazkovy priklad cislo 30 // Autor: Pavel Tisnovsky // // Tento priklad svym ovladanim navazuje na priklad cislo 28, ktery byl // prezentovany v minulem dilu tohoto serialu. Funkcni zustavaji veskere // klavesove kombinace i ovladani, je pouze pridano submenu pro povoleni // a zakazani orezavaci roviny rovnobezne s rovinou x-z prochazejici // pocatkem. // // Program lze ovladat kombinaci mysi a klavesnice. Pomoci leveho // tlacitka mysi se aplikuje nektera operace, prave tlacitko mysi slouzi // k zobrazeni kontextoveho menu. Zakladni udaje o scene se vypisuji // primo do okna aplikace. // // Funkce klaves v tomto programu: // ESC - ukonceni aplikace // 'q' - ukonceni aplikace // 'r' - rezim rotace objektu // 't' - rezim posunu objektu dale/blize ke kamere // 'z' - rezim posunu blizke orezavaci roviny // 'x' - rezim posunu vzdalene orezavaci roviny // 'f' - prepnuti do rezimu full-screen // 'w' - prepnuti zpet do okna // 'e' - povoleni testu pameti hloubky // 'd' - zakazani testu pameti hloubky // '.' - zmenseni zorneho uhlu // ',' - zvetseni zorneho uhlu // '>' - rychlejsi zmenseni zorneho uhlu // '<' - rychlejsi zvetseni zorneho uhlu // '0'-'9' - zmena rezimu vykreslovani prednich a zadnich stran polygonu //--------------------------------------------------------------------- #include <GL/glut.h> // hlavickovy soubor funkci GLUTu a OpenGL #include <stdio.h> #include <stdlib.h> enum { // operace, ktere se mohou provadet s mysi ROTATE, TRANSLATE, NEAR_PLANE, FAR_PLANE } operation=ROTATE; enum { // prikazy z kontextoveho menu COMMAND_ROTATE, COMMAND_TRANSLATE, COMMAND_NEAR_PLANE, COMMAND_FAR_PLANE, COMMAND_FRONT_FACE_DISABLE, COMMAND_FRONT_FACE_ENABLE, COMMAND_FRONT_FACE_POINTS, COMMAND_FRONT_FACE_LINES, COMMAND_FRONT_FACE_POLYGONS, COMMAND_BACK_FACE_DISABLE, COMMAND_BACK_FACE_ENABLE, COMMAND_BACK_FACE_POINTS, COMMAND_BACK_FACE_LINES, COMMAND_BACK_FACE_POLYGONS, COMMAND_ENABLE_DEPTH_TEST, COMMAND_DISABLE_DEPTH_TEST, COMMAND_DEPTH_FUNC_NEVER, COMMAND_DEPTH_FUNC_LESS, COMMAND_DEPTH_FUNC_LEQUAL, COMMAND_DEPTH_FUNC_EQUAL, COMMAND_DEPTH_FUNC_GEQUAL, COMMAND_DEPTH_FUNC_GREATER, COMMAND_DEPTH_FUNC_NOTEQUAL, COMMAND_DEPTH_FUNC_ALWAYS, COMMAND_FULL_SCREEN, COMMAND_WINDOW, COMMAND_ENABLE_XZ_PLANE, COMMAND_DISABLE_XZ_PLANE, COMMAND_QUIT, COMMAND_NONE } command; int xnew=0, ynew=0, znew=0; // soucasna pozice mysi, ze ktere se pocitaji rotace a posuvy int xold=0, yold=0, zold=0; // minula pozice mysi, ze ktere se pocitaji rotace a posuvy int xx, yy, zz; // bod, ve kterem se nachazi kurzor mysi int np_old=1, np_new=1, npp=1; // priznaky blizke orezavaci roviny int fp_old=900, fp_new=900, fpp=900; // priznaky vzdalene orezavaci roviny float fov=70.0; // hodnota zorneho uhlu - field of view float nearPlane=0.1; // blizsi orezavaci rovina float farPlane=90.0; // vzdalenejsi orezavaci rovina int windowWidth; // sirka okna int windowHeight; // vyska okna int depthBufferEnabled=1; // priznak, zda je povolena pamet hloubky int frontFaceEnabled=1; // priznak viditelnosti prednich sten int backFaceEnabled=1; // priznak viditelnosti zadnich sten //--------------------------------------------------------------------- // Funkce, ktera je zavolana pri vyberu prikazu z kontextoveho menu //--------------------------------------------------------------------- void onMenu(int command) { switch (command) { // rozeskok podle vybraneho prikazu case COMMAND_ROTATE: operation=ROTATE; break; case COMMAND_TRANSLATE: operation=TRANSLATE; break; case COMMAND_NEAR_PLANE: operation=NEAR_PLANE; break; case COMMAND_FAR_PLANE: operation=FAR_PLANE; break; case COMMAND_FRONT_FACE_DISABLE: glCullFace(GL_FRONT); glEnable(GL_CULL_FACE); glutPostRedisplay(); break; case COMMAND_FRONT_FACE_ENABLE: glDisable(GL_CULL_FACE); glutPostRedisplay(); break; case COMMAND_FRONT_FACE_POINTS: glPolygonMode(GL_FRONT, GL_POINT); glutPostRedisplay(); break; case COMMAND_FRONT_FACE_LINES: glPolygonMode(GL_FRONT, GL_LINE); glutPostRedisplay(); break; case COMMAND_FRONT_FACE_POLYGONS: glPolygonMode(GL_FRONT, GL_FILL); glutPostRedisplay(); break; case COMMAND_BACK_FACE_DISABLE: glCullFace(GL_BACK); glEnable(GL_CULL_FACE); glutPostRedisplay(); break; case COMMAND_BACK_FACE_ENABLE: glDisable(GL_CULL_FACE); glutPostRedisplay(); break; case COMMAND_BACK_FACE_POINTS: glPolygonMode(GL_BACK, GL_POINT); glutPostRedisplay(); break; case COMMAND_BACK_FACE_LINES: glPolygonMode(GL_BACK, GL_LINE); glutPostRedisplay(); break; case COMMAND_BACK_FACE_POLYGONS: glutPostRedisplay(); glPolygonMode(GL_BACK, GL_FILL); break; case COMMAND_ENABLE_DEPTH_TEST: depthBufferEnabled=1; glEnable(GL_DEPTH_TEST); glutPostRedisplay(); break; case COMMAND_DISABLE_DEPTH_TEST: depthBufferEnabled=0; glDisable(GL_DEPTH_TEST); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_NEVER: glDepthFunc(GL_NEVER); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_LESS: glDepthFunc(GL_LESS); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_LEQUAL: glDepthFunc(GL_LEQUAL); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_EQUAL: glDepthFunc(GL_EQUAL); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_GEQUAL: glDepthFunc(GL_GEQUAL); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_GREATER: glDepthFunc(GL_GREATER); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_NOTEQUAL: glDepthFunc(GL_NOTEQUAL); glutPostRedisplay(); break; case COMMAND_DEPTH_FUNC_ALWAYS: glDepthFunc(GL_ALWAYS); glutPostRedisplay(); break; case COMMAND_FULL_SCREEN: glutFullScreen(); break; case COMMAND_WINDOW: glutReshapeWindow(500, 500); break; case COMMAND_ENABLE_XZ_PLANE: glEnable(GL_CLIP_PLANE0); glutPostRedisplay(); break; case COMMAND_DISABLE_XZ_PLANE: glDisable(GL_CLIP_PLANE0); glutPostRedisplay(); break; case COMMAND_QUIT: exit(0); break; case COMMAND_NONE: break; } } //--------------------------------------------------------------------- // Funkce pro inicializaci vykreslovani //--------------------------------------------------------------------- void onInit(void) { GLdouble equation[]={0.0, 1.0, 0.0, 0.0}; int menu; // identifikatory jednotlivych menu a submenu int menuMode; int menuDepth; int menuDFunc; int menuFrontFace; int menuBackFace; int menuClipping; int menuQuit; glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // barva pozadi obrazku glClearDepth(1.0f); // implicitni hloubka ulozena v pameti hloubky glEnable(GL_DEPTH_TEST); // povoleni funkce pro testovani hodnot 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 glPointSize(3.0f); // body zobrazovat s prumerem 3 pixely glEnable(GL_POINT_SMOOTH); // povoleni antialiasingu bodu glLineWidth(1.0f); // usecky zobrazovat siroke 1 pixel glEnable(GL_LINE_SMOOTH); // povoleni antialiasingu usecek glDisable(GL_CULL_FACE); // zadne hrany ani steny se nebudou odstranovat glClipPlane(GL_CLIP_PLANE0, equation); menuMode=glutCreateMenu(onMenu); // vytvoreni kontextoveho menu a jeho submenu glutSetMenu(menuMode); glutAddMenuEntry("Rotate object\tR", COMMAND_ROTATE); glutAddMenuEntry("Translate object\tT", COMMAND_TRANSLATE); glutAddMenuEntry("Translate near clipping plane\tZ", COMMAND_NEAR_PLANE); glutAddMenuEntry("Translate far clipping plane\tX", COMMAND_FAR_PLANE); menuDepth=glutCreateMenu(onMenu); glutSetMenu(menuDepth); glutAddMenuEntry("Enable depth test\tE", COMMAND_ENABLE_DEPTH_TEST); glutAddMenuEntry("Disable depth test\tD", COMMAND_DISABLE_DEPTH_TEST); menuDFunc=glutCreateMenu(onMenu); glutSetMenu(menuDFunc); glutAddMenuEntry("Never", COMMAND_DEPTH_FUNC_NEVER); glutAddMenuEntry("Less", COMMAND_DEPTH_FUNC_LESS); glutAddMenuEntry("Less or Equal", COMMAND_DEPTH_FUNC_LEQUAL); glutAddMenuEntry("Equal", COMMAND_DEPTH_FUNC_EQUAL); glutAddMenuEntry("Greater or Equal", COMMAND_DEPTH_FUNC_GEQUAL); glutAddMenuEntry("Greater", COMMAND_DEPTH_FUNC_GREATER); glutAddMenuEntry("Not Equal", COMMAND_DEPTH_FUNC_NOTEQUAL); glutAddMenuEntry("Always", COMMAND_DEPTH_FUNC_ALWAYS); menuFrontFace=glutCreateMenu(onMenu); glutSetMenu(menuFrontFace); glutAddMenuEntry("Disable\t1", COMMAND_FRONT_FACE_DISABLE); glutAddMenuEntry("Enable\t2", COMMAND_FRONT_FACE_ENABLE); glutAddMenuEntry("Points\t3", COMMAND_FRONT_FACE_POINTS); glutAddMenuEntry("Lines\t4", COMMAND_FRONT_FACE_LINES); glutAddMenuEntry("Polygons\t5", COMMAND_FRONT_FACE_POLYGONS); menuBackFace=glutCreateMenu(onMenu); glutSetMenu(menuBackFace); glutAddMenuEntry("Disable\t6", COMMAND_BACK_FACE_DISABLE); glutAddMenuEntry("Enable\t7", COMMAND_BACK_FACE_ENABLE); glutAddMenuEntry("Points\t8", COMMAND_BACK_FACE_POINTS); glutAddMenuEntry("Lines\t9", COMMAND_BACK_FACE_LINES); glutAddMenuEntry("Polygons\t0", COMMAND_BACK_FACE_POLYGONS); menuClipping=glutCreateMenu(onMenu); glutSetMenu(menuClipping); glutAddMenuEntry("Enable x-z plane", COMMAND_ENABLE_XZ_PLANE); glutAddMenuEntry("Disable x-z plane", COMMAND_DISABLE_XZ_PLANE); menuQuit=glutCreateMenu(onMenu); glutSetMenu(menuQuit); glutAddMenuEntry("Yes\tQ", COMMAND_QUIT); glutAddMenuEntry("No", COMMAND_NONE); menu=glutCreateMenu(onMenu); glutAddSubMenu("Mode", menuMode); glutAddSubMenu("Front faces", menuFrontFace); glutAddSubMenu("Back faces", menuBackFace); glutAddSubMenu("Depth test", menuDepth); glutAddSubMenu("Depth function", menuDFunc); glutAddSubMenu("Clipping", menuClipping); glutAddMenuEntry("Full screen\tF", COMMAND_FULL_SCREEN); glutAddMenuEntry("Window\tW", COMMAND_WINDOW); glutAddSubMenu("Quit", menuQuit); glutAttachMenu(GLUT_RIGHT_BUTTON); // menu je navazano na prave tlacitko mysi } //--------------------------------------------------------------------- // 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 windowWidth=w; // zapamatovat si velikost okna windowHeight=h; } //--------------------------------------------------------------------- // Nastaveni perspektivni projekce //--------------------------------------------------------------------- void setPerspectiveProjection(void) { glMatrixMode(GL_PROJECTION); // zacatek modifikace projekcni matice glLoadIdentity(); // vymazani projekcni matice (=identita) gluPerspective(fov, (double)windowWidth/(double)windowHeight, nearPlane, farPlane);// nastaveni perspektivni kamery glMatrixMode(GL_MODELVIEW); // bude se menit modelova matice glLoadIdentity(); // nahrat jednotkovou matici } //--------------------------------------------------------------------- // Nastaveni ortogonalni projekce //--------------------------------------------------------------------- void setOrthogonalProjection(void) { glMatrixMode(GL_PROJECTION); // zacatek modifikace projekcni matice glLoadIdentity(); // vymazani projekcni matice (=identita) glOrtho(0, windowWidth, 0, windowHeight, -1, 1); glMatrixMode(GL_MODELVIEW); // bude se menit modelova matice glLoadIdentity(); // nahrat jednotkovou matici } //--------------------------------------------------------------------- // Vypsani retezce do okna na pozici [x,y] //--------------------------------------------------------------------- void printString(int x, int y, char *text) { glRasterPos2i(x, y); // pozice prvniho znaku retezce for (; *text; text++) // pruchod retezcem glutBitmapCharacter(GLUT_BITMAP_9_BY_15, *text);// vykresleni jednoho znaku } //-------------------------------------------------------------------- // Vypsani informaci o nastavenych parametrech //--------------------------------------------------------------------- void drawInfoText(void) { char str[100]; glColor3f(1.0,1.0,1.0); sprintf(str, "Rotation x: %d", xnew); printString(10, 100, str); // vypsat rotaci ve smeru osy x sprintf(str, "Rotation y: %d", ynew); printString(10, 85, str); // vypsat rotaci ve smeru osy y sprintf(str, "Translation: %d", znew); printString(10, 70, str); // vypsat posun objektu od kamery sprintf(str, "Near plane: %5.2f", nearPlane); printString(10, 55, str); // vzdalenost blizke orezavaci roviny sprintf(str, "Far plane: %5.2f", farPlane); printString(10, 40, str); // vzdalenost vzdalene orezavaci roviny sprintf(str, "Field of view: %5.2f", fov); printString(10, 25, str); // zorny uhel kamery sprintf(str, "Clip plane: %s", glIsEnabled(GL_CLIP_PLANE0) ? "enabled":"disabled"); printString(10, 10, str); // povoleni ci zakazani orezavaci roviny } //-------------------------------------------------------------------- // Vykresleni objektu //--------------------------------------------------------------------- void drawObject(void) { glBegin(GL_QUADS); // vykresleni otevrene krychle - sten domecku glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-5.0f, -5.0f, -5.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-5.0f, -5.0f, 5.0f); glColor3f(0.0f, 1.0f, 1.0f); glVertex3f( 5.0f, -5.0f, 5.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 5.0f, -5.0f, -5.0f); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(-5.0f, 5.0f, -5.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f(-5.0f, 5.0f, 5.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f( 5.0f, 5.0f, 5.0f); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f( 5.0f, 5.0f, -5.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-5.0f, -5.0f, -5.0f); glColor3f(0.0f, 1.0f, 1.0f); glVertex3f(-5.0f, -5.0f, 5.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f(-5.0f, 5.0f, 5.0f); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f(-5.0f, 5.0f, -5.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f( 5.0f, -5.0f, -5.0f); glColor3f(0.0f, 1.0f, 1.0f); glVertex3f( 5.0f, -5.0f, 5.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 5.0f, 5.0f, 5.0f); glColor3f(1.0f, 0.0f, 1.0f); glVertex3f( 5.0f, 5.0f, -5.0f); glEnd(); glBegin(GL_TRIANGLES); // vykresleni strechy domecku z trojuhelniku glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-5.0f, 5.0f, -5.0f); glColor3f(0.0f, 1.0f, 1.0f); glVertex3f( 5.0f, 5.0f, -5.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f( 0.0f, 11.0f, 0.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3f( 5.0f, 5.0f, -5.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f( 5.0f, 5.0f, 5.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f( 0.0f, 11.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f( 5.0f, 5.0f, 5.0f); glColor3f(0.0f, 1.0f, 1.0f); glVertex3f(-5.0f, 5.0f, 5.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f( 0.0f, 11.0f, 0.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(-5.0f, 5.0f, 5.0f); glColor3f(1.0f, 1.0f, 0.0f); glVertex3f(-5.0f, 5.0f, -5.0f); glColor3f(1.0f, 1.0f, 1.0f); glVertex3f( 0.0f, 11.0f, 0.0f); glEnd(); } //-------------------------------------------------------------------- // Tato funkce je volana pri kazdem prekresleni okna //--------------------------------------------------------------------- void onDisplay(void) { if (depthBufferEnabled) // podle povoleni pameti hloubky glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// vymazani barvoveho bufferu i pameti hloubky else glClear(GL_COLOR_BUFFER_BIT); // vymazani vsech bitovych rovin barvoveho bufferu setOrthogonalProjection(); // ortogonalni rezim pro kresleni 2D obrazku drawInfoText(); // vypsat informace o nastaveni 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); drawObject(); // vykresleni objektu glFlush(); // provedeni a vykresleni vsech zmen glutSwapBuffers(); // a prohozeni predniho a zadniho bufferu } //--------------------------------------------------------------------- // Tato funkce je volana pri stlaceni ASCII klavesy //--------------------------------------------------------------------- void onKeyboard(unsigned char key, int x, int y) { if (key>='A' && key<='Z') // uprava velkych pismen na mala key+='a'-'A'; // pro zjednoduseni prikazu switch switch (key) { case 27: exit(0); break; // ukonceni aplikace case 'q': exit(0); break; // ukonceni aplikace case 'f': onMenu(COMMAND_FULL_SCREEN); break; // prepnuti do full-screen rezimu case 'w': onMenu(COMMAND_WINDOW); break; // prepnuti zpet do okna case 'e': onMenu(COMMAND_ENABLE_DEPTH_TEST); break; // povoleni funkce pameti hloubky case 'd': onMenu(COMMAND_DISABLE_DEPTH_TEST); break; // zakazani funkce pameti hloubky case 'r': onMenu(COMMAND_ROTATE); break; // rezim rotace objektu case 't': onMenu(COMMAND_TRANSLATE); break; // rezim posunu objektu case 'z': onMenu(COMMAND_NEAR_PLANE); break; // rezim posunu blizke orezavaci roviny case 'x': onMenu(COMMAND_FAR_PLANE); break; // rezim posunu vzdalene orezavaci roviny case '.': fov--; glutPostRedisplay(); break; // zmenseni zorneho uhlu case ',': fov++; glutPostRedisplay(); break; // zvetseni zorneho uhlu case '>': fov-=5; glutPostRedisplay(); break; // rychlejsi zmenseni zorneho uhlu case '<': fov+=5; glutPostRedisplay(); break; // rychlejsi zvetseni zorneho uhlu case '1': onMenu(COMMAND_FRONT_FACE_DISABLE); break; // zakaz vykresleni prednich sten case '2': onMenu(COMMAND_FRONT_FACE_ENABLE); break; // povoleni vykresleni prednich sten case '3': onMenu(COMMAND_FRONT_FACE_POINTS); break; // predni steny se vykresli jako body case '4': onMenu(COMMAND_FRONT_FACE_LINES); break; // predni steny se vykresli jako usecky case '5': onMenu(COMMAND_FRONT_FACE_POLYGONS);break; // predni steny se vykresli jako polygony case '6': onMenu(COMMAND_BACK_FACE_DISABLE); break; // zakaz vykresleni zadnich sten case '7': onMenu(COMMAND_BACK_FACE_ENABLE); break; // povoleni vykresleni zadnich sten case '8': onMenu(COMMAND_BACK_FACE_POINTS); break; // zadni steny se vykresli jako body case '9': onMenu(COMMAND_BACK_FACE_LINES); break; // zadni steny se vykresli jako usecky case '0': onMenu(COMMAND_BACK_FACE_POLYGONS); break; // zadni steny se vykresli jako polygony default: break; } } //--------------------------------------------------------------------- // Tato funkce je volana pri stisku ci pusteni tlacitka mysi //--------------------------------------------------------------------- void onMouseButton(int button, int state, int x, int y) { if (button==GLUT_LEFT_BUTTON) { // pri zmene stavu leveho tlacitka switch (operation) { case ROTATE: // rotace objektu 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 break; case TRANSLATE: // posun objektu 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 break; case NEAR_PLANE: // zmena polohy blizke orezavaci roviny if (state==GLUT_DOWN) npp=y; // pri stlaceni tlacitka zapamatovat polohu kurzoru mysi else np_old=np_new; break; case FAR_PLANE: // zmena polohy vzdalene orezavaci roviny if (state==GLUT_DOWN) fpp=y; // pri stlaceni tlacitka zapamatovat polohu kurzoru mysi else fp_old=fp_new; break; default: break; } } } //--------------------------------------------------------------------- // Tato funkce je volana pri pohybu mysi se stlacenym tlacitkem. // To, ktere tlacitko je stlaceno si musime predem zaznamenat do // globalni promenne stav ve funkci onMouseButton() //--------------------------------------------------------------------- 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; case NEAR_PLANE: // priblizeni/vzdaleni blizke orezavaci roviny np_new=np_old+y-npp; nearPlane=np_new/100.0; onResize(windowWidth, windowHeight);// zmena projekcni matice glutPostRedisplay(); // a prekreslit scenu break; case FAR_PLANE: // priblizeni/vzdaleni vzdalene orezavaci roviny fp_new=fp_old+y-fpp; farPlane=fp_new/10.0; onResize(windowWidth, windowHeight);// zmena projekcni matice glutPostRedisplay(); // a prekreslit scenu break; } } //--------------------------------------------------------------------- // Hlavni funkce konzolove aplikace //--------------------------------------------------------------------- int main(int argc, char **argv) { glutInit(&argc, argv); // inicializace knihovny GLUT glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);// nastaveni dvou barvovych bufferu a pameti hloubky glutInitWindowPosition(30, 30); // pocatecni pozice leveho horniho rohu okna glutInitWindowSize(500, 500); // pocatecni velikost okna glutCreateWindow("Priklad na OpenGL cislo 30");// vytvoreni okna pro kresleni 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 glutMouseFunc(onMouseButton); // registrace funkce volane pri stlaceni ci pusteni tlacitka glutMotionFunc(onMouseMotion); // registrace funkce volane pri pohybu mysi se stlacenym tlacitkem onInit(); // inicializace vykreslovani glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane funkce return 0; // navratova hodnota vracena operacnimu systemu } //--------------------------------------------------------------------- // Konec zdrojoveho souboru //---------------------------------------------------------------------