Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*************************************************************************************/
- // Jajko 3-D
- /*************************************************************************************/
- #include "stdafx.h"
- #include <windows.h>
- #include <math.h>
- #include <gl/gl.h>
- #include <gl/glut.h>
- #define PI 3.1415926
- typedef float point3[3];
- bool fullscreenMode = false;
- typedef float point3[3];
- static GLfloat viewer[]= {0.0, 0.0, 10.0};
- // inicjalizacja położenia obserwatora
- static GLfloat thetaX = 0.0; // kąt obrotu obiektu wokol osi X
- static GLfloat thetaY = 0.0; // kąt obrotu obiektu wokol osi X
- static GLfloat pix2angle; // przelicznik pikseli na stopnie
- static GLint status = 0; // stan klawiszy myszy
- // 0 - nie naciśnięto żadnego klawisza
- // 1 - naciśnięty został lewy klawisz
- static GLint x_pos_old=0; // poprzednia pozycja X kursora myszy
- static GLint y_pos_old=0; // poprzednia pozycja Y kursora myszy
- static GLint delta_x = 0; // różnica pomiędzy pozycją bieżącą
- // i poprzednią kursora myszy dla osi X
- static GLint delta_y = 0; // różnica pomiędzy pozycją bieżącą
- // i poprzednią kursora myszy dla osi Y
- static GLfloat scale = 0.1;
- int N = 50;
- int model = 1;
- /*************************************************************************************/
- // 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 "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;
- status = 2;
- }
- 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żacego położenia jako poprzednie
- delta_y=y-y_pos_old; // obliczenie różnicy położenia kursora myszy
- y_pos_old=y; // podstawienie bieżacego położenia jako popr
- glutPostRedisplay(); // przerysowanie obrazu sceny
- }
- /*************************************************************************************/
- //
- float*** fillColor(int N)
- {
- const int D = 3;
- float ***color;
- // alokacja pamieci
- color = new float** [N];
- for (int i=0; i<N; i++)
- {
- color[i] = new float* [N];
- for (int j=0; j<N; j++)
- {
- color[i][j] = new float [N];
- for (int k=0; k<D; k++)
- color[i][j][k] = ((float)(rand() % 100)) * 0.01; // wylosowanie koloru
- }
- }
- for(int i=N/2; i<N; i++)
- {
- for (int k=0; k<D; k++)
- {
- color[i][0][k] = color[N-i-1][N-1][k];
- color[i][N-1][k] = color[N-i-1][0][k];
- }
- }
- return color;
- }
- void drawEgg(int N)
- {
- // alokacja pamieci
- const int D = 3;
- float ***color;
- if (model == 3)
- color = fillColor(N);
- float ***tab = new float** [N];
- for (int i=0; i<N; i++)
- {
- tab[i] = new float* [N];
- for (int j=0; j<N; j++)
- tab[i][j] = new float [N];
- }
- glColor3f(1.0f, 1.0f, 0.0f);
- for (int i=0; i<N; i++)
- {
- for (int j=0; j<N; j++)
- {
- float u = (float) i/(N-1);
- float v = (float) j/(N-1);
- float temp = (-90.0 * pow(u,5) + 225.0 * pow(u,4) - 270.0 * pow(u,3)
- + 180.0 * pow(u,2) - 45.0 * u);
- tab[i][j][0] = temp * cos(PI * v);
- tab[i][j][1] = (160.0 * pow(u,4) - 320.0 * pow(u,3) + 160.0 * pow(u,2) - 5.0);
- tab[i][j][2] = temp * sin(PI * v);
- switch (model)
- {
- case 1: // chmura punktow
- glBegin(GL_POINTS);
- glVertex3fv(tab[i][j]);
- glEnd();
- break;
- case 2: // siatka
- if (i>0 && j>0)
- {
- glBegin(GL_LINES);
- // odcinki pionowe
- glVertex3fv(tab[i-1][j]);
- glVertex3fv(tab[i][j]);
- // odcinki poziome
- glVertex3fv(tab[i][j-1]);
- glVertex3fv(tab[i][j]);
- // odcinki ukosne
- if (i<N/2)
- {
- glVertex3fv(tab[i-1][j]);
- glVertex3fv(tab[i][j-1]);
- }
- else
- {
- glVertex3fv(tab[i-1][j-1]);
- glVertex3fv(tab[i][j]);
- }
- glEnd();
- }
- break;
- case 3: // trojkaty
- if (i>0 && j>0)
- {
- if (i < N/2)
- {
- glBegin(GL_TRIANGLES);
- glColor3fv(color[i-1][j-1]);
- glVertex3fv(tab[i-1][j-1]);
- glColor3fv(color[i][j-1]);
- glVertex3fv(tab[i][j-1]);
- glColor3fv(color[i-1][j]);
- glVertex3fv(tab[i-1][j]);
- glColor3fv(color[i][j]);
- glVertex3fv(tab[i][j]);
- glColor3fv(color[i][j-1]);
- glVertex3fv(tab[i][j-1]);
- glColor3fv(color[i-1][j]);
- glVertex3fv(tab[i-1][j]);
- glEnd();
- }
- else
- {
- glBegin(GL_TRIANGLES);
- glColor3fv(color[i-1][j-1]);
- glVertex3fv(tab[i-1][j-1]);
- glColor3fv(color[i][j-1]);
- glVertex3fv(tab[i][j-1]);
- glColor3fv(color[i][j]);
- glVertex3fv(tab[i][j]);
- glColor3fv(color[i-1][j-1]);
- glVertex3fv(tab[i-1][j-1]);
- glColor3fv(color[i-1][j]);
- glVertex3fv(tab[i-1][j]);
- glColor3fv(color[i][j]);
- glVertex3fv(tab[i][j]);
- glEnd();
- }
- }
- break;
- }
- }
- }
- //dealokacja pamieci
- for (int i=0; i<N; i++)
- {
- for (int j=0; j<N; j++)
- {
- delete [] tab[i][j];
- }
- delete [] tab[i];
- }
- delete [] tab;
- if (model == 3)
- {
- for (int i=0; i<N; i++)
- {
- for (int j=0; j<N; j++)
- delete [] color[i][j];
- delete [] color[i];
- }
- delete [] color;
- }
- }
- int getLength(void *font, char *txt)
- /* Funkcja zwraca rzeczywista dlugosc tekstu odrysowywanego na ekranie. Potrzebna
- do wyrownywania tekstu (do lewej, srodek, do prawej).
- Parametry:
- - void *font = czcionka, mozliwe typy: GLUT_STROKE_ROMAN, GLUT_STROKE_MONO_ROMAN
- - char *txt = tekst, ktorego dlugosc jest zwracana */
- {
- int length = 0;
- int i;
- int len=strlen(txt);
- for (i=0; i<len; i++)
- {
- length += glutStrokeWidth(font, txt[i]);
- // glutStrokeWidth zwraca dlugosc pojedynczego znaku
- }
- return length;
- }
- enum TAlign {LEFT, CENTER, RIGHT};
- // wyrownanie tekstu: LEFT (do lewej), CENTER (wysrodkowane), RIGHT (do prawej)
- void printText(GLfloat x, GLfloat y, void *font, char *txt, TAlign align = LEFT, GLfloat scale = 1, GLfloat lineWidth = 1)
- {
- int length = getLength(font, txt) * scale;
- if (align == CENTER)
- x -= length/2;
- else if (align == RIGHT)
- x -= length;
- glLineWidth(lineWidth); // ustawienie grubosci linii
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_LINE_SMOOTH);
- glPushMatrix();
- glTranslatef(x, y, 0); // przesuniecie o wektor
- glScalef(scale, scale, scale); // skalowanie
- int i;
- int len=strlen(txt);
- for (i=0; i<len; i++)
- {
- glutStrokeCharacter(font, txt[i]); // rysowanie pojedynczego znaku
- }
- glPopMatrix();
- }
- // 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
- gluLookAt(viewer[0],viewer[1],viewer[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
- // Zdefiniowanie położenia obserwatora
- Axes();
- // Narysowanie osi przy pomocy funkcji zdefiniowanej wyżej
- char txt[10] = "N = ";
- char tmp[5];
- itoa(N, tmp, 10);
- strcat(txt, tmp);
- glColor3f(1.0f, 1.0f, 1.0f);
- // Ustawienie koloru rysowania na biały
- printText(0.0, 6.1, GLUT_STROKE_ROMAN, txt, CENTER, 0.007, 3.0);
- if(status == 1) // jeśli lewy klawisz myszy wciśnięty
- {
- thetaX += delta_x*pix2angle; // modyfikacja kąta obrotu o kąt proporcjonalny
- thetaY += delta_y*pix2angle; // do różnicy położeń kursora myszy
- }
- if (status == 2)
- {
- viewer[2] += delta_y * scale;
- }
- glRotatef(thetaX, 0.0, 1.0, 0.0); //obrót obiektu o nowy kąt X
- glRotatef(thetaY, 1.0, 0.0, 0.0); //obrót obiektu o nowy kąt Y
- glColor3f(1.0f, 1.0f, 1.0f);
- // Ustawienie koloru rysowania na biały
- drawEgg(N);
- glFlush();
- // Przekazanie poleceń rysujących do wykonania
- glutSwapBuffers();
- }
- void keyboard(unsigned char key, int x, int y)
- {
- if (key == '1')
- model = 1;
- if (key == '2')
- model = 2;
- if (key == '3')
- model = 3;
- if (key == '+')
- N++;
- if (key == '-' && N>3)
- N--;
- if(key==27 && fullscreenMode)
- {
- glutLeaveGameMode();
- exit(0);
- }
- RenderScene(); // przerysowanie obrazu sceny
- }
- /*************************************************************************************/
- // Funkcja ustalająca stan renderowania
- void MyInit(void)
- {
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- // Kolor czyszcą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 = 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
- }
- /*************************************************************************************/
- // Główny punkt wejścia programu. Program działa w trybie konsoli
- int _tmain(int argc, _TCHAR* argv[])
- {
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB |GLUT_DEPTH);
- if (!fullscreenMode)
- {
- glutInitWindowSize(300, 300);
- glutCreateWindow("Jajko 3D");
- //Utworzenie okna i określenie treści napisu w nagłówku okna
- }
- if (fullscreenMode)
- {
- glutGameModeString( "1280x1024:32@75" );
- glutEnterGameMode();
- }
- glutDisplayFunc(RenderScene);
- // Określenie, że funkcja RenderScene będzie funkcją zwrotną
- // (callback function). Bedzie ona wywoływana za każdym razem
- // gdy zajdzie potrzba przeryswania okna
- glutReshapeFunc(ChangeSize);
- // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
- // zazmiany rozmiaru okna
- MyInit();
- // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
- // inicjalizacje konieczne przed przystąpieniem do renderowania
- glutKeyboardFunc(keyboard);
- // Ustala funkcję zwrotną odpowiedzialną za badanie stanu klawiatury
- glutMouseFunc(Mouse);
- // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
- glutMotionFunc(Motion);
- // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
- glEnable(GL_DEPTH_TEST);
- // Włączenie mechanizmu usuwania niewidocznych elementów sceny
- glutMainLoop();
- // Funkcja uruchamia szkielet biblioteki GLUT
- return 0;
- }
- /*************************************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement