Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*************************************************************************************/
- // Szkielet programu do tworzenia modelu sceny 3-D z wizualizacją osi
- // układu współrzędnych dla rzutowania perspektywicznego
- /*************************************************************************************/
- #include <windows.h>
- #include <gl/gl.h>
- #include <gl/glut.h>
- #include <math.h>
- typedef float point3[3];
- float pi = 3.14159265359;
- float bokKwadrat = 1.0; // długość boku kwadratu jednostkowego
- int n = 30; // do podziału kwadratu jednostkowego
- point3 **wspTab; // tablica współrzędnych
- point3 **kolorTab; // tablica kolorów
- int model = 3;
- static GLfloat viewer[] = { 0.0, 0.0, 10.0 }; // inicjalizacja położenia obserwatora
- static GLfloat theta = 0.0; // kąt azymutu (kierunek patrzenia na obiekt)
- static GLfloat phi = 0.0; // kat elewacji (wysokosc polozenia obserwatora nad horyzontem)
- static GLfloat pix2angle_x; // przelicznik pikseli na stopnie
- static GLfloat pix2angle_y;
- static GLfloat R = 10.0;
- static GLint status = 0; // stan klawiszy myszy
- // 0 - nie naciśnięto żadnego klawisza
- // 1 - naciśnięty zostać lewy klawisz
- // 2 - nacisniety zostal prawy klawisz
- static int x_pos_old = 0; // poprzednia pozycja kursora myszy
- static int y_pos_old = 0;
- static int delta_x = 0; // różnica pomiędzy pozycją bieżącą
- // i poprzednią kursora myszy
- static int delta_y = 0;
- // Obliczanie współrzędnych punktów
- float obliczX(float u, float v) {
- return (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u) * cos(v * pi);
- }
- float obliczY(float u, float v) {
- return (160 * pow(u, 4) - 320 * pow(u, 3) + 160 * pow(u, 2));
- }
- float obliczZ(float u, float v) {
- return (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u) * sin(v * pi);
- }
- void colors() {
- // Tablica kolorów
- kolorTab = new point3*[n + 1];
- for (int i = 0; i < n + 1; i++)
- kolorTab[i] = new point3[n + 1];
- for (int i = 0; i < n + 1; i++)
- for (int j = 0; j < n + 1; j++) {
- kolorTab[i][j][0] = ((float)((rand() % 100)*0.01));
- kolorTab[i][j][1] = ((float)((rand() % 100)*0.01));
- kolorTab[i][j][2] = ((float)((rand() % 100)*0.01));
- }
- }
- // Generowanie siatki punktów
- void siatkaPkt() {
- wspTab = new point3*[n + 1];
- for (int i = 0; i < n + 1; i++)
- wspTab[i] = new point3[n + 1];
- float u, v;
- for (int i = 0; i<n + 1; i++)
- for (int j = 0; j<n + 1; j++) {
- u = j * (bokKwadrat / n);
- v = i * (bokKwadrat / n);
- wspTab[i][j][0] = obliczX(u, v);
- wspTab[i][j][1] = obliczY(u, v) - 5;
- wspTab[i][j][2] = obliczZ(u, v);
- }
- }
- void Egg() {
- siatkaPkt();
- // Ustawienie koloru jaja (siatki, punktów)
- glColor3f(0.0, 0.5, 0.75);
- // Wybór trybu/modelu
- switch (model) {
- case 1: { // punkty
- glBegin(GL_POINTS);
- for (int i = 0; i<n; i++)
- for (int j = 0; j<n; j++)
- // wierzchołki odpowiadające punktom z tablicy współrzędnych punktów
- glVertex3fv(wspTab[i][j]);
- glEnd();
- }
- break;
- case 2: { // siatka
- for (int i = 0; i < n; i++)
- for (int j = 0; j < n; j++) {
- glBegin(GL_LINES);
- // pionowe
- glVertex3fv(wspTab[i][j]);
- glVertex3fv(wspTab[i][j + 1]);
- // poziome
- glVertex3fv(wspTab[i][j]);
- glVertex3fv(wspTab[i + 1][j]);
- // przekątne
- glVertex3fv(wspTab[i][j]);
- glVertex3fv(wspTab[i + 1][j + 1]);
- glEnd();
- }
- }
- break;
- case 3: { // trójkąty
- for (int i = 0; i < n; i++)
- for (int j = 0; j < n; j++) {
- glBegin(GL_TRIANGLES);
- // prawe trójkąty
- glColor3fv(kolorTab[i][j + 1]);
- glVertex3fv(wspTab[i][j + 1]);
- glColor3fv(kolorTab[i + 1][j]);
- glVertex3fv(wspTab[i + 1][j]);
- glColor3fv(kolorTab[i + 1][j + 1]);
- glVertex3fv(wspTab[i + 1][j + 1]);
- // lewe trójkąty
- glColor3fv(kolorTab[i][j]);
- glVertex3fv(wspTab[i][j]);
- glColor3fv(kolorTab[i + 1][j]);
- glVertex3fv(wspTab[i + 1][j]);
- glColor3fv(kolorTab[i][j + 1]);
- glVertex3fv(wspTab[i][j + 1]);
- glEnd();
- }
- }
- break;
- }
- }
- /*************************************************************************************/
- // Funkcja rysująca osie układu współrzędnych
- void Axes(void)
- {
- point3 x_min = { -5.0, 0.0, 0.0 };
- point3 x_max = { 5.0, 0.0, 0.0 };
- // początek i koniec obrazu osi x
- point3 y_min = { 0.0, -5.0, 0.0 };
- point3 y_max = { 0.0, 5.0, 0.0 };
- // początek i koniec obrazu osi y
- point3 z_min = { 0.0, 0.0, -5.0 };
- point3 z_max = { 0.0, 0.0, 5.0 };
- // początek i koniec obrazu osi y
- glColor3f(1.0f, 0.0f, 0.0f); // kolor rysowania osi - czerwony
- glBegin(GL_LINES); // rysowanie osi x
- glVertex3fv(x_min);
- glVertex3fv(x_max);
- glEnd();
- glColor3f(0.0f, 1.0f, 0.0f); // kolor rysowania - zielony
- glBegin(GL_LINES); // rysowanie osi y
- glVertex3fv(y_min);
- glVertex3fv(y_max);
- glEnd();
- glColor3f(0.0f, 0.0f, 1.0f); // kolor rysowania - niebieski
- glBegin(GL_LINES); // rysowanie osi z
- glVertex3fv(z_min);
- glVertex3fv(z_max);
- glEnd();
- }
- /*************************************************************************************/
- // Funkcja określająca co ma być rysowane (zawsze wywoływana, gdy trzeba
- // przerysować scenę)
- void RenderScene(void)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // Czyszczenie okna aktualnym kolorem czyszczącym
- glLoadIdentity();
- // Czyszczenie macierzy bieżącej
- if (status == 1) // jeśli lewy klawisz myszy wcięnięty
- {
- theta += delta_x*pix2angle_x/180;
- phi += delta_y*pix2angle_y/180;
- }
- else if (status == 2) // jeśli prawy klawisz myszy wciśnięty
- {
- R += 0.1 * delta_y; // skala przyblizania
- if (R <= 10.0) R = 10.0; // ograniczenie przyblizenia (im mniejsze, tym wieksze przybl)
- if (R >= 50.0) R = 50.0; // ograniczenie oddalenia (im wieksze, tym mniejsze oddalenie)
- }
- viewer[0] = R * cos(theta) * cos(phi);
- viewer[1] = R * sin(phi);
- viewer[2] = R * sin(theta) * cos(phi);
- gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, cos(phi), 0.0);
- // Zdefiniowanie położenia obserwatora
- // pierwsze trzy - wspolrzedne obserwatora,
- // kolejne trzy - definiuja punkt na ktory obserwator patrzy
- // ostatnie trzy - wektor pozwalajacy na podanie skrócenia trzymanej przez obserwatora kamery
- Axes();
- // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
- glColor3f(1.0f, 1.0f, 1.0f);
- // Ustawienie koloru rysowania na biały
- Egg();
- // Narysowanie jajka
- glFlush();
- // Przekazanie poleceń rysujących do wykonania
- glutSwapBuffers();
- }
- /*************************************************************************************/
- // Funkcja ustalająca stan renderowania
- void MyInit(void)
- {
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- // Kolor czyszczący (wypełnienia okna) ustawiono na czarny
- }
- /*************************************************************************************/
- // Funkcja ma za zadanie utrzymanie stałych proporcji rysowanych
- // w przypadku zmiany rozmiarów okna.
- // Parametry vertical i horizontal (wysokość i szerokość okna) są
- // przekazywane do funkcji za każdym razem gdy zmieni się rozmiar okna.
- void ChangeSize(GLsizei horizontal, GLsizei vertical)
- {
- pix2angle_x = 360.0 / (float)horizontal; // przeliczenie pikseli na stopnie
- pix2angle_y = 360.0 / (float)vertical; // przeliczenie pikseli na stopnie
- GLdouble aspect; // proporcja w/h okresla proporcje wymiarow okna
- glViewport(0, 0, horizontal, vertical);
- glMatrixMode(GL_PROJECTION);
- // Przełączenie macierzy bieżącej na macierz projekcji
- glLoadIdentity();
- // Czyszcznie macierzy bieżącej
- aspect = (GLfloat)horizontal / (GLfloat)vertical;
- gluPerspective(70, aspect, 1.0, 90.0); // Ustawienie parametrów dla rzutu perspektywicznego
- // (fovy, aspect, zNear, zFar)
- // (kąt, stosunek szerokości do wysokości, odległość od okna, odległość od rzutni)
- if (horizontal <= vertical)
- glViewport(0, 0, horizontal, vertical);
- else
- glViewport(0, 0, horizontal, vertical);
- // Ustawienie wielkości okna okna widoku (viewport) w zależności
- // relacji pomiędzy wysokością i szerokością okna
- glMatrixMode(GL_MODELVIEW);
- // Przełączenie macierzy bieżącej na macierz widoku modelu
- glLoadIdentity();
- // Czyszczenie macierzy bieżącej
- }
- /*************************************************************************************/
- // Funkcja "bada" stan myszy i ustawia wartości odpowiednich zmiennych globalnych
- void Mouse(int btn, int state, int x, int y)
- {
- if (btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
- {
- x_pos_old = x; // przypisanie aktualnie odczytanej pozycji kursora
- // jako pozycji poprzedniej
- y_pos_old = y;
- status = 1; // wcięnięty został lewy klawisz myszy
- }
- else if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN) {
- y_pos_old = y; // przypisanie aktualnie odczytanej pozycji kursora
- status = 2; // wcięnięty został prawy klawisz myszy
- }
- else
- status = 0; // nie został wcięnięty żaden klawisz
- }
- /*************************************************************************************/
- // Funkcja "monitoruje" położenie kursora myszy i ustawia wartości odpowiednich
- // zmiennych globalnych
- void Motion(GLsizei x, GLsizei y)
- {
- delta_x = x - x_pos_old; // obliczenie różnicy położenia kursora myszy
- x_pos_old = x; // podstawienie bieżącego położenia jako poprzednie
- delta_y = y - y_pos_old;
- y_pos_old = y;
- glutPostRedisplay(); // przerysowanie obrazu sceny
- }
- /*************************************************************************************/
- /*************************************************************************************/
- // Funkcja zwrotna dla klawiszy
- void Keys(unsigned char key, int x, int y) {
- // zmiana modelu wyświetlania
- if (key == 'p' || key == '1') model = 1;
- if (key == 's' || key == '2') model = 2;
- if (key == 't' || key == '3') model = 3;
- RenderScene();
- }
- /*************************************************************************************/
- // Główny punkt wejścia programu. Program działa w trybie konsoli
- void main(void){
- FreeConsole();
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowSize(600, 600);
- glutCreateWindow("Rzutowanie perspektywiczne");
- glutMouseFunc(Mouse);
- // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
- glutMotionFunc(Motion);
- // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
- colors();
- glutDisplayFunc(RenderScene);
- // Określenie, że funkcja RenderScene będzie funkcją zwrotną
- // (callback function). Będzie ona wywoływana za każdym razem
- // gdy zajdzie potrzeba przerysowania okna
- glutReshapeFunc(ChangeSize);
- // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
- // za zmiany rozmiaru okna
- MyInit();
- // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
- // inicjalizacje konieczne przed przystąpieniem do renderowania
- glEnable(GL_DEPTH_TEST);
- // Włączenie mechanizmu usuwania niewidocznych elementów sceny
- glutKeyboardFunc(Keys);
- // Funkcja ta rejestruje funkcje zwrotną
- glutMainLoop();
- // Funkcja uruchamia szkielet biblioteki GLUT
- }
- /*************************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment