/*
gcc -o robot.exe -Wall robot.c glut32.lib -lopengl32 -lglu32
*/
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glut.h>
#include <time.h>
#include <windows.h>
#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)
}
/* 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;
}