/* gcc -o robot.exe -Wall robot.c glut32.lib -lopengl32 -lglu32 */ #include #include #include #include #include #define UP 0 #define DOWN 1 /* Wskazniki do wykorzystywanych kwadryk */ GLUquadricObj *podstawaSciany; GLUquadricObj *podstawaDyskG; GLfloat zoom = -7.0; GLfloat rotObsY = 25.0; GLfloat rotObsX = 20.0; int i,j,k; float czas=0.0; int przycisk = 0.0; float katGlownejOsi = 0.0; float katPobocznychOsi = 0.0; float odlegloscOdSrodka = 1.0; float distance = 0; int direction = 0; int pomocnicze = -1; float color1R = 0.0; float color1G = 0.0; float color1B = 0.0; float color2R = 0.0; float color2G = 0.0; float color2B = 0.0; float color3R = 0.0; float color3G = 0.0; float color3B = 0.0; int changedColor = 0; /* Funkcja inicjujaca elementy skladowe ramienia robota zamodelowane jako kwadryki */ void InicjujRamieRobota(void) { /* Zainicjowanie scian bocznych walca bedacego podstawa ramienia */ podstawaSciany = gluNewQuadric(); gluQuadricDrawStyle(podstawaSciany, GLU_LINE); // Zainicjowanie gornej podstawy walca podstawaDyskG = gluNewQuadric(); gluQuadricDrawStyle(podstawaDyskG, GLU_LINE); } /* Funkcja rysujaca obraz sceny widzianej z biezacej pozycji obserwatora Zalozenie: Funkcja glutWireSpehere moze ryswac tylko sfere o promieniu 1 */ void RysujRamieRobota() { glEnable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); czas = 0.5; if(pomocnicze == 1) { glBegin(GL_LINES); glColor3f(1.0, 0.0, 0.0); // Os X glVertex3f(-30.0, 0.0, 0.0); glVertex3f(30.0, 0.0, 0.0); glColor3f(0.0,1.0,0.0); // Os Y glVertex3f(0.0, -5.0, 0.0); glVertex3f(0.0, 30.0, 0.0); glColor3f(0.0,0.0,1.0); // Os Z glVertex3f(0.0, 0.0, -30.0); glVertex3f(0.0, 0.0, 30.0); glEnd(); } glColor3f(0.3,0.3,1.0); glTranslatef(0.0,0.0,0.0); switch(przycisk) { case 0: glRotatef(katGlownejOsi,0,1,0); for(i=-1;i<2;i++) { for(j=-1;j<2;j++) { for(k=-1;k<2;k++) { glPushMatrix(); glTranslatef(i,j,k); switch(i) { case -1: glTranslatef(distance, 0, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(-distance, 0, 0); break; } switch(j) { case -1: glTranslatef(0, distance, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, -distance, 0); break; } switch(k) { case -1: glTranslatef(0, 0, distance); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, 0, -distance); break; } if(changedColor==1) { if(i==-1 && j==1 && k==-1) glColor3f(color1R, color1G, color1B); if(i==0 && j==1 && k==0) glColor3f(color2R, color2G, color2B); if(i==1 && j==1 && k==1) glColor3f(color3R, color3G, color3B); } glRotatef(-katPobocznychOsi,0,1,0); glutSolidCube(0.55); glPopMatrix(); glColor3f(0.3,0.3,1.0); } } } break; /* Obracanie wzgledem osi srodkowej */ case 1: katGlownejOsi += -0.05; glRotatef(katGlownejOsi,0,1,0); for(i=-1;i<2;i++) { for(j=-1;j<2;j++) { for(k=-1;k<2;k++) { glPushMatrix(); glTranslatef(i,j,k); switch(i) { case -1: glTranslatef(distance, 0, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(-distance, 0, 0); break; } switch(j) { case -1: glTranslatef(0, distance, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, -distance, 0); break; } switch(k) { case -1: glTranslatef(0, 0, distance); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, 0, -distance); break; } if(changedColor==1) { if(i==-1 && j==1 && k==-1) glColor3f(color1R, color1G, color1B); if(i==0 && j==1 && k==0) glColor3f(color2R, color2G, color2B); if(i==1 && j==1 && k==1) glColor3f(color3R, color3G, color3B); } glRotatef(-katPobocznychOsi,0,1,0); glutSolidCube(0.55); glPopMatrix(); glColor3f(0.3,0.3,1.0); } } } break; /* Obracanie wzgledem osi Z dla 3*3 elementow */ case 2: katPobocznychOsi += 0.05; glPushMatrix(); glRotatef(katGlownejOsi,0,1,0); for(i=-1;i<2;i++) { for(j=-1;j<2;j++) { for(k=-1;k<2;k++) { glPushMatrix(); glTranslatef(i,k,j); if(changedColor==1) { if(i==-1 && k==1 && j==-1) glColor3f(color1R, color1G, color1B); if(i==0 && k==1 && j==0) glColor3f(color2R, color2G, color2B); if(i==1 && k==1 && j==1) glColor3f(color3R, color3G, color3B); } switch(i) { case -1: glTranslatef(distance, 0, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(-distance, 0, 0); break; } switch(j) { case -1: glTranslatef(0, 0, distance); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, 0, -distance); break; } switch(k) { case -1: glTranslatef(0, distance, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, -distance, 0); break; } glRotatef(-katPobocznychOsi,0,1,0); glutSolidCube(0.55); glPopMatrix(); glColor3f(0.3,0.3,1.0); } } } glPopMatrix(); break; /* Rozciaganie od srodka */ case 3: if(distance >= 0.2f) direction = UP; if(distance <= -0.2f) direction = DOWN; if(direction == UP) { distance -= 0.0004f; } else { distance += 0.0004f; } glRotatef(katGlownejOsi,0,1,0); for(i=-1;i<2;i++) { for(j=-1;j<2;j++) { for(k=-1;k<2;k++) { glPushMatrix(); glTranslatef(i,j,k); switch(i) { case -1: glTranslatef(distance, 0, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(-distance, 0, 0); break; } switch(j) { case -1: glTranslatef(0, distance, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, -distance, 0); break; } switch(k) { case -1: glTranslatef(0, 0, distance); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, 0, -distance); break; } if(changedColor==1) { if(i==-1 && j==1 && k==-1) glColor3f(color1R, color1G, color1B); if(i==0 && j==1 && k==0) glColor3f(color2R, color2G, color2B); if(i==1 && j==1 && k==1) glColor3f(color3R, color3G, color3B); } glRotatef(-katPobocznychOsi,0,1,0); glutSolidCube(0.55); glPopMatrix(); glColor3f(0.3,0.3,1.0); } } } break; /* Zmiany kolorow */ case 4: changedColor = 1; glRotatef(katGlownejOsi,0,1,0); for(i=-1;i<2;i++) { for(j=-1;j<2;j++) { for(k=-1;k<2;k++) { glPushMatrix(); glTranslatef(i,j,k); switch(i) { case -1: glTranslatef(distance, 0, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(-distance, 0, 0); break; } switch(j) { case -1: glTranslatef(0, distance, 0); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, -distance, 0); break; } switch(k) { case -1: glTranslatef(0, 0, distance); break; case 0: glTranslatef(0, 0, 0); break; case 1: glTranslatef(0, 0, -distance); break; } if(i==-1 && j==1 && k==-1) glColor3f(color1R+=0.0001f, color1G+=0.0003f, color1B+=0.0006f); if(i==0 && j==1 && k==0) glColor3f(color2R+=0.0006f, color2G+=0.0001f, color2B+=0.0003f); if(i==1 && j==1 && k==1) glColor3f(color3R+=0.0003f, color3G+=0.0006f, color3B+=0.0001f); glRotatef(-katPobocznychOsi,0,1,0); glutSolidCube(0.55); glPopMatrix(); glColor3f(0.3,0.3,1.0); } } } break; } /* Sprzatamy */ glPopMatrix(); } /* Funkcja generujaca pojedyncza klatke animacji */ void WyswietlObraz(void) { /* Wyczyszczenie bufora ramki i bufora glebokosci */ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); /* Powielenie macierzy na wierzcholku stosu */ glPushMatrix(); /* Wyznaczenie polozenia obserwatora (przeksztalcenie uladu wspolrzednych, sceny do ukladu wspolrzednych obserwatora). */ glTranslatef(0, 0, zoom); glRotatef(rotObsX, 1, 0, 0); glRotatef(rotObsY,0,1,0); /* Generacja obrazu sceny w niewidocznym buforze ramki */ RysujRamieRobota(); /* Usuniecie macierzy lezacej na wierzcholku stosu (powrot do stanu sprzed wywolania funkcji) */ glPopMatrix(); /* Przelaczenie buforow ramki */ glutSwapBuffers(); } /* Funkcja ustawiajaca parametry rzutu perspektywicznego i rozmiary viewportu */ void UstawParametryWidoku(int szerokosc, int wysokosc) { /* Ustawienie parametrow viewportu */ glViewport(0, 0, szerokosc, wysokosc); /* Przejscie w tryb modyfikacji macierzy rzutowania */ glShadeModel(GL_SMOOTH); glClearColor(0, 0, 0, 0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0, (float)szerokosc/(float)wysokosc, 1.0, 1000.0); /* Przejscie w tryb modyfikacji macierzy przeksztalcen geometrycznych */ glMatrixMode(GL_MODELVIEW); /* Zmiana macierzy znajdujacej sie na wierzcholku stosu na macierz jednostkowa */ glLoadIdentity(); } /* Funkcja klawiszy specjalnych */ void ObslugaKlawiszySpecjalnych(int klawisz, int x, int y) { switch(klawisz) { case GLUT_KEY_UP: //rotObsX = (rotObsX < 90.0) ? rotObsX + 1.0 : rotObsX; rotObsX = rotObsX + 2.0; break; case GLUT_KEY_DOWN: //rotObsX = (rotObsX > 0.0) ? rotObsX - 1.0 : rotObsX; rotObsX = rotObsX - 2.0; break; case GLUT_KEY_LEFT: //rotObsY = (rotObsY > -180.0) ? rotObsY - 1.0 : rotObsY; rotObsY = rotObsY - 2.0; break; case GLUT_KEY_RIGHT: //rotObsY = (rotObsY < 180.0) ? rotObsY + 1.0 : rotObsY; rotObsY = rotObsY + 2.0; break; case GLUT_KEY_PAGE_UP: zoom = (zoom <= -10.0) ? zoom + 5.0 : zoom; break; case GLUT_KEY_PAGE_DOWN: zoom = (zoom >= -200.0) ? zoom - 5.0 : zoom; break; } } /* Funkcja obslugi klawiatury */ void ObslugaKlawiatury(unsigned char klawisz, int x, int y) { switch(klawisz) { case '1': przycisk = 1; break; case '2': przycisk = 2; break; case '3': przycisk = 3; break; case '4': przycisk = 4; break; case '0': przycisk = 0; break; case 'p': pomocnicze = -pomocnicze; break; } if(klawisz == 27) exit(0); } /* Glowna funkcja programu */ int main(int argc, char **argv) { /* Info o aplikacji */ MessageBox(0,"Tryby: 1,2,3,4\nPauza: 0\nLinie pomocnicze: p\nEsc: wyjscie\nStrzalki: obracanie obrazu\nPgUp/PgDwn: Przyblizenie/oddalenie","Info",0); /* Zainicjowanie biblioteki GLUT */ glutInit(&argc, argv); /* Ustawienie trybu wyswietlania */ glutInitDisplayMode (GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); /* Ustawienie polozenia dolenego lewego rogu okna */ glutInitWindowPosition(100, 100); /* Ustawienie rozmiarow okna */ glutInitWindowSize(600, 400); /* Utworzenie okna */ glutCreateWindow("Cubes"); /* Odblokowanie bufora glebokosci */ glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); /* Ustawienie wartosci czyszczacej zawartosc bufora glebokosci */ glClearDepth(1000.0); /* Ustawienie koloru czyszczenia bufora ramki */ glClearColor (0.0, 0.0, 0.0, 0.0); /* Zarejestrowanie funkcji (callback) wyswietlajacej */ glutDisplayFunc(WyswietlObraz); /* Zarejestrowanie funkcji (callback) wywolywanej za kazdym razem kiedy zmieniane sa rozmiary okna */ glutReshapeFunc(UstawParametryWidoku); /* Zarejestrowanie funkcji wykonywanej gdy okno nie obsluguje zadnych zadan */ glutIdleFunc(WyswietlObraz); /* Zarejestrowanie funkcji obslugi klawiatury */ glutKeyboardFunc(ObslugaKlawiatury); /* Zarejestrowanie funkcji obslugi klawiszy specjalnych */ glutSpecialFunc(ObslugaKlawiszySpecjalnych); /* Zainicjowanie kwadryk tworzacych ramie robota */ InicjujRamieRobota(); /* Obsluga glownej petli programu (wywolywanie zarejestrowanych callbackow w odpowiedzi na odbierane zdarzenia lub obsluga stanu bezczynnosci) */ glutMainLoop(); return 0; }