Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <math.h>
- #define M_PI 3.14159265358979323846
- #include <time.h>
- #include <iostream>
- #include <gl/gl.h>
- #include <gl/glut.h>
- #include <cstdlib>
- //Definicja typu point3 - punkt w przestrzeni 3D
- typedef float point3[3];
- const float PI = 3.14159265;
- static GLfloat viewer[] = { 0.0, 0.0, 10.0 };
- // inicjalizacja położenia obserwatora
- static GLfloat fi = 0.0, // kąty obrotu, elewacja i azymut
- theta = 0.0;
- static GLfloat pix2angle_x, // przelicznik pikseli na stopnie
- pix2angle_y;
- static GLint status = 0; // stan klawiszy myszy
- // 0 - nie naciśnięto żadnego klawisza
- // 1 - naciśnięty został lewy klawisz, 2 - prawy
- static int x_pos_old = 0, // poprzednia pozycja kursora myszy
- y_pos_old = 0;
- static int delta_x = 0, // różnica pomiędzy pozycjami
- delta_y = 0; // i poprzednią kursora myszy
- //Przelacznik renderowania scian
- bool sciany[5] = { true, true, true, true, true };
- //Parametry programu
- float verLength = 2.0; //Dlugosc boku kwadratu
- float viewerR = 5.0; //Promien sfery obserwatora
- /*Funkcja wczytuje dane obrazu zapisanego w formacie TGA w pliku, alokuje
- pamięć i zwraca wskaźnik (pBits) do bufora w którym umieszczone są dane.
- Ponadto udostępnia (ImWidth), (ImHeight) obrazu tekstury oraz dane
- opisujące format obrazu według specyfikacji OpenGL (ImComponents) i
- (ImFormat).*/
- GLbyte* LoadTGAImage(const char* FileName, GLint* ImWidth, GLint
- * ImHeight, GLint* ImComponents, GLenum* ImFormat)
- {
- // Struktura dla nagłówka pliku TGA
- #pragma pack(1)
- typedef struct
- {
- GLbyte idlength;
- GLbyte colormaptype;
- GLbyte datatypecode;
- unsigned short colormapstart;
- unsigned short colormaplength;
- unsigned char colormapdepth;
- unsigned short x_orgin;
- unsigned short y_orgin;
- unsigned short width;
- unsigned short height;
- GLbyte bitsperpixel;
- GLbyte descriptor;
- }TGAHEADER;
- #pragma pack(8)
- FILE* pFile;
- TGAHEADER tgaHeader;
- unsigned long lImageSize;
- short sDepth;
- GLbyte* pbitsperpixel = NULL;
- // Wartości domyślne zwracane w przypadku błędu
- *ImWidth = 0;
- *ImHeight = 0;
- *ImFormat = GL_BGR_EXT;
- *ImComponents = GL_RGB8;
- fopen_s(&pFile, FileName, "rb");
- if (pFile == NULL)
- return NULL;
- // Przeczytanie nagłówka pliku
- fread(&tgaHeader, sizeof(TGAHEADER), 1, pFile);
- // Odczytanie szerokości, wysokości i głębi obrazu
- *ImWidth = tgaHeader.width;
- *ImHeight = tgaHeader.height;
- sDepth = tgaHeader.bitsperpixel / 8;
- // Sprawdzenie, czy głębia spełnia założone warunki (8, 24, lub 32 bity)
- if (tgaHeader.bitsperpixel != 8 && tgaHeader.bitsperpixel != 24 &&
- tgaHeader.bitsperpixel != 32)
- return NULL;
- // Obliczenie rozmiaru bufora w pamięci
- lImageSize = tgaHeader.width * tgaHeader.height * sDepth;
- // Alokacja pamięci dla danych obrazu
- pbitsperpixel = (GLbyte*)malloc(lImageSize * sizeof(GLbyte));
- if (pbitsperpixel == NULL)
- return NULL;
- if (fread(pbitsperpixel, lImageSize, 1, pFile) != 1)
- {
- free(pbitsperpixel);
- return NULL;
- }
- // Ustawienie formatu OpenGL
- switch (sDepth)
- {
- case 3:
- *ImFormat = GL_BGR_EXT;
- *ImComponents = GL_RGB8;
- break;
- case 4:
- *ImFormat = GL_BGRA_EXT;
- *ImComponents = GL_RGBA8;
- break;
- case 1:
- *ImFormat = GL_LUMINANCE;
- *ImComponents = GL_LUMINANCE8;
- break;
- };
- fclose(pFile);
- return pbitsperpixel;
- }
- //------------------------------------------------------------------------
- //Funkcja rysujaca ostroslup
- void Pyramid(float sX, float sY, float sZ) {
- //Ustawienie koloru
- glColor3f(1.0, 1.0, 1.0);
- //Rysowanie scian, poczawszy od podstawy i tylko jesli przelacznik dla sciany == true
- //Podstawa
- if (sciany[0]) {
- glBegin(GL_QUADS);
- glNormal3f(0.0, -1.0, 0.0);
- glTexCoord2f(0.0, 0.0);
- glVertex3f(sX, sY, sZ);
- glNormal3f(0.0, -1.0, 0.0);
- glTexCoord2f(1.0, 0.0);
- glVertex3f(sX + verLength, sY, sZ);
- glNormal3f(0.0, -1.0, 0.0);
- glTexCoord2f(1.0, 1.0);
- glVertex3f(sX + verLength, sY, sZ + verLength);
- glNormal3f(0.0, -1.0, 0.0);
- glTexCoord2f(0.0, 1.0);
- glVertex3f(sX, sY, sZ + verLength);
- glEnd();
- }
- //Sciana 1.
- if (sciany[1]) {
- glBegin(GL_TRIANGLES);
- glNormal3f(0.0, 0.0, -1.0);
- glTexCoord2f(0.0, 0.0);
- glVertex3f(sX, sY, sZ);
- glNormal3f(0.0, 0.0, -1.0);
- glTexCoord2f(1.0, 0.0);
- glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
- glNormal3f(0.0, 0.0, -1.0);
- glTexCoord2f(0.5, 0.5);
- glVertex3f(sX + verLength, sY, sZ);
- glEnd();
- }
- //Sciana 2.
- if (sciany[2]) {
- glBegin(GL_TRIANGLES);
- glNormal3f(1.0, 0.0, 0.0);
- glTexCoord2f(0.0, 0.0);
- glVertex3f(sX + verLength, sY, sZ);
- glNormal3f(1.0, 0.0, 0.0);
- glTexCoord2f(1.0, 0.0);
- glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
- glNormal3f(1.0, 0.0, 0.0);
- glTexCoord2f(0.5, 5.0);
- glVertex3f(sX + verLength, sY, sZ + verLength);
- glEnd();
- }
- //Sciana 3.
- if (sciany[3]) {
- glBegin(GL_TRIANGLES);
- glNormal3f(0.0, 0.0, 1.0);
- glTexCoord2f(0.0, 0.0);
- glVertex3f(sX + verLength, sY, sZ + verLength);
- glNormal3f(0.0, 0.0, 1.0);
- glTexCoord2f(1.0, 0.0);
- glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
- glNormal3f(0.0, 0.0, 1.0);
- glTexCoord2f(0.5, 0.5);
- glVertex3f(sX, sY, sZ + verLength);
- glEnd();
- }
- //Sciana 4.
- if (sciany[4]) {
- glBegin(GL_TRIANGLES);
- glNormal3f(-1.0, 0.0, 0.0);
- glTexCoord2f(0.0, 0.0);
- glVertex3f(sX, sY, sZ + verLength);
- glNormal3f(-1.0, 0.0, 0.0);
- glTexCoord2f(1.0, 0.0);
- glVertex3f(sX + verLength / 2, sY + 2.0, sZ + verLength / 2);
- glNormal3f(-1.0, 0.0, 0.0);
- glTexCoord2f(0.5, 0.5);
- glVertex3f(sX, sY, sZ);
- glEnd();
- }
- }
- // Funkcja rysująca osie układu współrzędnych
- void Axes(void)
- {
- point3 x_min = { -2.0, 0.0, 0.0 };
- point3 x_max = { 2.0, 0.0, 0.0 };
- // początek i koniec obrazu osi x
- point3 y_min = { 0.0, -2.0, 0.0 };
- point3 y_max = { 0.0, 2.0, 0.0 };
- // początek i koniec obrazu osi y
- point3 z_min = { 0.0, 0.0, -2.0 };
- point3 z_max = { 0.0, 0.0, 2.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; // modyfikacja kąta obrotu o kąt proporcjonalny
- fi += delta_y * pix2angle_y; // do różnicy położeń kursora myszy
- if (theta >= 360.0)
- theta = 0.0;
- if (fi >= 360.0)
- fi = 0.0;
- }
- else if (status == 2) { // jeśli prawy klawisz myszy wciśnięty
- viewerR += 0.1 * delta_y; // modyfikacja polozenia obserwatora(zoom)
- if (viewerR <= 3.0) // ograniczenie zblizenia
- viewerR = 3.0;
- if (viewerR >= 10.0) // ograniczenie oddalenia
- viewerR = 10.0;
- }
- //Wspolrzedne obserwatora - wzorki z ZSK
- viewer[0] = viewerR * cos(theta) * cos(fi);
- viewer[1] = viewerR * sin(fi);
- viewer[2] = viewerR * sin(theta) * cos(fi);
- gluLookAt(viewer[0], viewer[1], viewer[2], 0.0, 0.0, 0.0, 0.0, cos(fi),
- 0.0);
- // Zdefiniowanie położenia obserwatora
- Axes();
- // Narysowanie osi przy pomocy funkcji zdefiniowanej powyżej
- //Renderowanie trojkata
- Pyramid(-1.0, 0.0, -1.0);
- glutSwapBuffers();
- glFlush();
- // Przekazanie poleceń rysujących do wykonania
- }
- //Funkcja - callback dla klawiszy
- void Keys(unsigned char key, int x, int y)
- {
- //Zmiana rodzaju modelu w zaleznosci od klawisza
- if (key == '1') sciany[0] = !sciany[0];
- if (key == '2') sciany[1] = !sciany[1];
- if (key == '3') sciany[2] = !sciany[2];
- if (key == '4') sciany[3] = !sciany[3];
- if (key == '5') sciany[4] = !sciany[4];
- RenderScene();
- }
- // Funkcja ustalająca stan renderowania
- void MyInit(void)
- {
- glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
- // Kolor czyszcący (wypełnienia okna) ustawiono na czarny
- // Zmienne dla obrazu tekstury
- GLbyte* pBytes;
- GLint ImWidth, ImHeight, ImComponents;
- GLenum ImFormat;
- // Definicja materiału z jakiego zrobiony jest przedmiot
- //-------------------------------------------------------
- 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 = { 100.0 };
- // współczynnik n opisujący połysk powierzchni
- // Definicja źródła światła
- //-------------------------------------------------------
- GLfloat light_position[] = { 0.0, 0.0, 10.0, 1.0 };
- // położenie źródła
- GLfloat light_ambient[] = { 0.1f, 0.1f, 0.1f, 1.0f };
- // składowe intensywności świecenia źródła światła otoczenia
- // Ia = [Iar,Iag,Iab]
- GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
- // składowe intensywności świecenia źródła światła powodującego
- // odbicie dyfuzyjne Id = [Idr,Idg,Idb]
- GLfloat light_specular[] = { 1.0, 1.0, 1.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 };
- // składowa stała ds dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_linear = { 0.05f };
- // składowa liniowa dl dla modelu zmian oświetlenia w funkcji
- // odległości od źródła
- GLfloat att_quadratic = { 0.001f };
- // składowa kwadratowa dq dla modelu zmian oświetlenia w funkcji
- // odległości od źródł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 światł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);
- // 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_DEPTH_TEST); // włączenie mechanizmu z-bufora
- // Teksturowanie będzie prowadzone tyko po jednej stronie ściany
- glEnable(GL_CULL_FACE);
- // Przeczytanie obrazu tekstury z pliku o nazwie tekstura.tga
- pBytes = LoadTGAImage("tekstura.tga", &ImWidth, &ImHeight, &ImComponents, &ImFormat);
- if (pBytes == NULL)
- std::cout << "error";
- // Zdefiniowanie tekstury 2-D
- glTexImage2D(GL_TEXTURE_2D, 0, ImComponents, ImWidth, ImHeight, 0,
- ImFormat, GL_UNSIGNED_BYTE, pBytes);
- // Zwolnienie pamięci
- free(pBytes);
- // Włączenie mechanizmu teksturowania
- glEnable(GL_TEXTURE_2D);
- // Ustalenie trybu teksturowania
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- // Określenie sposobu nakładania tekstur
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- }
- // 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 * 0.1 / (float)horizontal; // przeliczenie pikseli na stopnie
- pix2angle_y = 360.0 * 0.1 / (float)vertical;
- glMatrixMode(GL_PROJECTION);
- // Przełączenie macierzy bieżącej na macierz projekcji
- glLoadIdentity();
- // Czyszcznie macierzy bieżącej
- gluPerspective(70.0, 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
- }
- // Funkcja "bada" stan myszy i ustawia wartosci 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
- y_pos_old = y; // jako pozycji poprzedniej
- 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
- // jako pozycji poprzedniej
- status = 2; //wciśnięty został prawy klawisz myszy
- }
- else
- status = 0; // nie został wciśnięty żaden klawisz
- }
- // Funkcja "monitoruje" polozenie kursora myszy i ustawia wartosci 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 poprzednie
- glutPostRedisplay(); // przerysowanie obrazu sceny
- }
- // Główny punkt wejścia programu. Program działa w trybie konsoli
- int main(int argc, char* argv[])
- {
- //Ziarno losowosci
- srand((unsigned)time(NULL));
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutInitWindowSize(1200, 800);
- glutCreateWindow("Teksturowanie");
- 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
- // Dla aktualnego okna ustala funkcję zwrotną odpowiedzialną
- // zazmiany rozmiaru okna
- glutReshapeFunc(ChangeSize);
- MyInit();
- // Funkcja MyInit() (zdefiniowana powyżej) wykonuje wszelkie
- // inicjalizacje konieczne przed przystąpieniem do renderowania
- glutMouseFunc(Mouse);
- // Ustala funkcję zwrotną odpowiedzialną za badanie stanu myszy
- glutMotionFunc(Motion);
- // Ustala funkcję zwrotną odpowiedzialną za badanie ruchu myszy
- //Rejestracja funkcji zwrotnej dla klawiatury
- glutKeyboardFunc(Keys);
- glutMainLoop();
- // Funkcja uruchamia szkielet biblioteki GLUT
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement