Advertisement
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>
- #include <iostream>
- #define M_PI 3.14159265358979323846
- typedef float point3[3];
- static GLfloat viewer[] = { 0.0, 0.0, 10.0 };
- static GLfloat viewer2[] = { 0.0, 0.0, 10.0 };
- // inicjalizacja położenia obserwatora
- static GLfloat theta[] = { 0.0, 0.0, 0.0 }; // trzy kąty obrotu
- static GLfloat theta2[] = { 0.0, 0.0, 0.0 }; // trzy kąty obrotu
- static GLfloat pix2angle; // przelicznik pikseli na stopnie
- # define Npoint 20
- int model = 3; // 1- punkty, 2- siatka, 3 - wypełnione trójkąty
- static GLint status = 0; // stan klawiszy myszy
- // 0 - nie naciśnięto żadnego klawisza
- // 1 - naciśnięty zostać lewy klawisz
- // 2 - naciśnięty zostać prawy klawisz
- static int x_pos_old = 0; // poprzednia pozycja kursora myszy
- static int y_pos_old = 0; // poprzednia pozycja kursora myszy
- static int delta_x = 0; // różnica pomiędzy pozycją bieżącą z poprzednią kursora myszy
- static int delta_y = 0; // różnica pomiędzy pozycją bieżącą z poprzednią kursora myszy
- static GLfloat promien = 10;
- static GLfloat azymut = 0.0;
- static GLfloat elewacja = 0.0;
- // kopia, aby utworzyc kolejna os
- static int x_pos_old2 = 0; // poprzednia pozycja kursora myszy
- static int y_pos_old2 = 0; // poprzednia pozycja kursora myszy
- static int delta_x2 = 0; // różnica pomiędzy pozycją bieżącą z poprzednią kursora myszy
- static int delta_y2 = 0; // różnica pomiędzy pozycją bieżącą z poprzednią kursora myszy
- static GLfloat promien2 = 10;
- static GLfloat azymut2 = 0.0;
- static GLfloat elewacja2 = 0.0;
- static GLfloat color[10][3];
- const int n = 60;
- struct Point
- {
- float x, y, z;
- };
- /*************************************************************************************/
- // 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();
- }
- /*************************************************************************************/
- void Egg() {
- Point coords[n][n]; // koordynaty
- Point normal[n][n]; // Do wektora normalnego
- float xu, xv, zu, zv, yu, yv, length;
- for (int i = 0; i < n; i++)
- {
- float u = (float)i / (n - 1);
- for (int j = 0; j < n; j++)
- {
- float v = (float)j / (n - 1);
- // Wzory na obliczenie normalnych koor dla jajka
- coords[i][j].x = (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u)*cos(3.14*v);
- coords[i][j].y = 160 * pow(u, 4) - 320 * pow(u, 3) + 160 * pow(u, 2);
- coords[i][j].z = (-90 * pow(u, 5) + 225 * pow(u, 4) - 270 * pow(u, 3) + 180 * pow(u, 2) - 45 * u) * sin(3.14*v);
- // Wzory na obliczenie wektora normalnego
- xu = (-450 * pow(u, 4) + 900 * pow(u, 3) - 810 * pow(u, 2) + 360 * u - 45) * cos(3.14*v);
- xv = 3.14 * (90 * pow(u, 5) - 225 * pow(u, 4) + 270 * pow(u, 3) - 180 * pow(u, 2) + 45 * u)* sin(3.14*v);
- yu = 640 * pow(u, 3) - 960 * pow(u, 2) + 320 * u;
- yv = 0;
- zu = (-450 * pow(u, 4) + 900 * pow(u, 3) - 810 * pow(u, 2) + 360 * u - 45) * sin(3.14*v);
- zv = -3.14 * (90 * pow(u, 5) - 225 * pow(u, 4) + 270 * pow(u, 3) - 180 * pow(u, 2) + 45 * u)*cos(3.14*v);
- normal[i][j].x = yu * zv - zu * yv;
- normal[i][j].y = zu * xv - xu * zv;
- normal[i][j].z = xu * yv - yu * xv;
- // Potrzebne do normalizacji
- length = sqrt(pow(normal[i][j].x, 2) + pow(normal[i][j].y, 2) + pow(normal[i][j].z, 2));
- // Gora jajka
- if (i == n / 2) {
- normal[i][j].x = 0;
- normal[i][j].y = 1;
- normal[i][j].z = 0;
- }
- // Dol jajka
- else if (i == n || i == 0) {
- normal[i][j].x = 0;
- normal[i][j].y = -1;
- normal[i][j].z = 0;
- }
- else if (i < n / 2) {
- normal[i][j].x = normal[i][j].x / length;
- normal[i][j].y = normal[i][j].y / length;
- normal[i][j].z = normal[i][j].z / length;
- }
- else if (i > n / 2) {
- normal[i][j].x = -normal[i][j].x / length;
- normal[i][j].y = -normal[i][j].y / length;
- normal[i][j].z = -normal[i][j].z / length;
- }
- }
- }
- if (model == 3) {
- glBegin(GL_TRIANGLES);
- for (int i = 0; i < n - 1; i++)
- {
- GLfloat k = i / n;
- for (int j = 0; j < n - 1; j++)
- {
- GLfloat l = j / n;
- glNormal3f(normal[i][j].x, normal[i][j].y, normal[i][j].z);
- glTexCoord2f(k, l);
- glVertex3f(coords[i][j].x, coords[i][j].y - 5, coords[i][j].z);
- glNormal3f(normal[i][j + 1].x, normal[i][j + 1].y, normal[i][j + 1].z);
- glTexCoord2f(k, l + 1);
- glVertex3f(coords[i][j + 1].x, coords[i][j + 1].y - 5, coords[i][j + 1].z);
- glNormal3f(normal[i + 1][j].x, normal[i + 1][j].y, normal[i + 1][j].z);
- glTexCoord2f(k + 1, l);
- glVertex3f(coords[i + 1][j].x, coords[i + 1][j].y - 5, coords[i + 1][j].z);
- }
- }
- for (int i = 0; i < n - 1; i++)
- {
- for (int j = 0; j < n - 1; j++)
- {
- glNormal3f(normal[i + 1][j + 1].x, normal[i + 1][j + 1].y, normal[i + 1][j + 1].z);
- glVertex3f(coords[i + 1][j + 1].x, coords[i + 1][j + 1].y - 5, coords[i + 1][j + 1].z);
- glNormal3f(normal[i][j + 1].x, normal[i][j + 1].y, normal[i][j + 1].z);
- glVertex3f(coords[i][j + 1].x, coords[i][j + 1].y - 5, coords[i][j + 1].z);
- glNormal3f(normal[i + 1][j].x, normal[i + 1][j].y, normal[i + 1][j].z);
- glVertex3f(coords[i + 1][j].x, coords[i + 1][j].y - 5, coords[i + 1][j].z);
- }
- }
- }
- glEnd();
- }
- void RenderScene(void)
- {
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- // Czyszczenie okna aktualnym kolorem czyszczącym
- glLoadIdentity();
- // Czyszczenie macierzy bie??cej
- // dla lewego przycisku myszki
- viewer[0] = promien * cos(azymut) * cos(elewacja);
- viewer[1] = promien * sin(elewacja);
- viewer[2] = promien * sin(azymut) * cos(elewacja);
- if (elewacja > 3 * M_PI / 2) {
- gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
- }
- else if (elewacja > M_PI / 2) {
- gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
- }
- else {
- gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
- }
- if (status == 1) // jeśli lewy klawisz myszy wcięnięty
- {
- theta[0] += delta_x * pix2angle; // modyfikacja kąta obrotu o kat proporcjonalny do różnicy położeń kursora myszy
- theta[1] += delta_y * pix2angle; // modyfikacja kąta obrotu o kat proporcjonalny do różnicy położeń kursora myszy
- azymut += delta_x * 0.1;
- elewacja += delta_y * 0.1;
- if (elewacja > 2 * M_PI) {
- elewacja -= 2 * M_PI;
- }
- else if (elewacja < 0) {
- elewacja += 2 * M_PI;
- }
- else elewacja += delta_y * pix2angle * 0.01;
- }
- // prawy przycisk myszy
- else if (status == 2) {
- theta2[0] += delta_x2 * pix2angle; // modyfikacja kąta obrotu o kat proporcjonalny do różnicy położeń kursora myszy
- theta2[1] += delta_y2 * pix2angle; // modyfikacja kąta obrotu o kat proporcjonalny do różnicy położeń kursora myszy
- azymut2 += delta_x2 * 0.1;
- elewacja2 += delta_y2 * 0.1;
- if (elewacja2 > 2 * M_PI) {
- elewacja2 -= 2 * M_PI;
- }
- else if (elewacja2 < 0) {
- elewacja2 += 2 * M_PI;
- }
- else elewacja2 += delta_y2 * pix2angle * 0.01;
- GLfloat x = promien2 * cos(azymut2) * cos(elewacja2);
- GLfloat y = promien2 * sin(elewacja2);
- GLfloat z = promien2 * sin(azymut2) * cos(elewacja2);
- // niech zmienia sie pozycja tego oswietlenia
- GLfloat light_position2[] = { x, y, z, 1.0 };
- glLightfv(GL_LIGHT1, GL_POSITION, light_position2);
- }
- // Zdefiniowanie położenia obserwatora
- Axes();
- // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
- Egg();
- //glutSolidTeapot(3);
- // Narysowanie czajnika
- 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
- /*************************************************************************************/
- // Definicja materiału z jakiego zrobiony jest czajnik
- // i definicja źródła światła
- /*************************************************************************************/
- /*************************************************************************************/
- // Definicja materiału z jakiego zrobiony jest czajnik
- GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
- // współczynniki ka =[kar,kag,kab] dla światła otoczenia
- GLfloat mat_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
- // współczynniki kd =[kdr,kdg,kdb] światła rozproszonego
- GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
- // współczynniki ks =[ksr,ksg,ksb] dla światła odbitego
- GLfloat mat_shininess = { 150.0 };
- // współczynnik n opisujący połysk powierzchni
- /*************************************************************************************/
- // Definicja źródła światła
- GLfloat light_position[] = { 20.0, 0.0, 0.0, 1.0 };
- GLfloat light_position2[] = { -20.0, 0.0, 0.0, 1.0 };
- // położenie źródła
- GLfloat light_ambient[] = { 0.0, 0.1, 0.0, 1.0 };
- GLfloat light_ambient2[] = { 0.1, 0.0, 0.0, 1.0 };
- // składowe intensywności świecenia źródła światła otoczenia
- // Ia = [Iar,Iag,Iab]
- GLfloat light_diffuse[] = { 0.0, 1.0, 0.0, 1.0 };
- GLfloat light_diffuse2[] = { 1.0, 0.0, 0.0, 1.0 };
- // składowe intensywności świecenia źródła światła powodującego
- // odbicie dyfuzyjne Id = [Idr,Idg,Idb]
- GLfloat light_specular[] = { 0.0, 1.0, 0.0, 1.0 };
- GLfloat light_specular2[] = { 1.0, 0.0, 0.0, 1.0 };
- // składowe intensywności świecenia źródła światła powodującego
- // odbicie kierunkowe Is = [Isr,Isg,Isb]
- GLfloat att_constant = { 1.0 };
- GLfloat att_constant2 = { 1.0 };
- // składowa stała ds dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_linear = { 0.05 };
- GLfloat att_linear2 = { 0.05 };
- // składowa liniowa dl dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_quadratic = { 0.001 };
- GLfloat att_quadratic2 = { 0.001 };
- // składowa kwadratowa dq dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- /*************************************************************************************/
- // Ustawienie parametrów materiału i źródła światła
- /*************************************************************************************/
- // Ustawienie patrametrów materiału
- glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
- glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
- glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
- glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
- /*************************************************************************************/
- // Ustawienie parametrów źródła
- glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
- glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
- glLightfv(GL_LIGHT0, GL_POSITION, light_position);
- glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, att_constant);
- glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, att_linear);
- glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, att_quadratic);
- glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient2);
- glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse2);
- glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular2);
- glLightfv(GL_LIGHT1, GL_POSITION, light_position2);
- glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, att_constant2);
- glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, att_linear2);
- glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, att_quadratic2);
- /*************************************************************************************/
- // Ustawienie opcji systemu oświetlania sceny
- glShadeModel(GL_SMOOTH); // właczenie łagodnego cieniowania
- glEnable(GL_LIGHTING); // właczenie systemu oświetlenia sceny
- glEnable(GL_LIGHT0); // włączenie źródła o numerze 0
- glEnable(GL_LIGHT1); // włączenie źródła o numerze 1
- glEnable(GL_DEPTH_TEST); // włączenie mechanizmu z-bufora
- /*************************************************************************************/
- }
- /*************************************************************************************/
- // 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 = 360.0 / (float)horizontal; // przeliczenie pikseli na stopnie
- glMatrixMode(GL_PROJECTION);
- // Przełączenie macierzy bieżącej na macierz projekcji
- glLoadIdentity();
- // Czyszcznie macierzy bieżącej
- gluPerspective(70, 1.0, 1.0, 30.0);
- // Ustawienie parametrów dla rzutu perspektywicznego
- if (horizontal <= vertical)
- glViewport(0, (vertical - horizontal) / 2, horizontal, horizontal);
- else
- glViewport((horizontal - vertical) / 2, 0, vertical, 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
- }
- /*************************************************************************************/
- void RandColor() {
- for (int i = 0; i < 10; i++) {
- for (int j = 0; j < 3; j++)
- color[i][j] = (float)(rand() % 11) / 10;
- }
- }
- /*************************************************************************************/
- // 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; // przypisanie aktualnie odczytanej pozycji kursora jako pozycji poprzedniej
- status = 1; // wcięnięty został lewy klawisz myszy
- }
- else if (btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN)
- {
- y_pos_old2 = y; // przypisanie aktualnie odczytanej pozycji kursora jako pozycji poprzedniej
- x_pos_old2 = x; // przypisanie aktualnie odczytanej pozycji kursora jako pozycji poprzedniej
- status = 2; // wciśniety 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
- delta_y = y - y_pos_old; // obliczenie różnicy położenia kursora myszy
- x_pos_old = x; // podstawienie bieżącego położenia jako poprzednie
- y_pos_old = y; // podstawienie bieżącego położenia jako poprzednie
- delta_x2 = x - x_pos_old2; // obliczenie różnicy położenia kursora myszy
- delta_y2 = y - y_pos_old2; // obliczenie różnicy położenia kursora myszy
- x_pos_old2 = x; // podstawienie bieżącego położenia jako poprzednie
- y_pos_old2 = y; // podstawienie bieżącego położenia jako poprzednie
- glutPostRedisplay(); // przerysowanie obrazu sceny
- }
- // Główny punkt wejścia programu. Program działa w trybie konsoli
- /*************************************************************************************/
- // Główny punkt wejścia programu. Program działa w trybie konsoli
- int main(void)
- {
- RandColor();
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowSize(300, 300);
- glutCreateWindow("OpenGL - oświetlanie scen 3-D");
- 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
- glutMouseFunc(Mouse);
- // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
- glutMotionFunc(Motion);
- // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
- glutMainLoop();
- // Funkcja uruchamia szkielet biblioteki GLUT
- return 0;
- }
- /*************************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement