/* Niniejszy program jest wolnym oprogramowaniem; możesz go rozprowadzać dalej i / lub modyfikować na warunkach Powszechnej Licencji Publicznej GNU, wydanej przez Fundację Wolnego Oprogramowania - według wersji 2 tej Licencji lub(według twojego wyboru) którejś z późniejszych wersji. Niniejszy program rozpowszechniany jest z nadzieją, iż będzie on użyteczny - jednak BEZ JAKIEJKOLWIEK GWARANCJI, nawet domyślnej gwarancji PRZYDATNOŚCI HANDLOWEJ albo PRZYDATNOŚCI DO OKREŚLONYCH ZASTOSOWAŃ.W celu uzyskania bliższych informacji sięgnij do Powszechnej Licencji Publicznej GNU. Z pewnością wraz z niniejszym programem otrzymałeś też egzemplarz Powszechnej Licencji Publicznej GNU(GNU General Public License); jeśli nie - napisz do Free Software Foundation, Inc., 59 Temple Place, Fifth Floor, Boston, MA 02110 - 1301 USA */ #define GLM_FORCE_RADIANS #define GLEW_STATIC #include #include #include #include #include #include #include #include #include "constants.h" #include "allmodels.h" #include "mycube.h" using namespace glm; float aspect=1.0f; //Aktualny stosunek szerokości do wysokości okna float speed_x=0; //Szybkość kątowa obrotu obiektu w radianach na sekundę wokół osi x float speed_y=0; //Szybkość kątowa obrotu obiektu w radianach na sekundę wokół osi y GLuint tex; //Uchwyt – deklaracja globalna //Procedura obsługi błędów void error_callback(int error, const char* description) { fputs(description, stderr); } //Procedura obługi zmiany rozmiaru bufora ramki void windowResize(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); //Obraz ma być generowany w oknie o tej rozdzielczości aspect=(float)width/(float)height; //Stosunek szerokości do wysokości okna } //Procedura obsługi klawiatury void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods){ if (action == GLFW_PRESS) { if (key == GLFW_KEY_LEFT) speed_y=PI/2; if (key == GLFW_KEY_RIGHT) speed_y=-PI/2; if (key == GLFW_KEY_UP) speed_x=PI/2; if (key == GLFW_KEY_DOWN) speed_x=-PI/2; } if (action == GLFW_RELEASE) { if (key == GLFW_KEY_LEFT) speed_y=0; if (key == GLFW_KEY_RIGHT) speed_y=0; if (key == GLFW_KEY_UP) speed_x=0; if (key == GLFW_KEY_DOWN) speed_x=0; } } //Procedura inicjująca void initOpenGLProgram(GLFWwindow* window) { //************Tutaj umieszczaj kod, który należy wykonać raz, na początku programu************ glfwSetFramebufferSizeCallback(window, windowResize); //Zarejestruj procedurę obsługi zmiany rozdzielczości bufora ramki glfwSetKeyCallback(window, key_callback); //Zarejestruj procedurę obsługi klawiatury glClearColor(0,0,0,1); //Ustaw kolor czyszczenia ekranu glEnable(GL_LIGHTING); //Włącz tryb cieniowania glEnable(GL_LIGHT0); //Włącz zerowe źródło światła glEnable(GL_DEPTH_TEST); //Włącz używanie budora głębokości //glEnable(GL_COLOR_MATERIAL); //Włącz śledzenie kolorów przez materiał glEnable(GL_TEXTURE_2D); glEnable(GL_NORMALIZE); //Wczytanie i import obrazka – w initOpenGLProgram //Wczytanie do pamięci komputera std::vector image; //Alokuj wektor do wczytania obrazka unsigned width, height; //Zmienne do których wczytamy wymiary obrazka //Wczytaj obrazek unsigned error = lodepng::decode(image, width, height, "bricks.png"); //Import do pamięci karty graficznej glGenTextures(1,&tex); //Zainicjuj jeden uchwyt glBindTexture(GL_TEXTURE_2D, tex); //Uaktywnij uchwyt //Wczytaj obrazek do pamięci KG skojarzonej z uchwytem glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (unsigned char*) image.data()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } //Procedura rysująca zawartość sceny void drawScene(GLFWwindow* window,float angle_x,float angle_y) { //************Tutaj umieszczaj kod rysujący obraz******************l float ambientemmisio[]={0,0,0,1}; float ambientemmisio2[]={0,0,0,1}; float difussion[]={0.7,0.5,0.5,1}; float specular[] = {0,0,0,1}; glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //Wyczyść bufor kolorów (czyli przygotuj "płótno" do rysowania) //***Przygotowanie do rysowania**** mat4 P=perspective(50.0f*PI/180.0f,aspect,1.0f,50.0f); //Wylicz macierz rzutowania P mat4 V=lookAt( //Wylicz macierz widoku vec3(0.0f,0.0f,-5.0f), vec3(0.0f,0.0f,0.0f), vec3(0.0f,1.0f,0.0f)); glMatrixMode(GL_PROJECTION); //Włącz tryb modyfikacji macierzy rzutowania glLoadMatrixf(value_ptr(P)); //Załaduj macierz rzutowania glMatrixMode(GL_MODELVIEW); //Włącz tryb modyfikacji macierzy model-widok //Rysowanie kostki mat4 M=mat4(1.0f); M=rotate(M,angle_x,vec3(1.0f,0.0f,0.0f)); M=rotate(M,angle_y,vec3(0.0f,1.0f,0.0f)); glLoadMatrixf(value_ptr(V)); float lightPos[]={0,0,-6,1}; float lightPos2[]= {0,0,1,0}; glLightfv(GL_LIGHT0,GL_POSITION,lightPos); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,lightPos2); glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,10); glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,128); float test[]={0.1,0.1,0.1,0.1}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT,test), glLoadMatrixf(value_ptr(V*M)); //glColor3d(0,1,0); //Models::cube.drawSolid(); glBindTexture(GL_TEXTURE_2D,tex); Models::detailedCube.drawSolid(); // glEnableClientState( GL_VERTEX_ARRAY ); //glEnableClientState(GL_TEXTURE_COORD_ARRAY); //glEnableClientState( GL_NORMAL_ARRAY ); //glEnableClientState( GL_COLOR_ARRAY ); //glVertexPointer( 3, GL_FLOAT, 0, myCubeVertices); //glTexCoordPointer( 2, GL_FLOAT, 0, myCubeTexColors); //glNormalPointer( GL_FLOAT, 0, myCubeVertices); glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,ambientemmisio); glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,ambientemmisio); glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,specular); glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,difussion); glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50 ); //glColorPointer( 3, GL_FLOAT, 0, myCubeColors); //glDrawArrays(GL_QUADS,0, myCubeVertexCount); //glDisableClientState( GL_VERTEX_ARRAY ); //glDisableClientState( GL_COLOR_ARRAY ); //glDisableClientState(GL_TEXTURE_COORD_ARRAY); //glDisableClientState( GL_NORMAL_ARRAY ); glfwSwapBuffers(window); //Przerzuć tylny bufor na przedni } int main(void) { GLFWwindow* window; //Wskaźnik na obiekt reprezentujący okno glfwSetErrorCallback(error_callback);//Zarejestruj procedurę obsługi błędów if (!glfwInit()) { //Zainicjuj bibliotekę GLFW fprintf(stderr, "Nie można zainicjować GLFW.\n"); exit(EXIT_FAILURE); } window = glfwCreateWindow(500, 500, "OpenGL", NULL, NULL); //Utwórz okno 500x500 o tytule "OpenGL" i kontekst OpenGL. if (!window) //Jeżeli okna nie udało się utworzyć, to zamknij program { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); //Od tego momentu kontekst okna staje się aktywny i polecenia OpenGL będą dotyczyć właśnie jego. glfwSwapInterval(1); //Czekaj na 1 powrót plamki przed pokazaniem ukrytego bufora GLenum err; if ((err=glewInit()) != GLEW_OK) { //Zainicjuj bibliotekę GLEW fprintf(stderr, "Nie można zainicjować GLEW: %s\n", glewGetErrorString(err)); exit(EXIT_FAILURE); } initOpenGLProgram(window); //Operacje inicjujące float angle_x=0.0f; //Aktualny kąt obrotu obiektu wokół osi x float angle_y=0.0f; //Aktualny kąt obrotu obiektu wokół osi y glfwSetTime(0); //Wyzeruj timer //Główna pętla while (!glfwWindowShouldClose(window)) //Tak długo jak okno nie powinno zostać zamknięte { angle_x+=speed_x*glfwGetTime(); //Oblicz przyrost kąta obrotu i zwiększ aktualny kąt angle_y+=speed_y*glfwGetTime(); //Oblicz przyrost kąta obrotu i zwiększ aktualny kąt glfwSetTime(0); //Wyzeruj timer drawScene(window,angle_x,angle_y); //Wykonaj procedurę rysującą glfwPollEvents(); //Wykonaj procedury callback w zalezności od zdarzeń jakie zaszły. } //Usunięcie tekstury z pamięci karty graficznej – po głownej pętli glDeleteTextures(1,&tex); glfwDestroyWindow(window); //Usuń kontekst OpenGL i okno glfwTerminate(); //Zwolnij zasoby zajęte przez GLFW exit(EXIT_SUCCESS); }