//--------------------------------------------------------------------- // Priklad cislo 9 // Autor: Pavel Tisnovsky // // Zpracovani udalosti od mysi - zachyceni pohybu mysi //--------------------------------------------------------------------- #include <GL/glut.h> // hlavickovy soubor funkci GLUTu #include <math.h> enum { None, LeftButton, RightButton } status=None; // stav tlacitek mysi int oldX=200, oldY=200; // stara pozice stredu trojuhelnika int newX=200, newY=200; // nova pozice stredu trojuhelnika int mouseX=0, mouseY=0; // body, ve kterych se nachazi kurzor mysi float newAngle, oldAngle, rotAngle=0.0; // uhel rotace sipky okolo sveho stredu //--------------------------------------------------------------------- // Nastaveni souradneho systemu v zavislosti na velikosti okna //--------------------------------------------------------------------- void onResize(int w, int h) // w a h reprezentuje novou velikost okna { glViewport(0, 0, w, h); // viditelna oblast pres cele okno glMatrixMode(GL_PROJECTION); // zacatek modifikace projekcni matice glLoadIdentity(); // vymazani projekcni matice (=identita) glOrtho(0, w, 0, h, -1, 1); // mapovani abstraktnich souradnic do souradnic okna glScalef(1, -1, 1); // inverze y-ove osy, aby se y zvetsovalo smerem dolu glTranslatef(0, -h, 0); // posun pocatku do leveho horniho rohu } //--------------------------------------------------------------------- // Tato funkce je volana pri kazdem prekresleni okna //--------------------------------------------------------------------- void onDisplay(void) { glClear(GL_COLOR_BUFFER_BIT); // vymazani bitovych rovin barvoveho bufferu glMatrixMode(GL_MODELVIEW); // bude se menit matice modelview glLoadIdentity(); // vynulovani predchozi transformace glTranslatef(newX, newY, 0); // posun sipky glRotatef(rotAngle*180.0/3.14, 0, 0, 1.0);// rotace sipky glBegin(GL_TRIANGLES); // zacatek vykreslovani trojuhelniku glColor3f(0.0, 0.0, 1.0); // barva prvniho vertexu glVertex2i(0, -70); // poloha prvniho vertexu glColor3f(0.0, 1.0, 0.0); // barva druheho vertexu glVertex2i(-50, 100); // poloha druheho vertexu glColor3f(1.0, 0.0, 0.0); // barva tretiho vertexu glVertex2i(50, 100); // poloha tretiho vertexu glEnd(); glFlush(); // provedeni a vykresleni zmen } //--------------------------------------------------------------------- // 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) { case 27: // Escape exit(0); break; case 'f': glutFullScreen(); // prepnuti na celou obrazovku break; case 'w': glutReshapeWindow(400, 400);// prepnuti zpet do okna glutPositionWindow(50, 50); break; default: break; } } //--------------------------------------------------------------------- // Tato funkce je volana pri stlaceni nebo pusteni tlacitka mysi //--------------------------------------------------------------------- void onMouse(int button, int state, int x, int y) { switch(button) { // ktere tlacitko je stlaceno? case GLUT_LEFT_BUTTON: // leve tlacitko if (state==GLUT_DOWN) { // pri stlaceni status=LeftButton; // nastaveni pro funkci motion mouseX=x; mouseY=y; // zapamatovat pozici kurzoru mysi } else { // GLUT_UP status=None; // normalni stav oldX=newX; oldY=newY; // zapamatovat novy stred trojuhelnika } break; case GLUT_RIGHT_BUTTON: // prave tlacitko if (state==GLUT_DOWN) { // pri stlaceni status=RightButton; // nastaveni pro funkci motion newAngle=atan2(y-newY,x-newX);// vypocitat uhel vektoru od pozice kurzoru mysi } else { // GLUT_UP status=None; // normalni stav oldAngle=rotAngle; // zapamatovat novy uhel natoceni trojuhelnika } break; } glutPostRedisplay(); // prekresleni sceny } //--------------------------------------------------------------------- // Tato funkce je volana pri pohybu mysi se soucasne stlacenym tlacitkem //--------------------------------------------------------------------- void onMouseMotion(int x, int y) { if (status==LeftButton) { // stav presunu trojuhelnika newX=oldX+x-mouseX; // vypocitat novou pozici stredu newY=oldY+y-mouseY; glutPostRedisplay(); // a prekreslit scenu } if (status==RightButton) { // stav otoceni trojuhelnika rotAngle=oldAngle+atan2(y-newY, x-newX)-newAngle;// vypocitat novy uhel natoceni glutPostRedisplay(); // a prekreslit scenu } } //--------------------------------------------------------------------- // Hlavni funkce konzolove aplikace //--------------------------------------------------------------------- int main (int argc, char **argv) { glutInit(&argc, argv); // inicializace knihovny GLUT glutInitDisplayMode(GLUT_RGBA|GLUT_SINGLE);// graficky mod okna glutInitWindowSize(400, 400); // pocatecni velikost okna glutInitWindowPosition(10, 10); // pocatecni pozice okna glutCreateWindow("Priklad cislo 9");// vytvoreni okna pro kresleni glutDisplayFunc(onDisplay); // registrace funkce volane pri prekreslovani glutReshapeFunc(onResize); // registrace funkce volane pri zmene velikosti glutKeyboardFunc(onKeyboard); // registrace funkce volane pri stisku klavesy glutMouseFunc(onMouse); // registrace funkce volane pri stisku tlacitek mysi glutMotionFunc(onMouseMotion); // registrace funkce volane pri pohybu mysi glutMainLoop(); // nekonecna smycka, kde se volaji zaregistrovane fce return 0; // navratova hodnota vracena operacnimu systemu } //--------------------------------------------------------------------- // Konec zdrojoveho souboru //---------------------------------------------------------------------