#include "glew.h" #include "freeglut.h" #include "glm.hpp" #include "ext.hpp" #include #include #include #include "Shader_Loader.h" #include "Render_Utils.h" #include "Camera.h" #include "Texture.h" #include "Physics.h" GLuint programColor; GLuint programTexture; Core::Shader_Loader shaderLoader; float appLoadingTime; obj::Model planeModel; obj::Model shipModel; obj::Model sphereModel; Core::RenderContext planeContext, shipContext, sphereContext; float cameraAngle = glm::radians(0.0f); glm::vec3 cameraPos = glm::vec3(0, 0 , 250); glm::vec3 cameraDir; glm::mat4 cameraMatrix, perspectiveMatrix; glm::vec3 lightDir = glm::normalize(glm::vec3(1.0f, -1.0f, -1.0f)); GLuint textureTest; GLuint textureEarth; GLuint textureAsteroid; GLuint textureShip; GLuint textureSun; GLuint textureEarthHighres; GLuint textureMoon; float frustumScale = 1.f; float orbitSpeed = 0.005f; void keyboard(unsigned char key, int x, int y) { float angleSpeed = 0.5f; float moveSpeed = 0.5f; switch(key) { //case 'z': cameraAngle -= angleSpeed; break; //case 'x': cameraAngle += angleSpeed; break; //case 'd': cameraPos += glm::cross(cameraDir, glm::vec3(0, 1, 0)) * moveSpeed; break; //case 'a': cameraPos -= glm::cross(cameraDir, glm::vec3(0, 1, 0)) * moveSpeed; break; //case 'e': cameraPos += glm::vec3(0, 1, 0) * moveSpeed; break; //case 'q': cameraPos -= glm::vec3(0, 1, 0) * moveSpeed; break; case 'w': if (orbitSpeed < 0.02f) { orbitSpeed += 0.001f; } break; case 's': if (orbitSpeed > 0.001f) { orbitSpeed -= 0.001f; } break; } } glm::mat4 createCameraMatrix() { float time = glutGet(GLUT_ELAPSED_TIME) / 1000.0f - appLoadingTime; // Obliczanie kierunku patrzenia kamery (w plaszczyznie x-z) przy uzyciu zmiennej cameraAngle kontrolowanej przez klawisze. cameraPos = glm::rotate(cameraPos, orbitSpeed, glm::vec3(0, 1, 0)); //cameraDir = glm::vec3(cosf(cameraAngle), 0.0f, sinf(cameraAngle)); cameraDir = glm::normalize(glm::vec3(0, 0, 0) - cameraPos); glm::vec3 up = glm::vec3(0, 1, 0); return Core::createViewMatrix(cameraPos, cameraDir, up); } void drawObjectColor(Core::RenderContext* context, glm::mat4 modelMatrix, glm::vec3 color) { GLuint program = programColor; glUseProgram(program); glUniform3f(glGetUniformLocation(program, "objectColor"), color.x, color.y, color.z); glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.z); glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(program, "modelViewProjectionMatrix"), 1, GL_FALSE, (float*)&transformation); glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); Core::DrawContext(*context); glUseProgram(0); } void drawObjectTexture(Core::RenderContext* context, glm::mat4 modelMatrix, GLuint textureId) { GLuint program = programTexture; glUseProgram(program); glUniform3f(glGetUniformLocation(program, "lightDir"), lightDir.x, lightDir.y, lightDir.z); Core::SetActiveTexture(textureId, "textureSampler", program, 0); glm::mat4 transformation = perspectiveMatrix * cameraMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(program, "modelViewProjectionMatrix"), 1, GL_FALSE, (float*)&transformation); glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); Core::DrawContext(*context); glUseProgram(0); } void renderScene() { float time = glutGet(GLUT_ELAPSED_TIME) / 1000.0f - appLoadingTime; // opcjonalny ruch swiatla do testow bool animateLight = false; if (animateLight) { float lightAngle = (glutGet(GLUT_ELAPSED_TIME) / 1000.0f) * 3.14 / 8; lightDir = glm::normalize(glm::vec3(sin(lightAngle), -1.0f, cos(lightAngle))); } // Aktualizacja macierzy widoku i rzutowania. cameraMatrix = createCameraMatrix(); perspectiveMatrix = Core::createPerspectiveMatrix(0.1f, 1000.f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.0f, 0.3f, 0.3f, 1.0f); //SHIP glm::mat4 shipModelMatrix = glm::translate(cameraPos + cameraDir * 0.6f + glm::vec3(0, -0.25f, 0)) * glm::rotate(-cameraAngle + glm::radians(90.0f), glm::vec3(0, 1, 0)); drawObjectTexture(&shipContext, shipModelMatrix, textureShip); //SUN //drawObjectTexture(&sphereModel, glm::translate(glm::vec3(0, 0, 0)) * glm::scale(glm::vec3(20.f)), textureSun); //EARTH nieruchoma - łatwiejsze dla naszej cutscenki drawObjectTexture(&sphereContext, glm::scale(glm::vec3(45)), textureEarthHighres); //MOON drawObjectTexture(&sphereContext, glm::rotate(time / 5.0f, glm::vec3(0, 1, 0)) * glm::translate(glm::vec3(0, 0, 300)) * glm::scale(glm::vec3(20)), textureMoon); glutSwapBuffers(); } void init() { glEnable(GL_DEPTH_TEST); programColor = shaderLoader.CreateProgram("shaders/shader_color.vert", "shaders/shader_color.frag"); programTexture = shaderLoader.CreateProgram("shaders/shader_tex.vert", "shaders/shader_tex.frag"); shipModel = obj::loadModelFromFile("models/ship.obj"); shipContext.initFromOBJ(shipModel); sphereModel = obj::loadModelFromFile("models/sphere.obj"); sphereContext.initFromOBJ(sphereModel); textureShip = Core::LoadTexture("textures/spaceship.png"); textureEarthHighres = Core::LoadTexture("textures/4k_earth_daymap.png"); textureAsteroid = Core::LoadTexture("textures/asteroid.png"); textureSun = Core::LoadTexture("textures/2k_sun_texture.png"); textureMoon = Core::LoadTexture("textures/2k_moon.png"); appLoadingTime = glutGet(GLUT_ELAPSED_TIME) / 1000.0f; } void shutdown() { shaderLoader.DeleteProgram(programColor); shaderLoader.DeleteProgram(programTexture); } void idle() { glutPostRedisplay(); } void onReshape(int width, int height) { frustumScale = (float)width / height; glViewport(0, 0, width, height); } int main(int argc, char ** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(200, 200); glutInitWindowSize(600, 600); glutCreateWindow("OpenGL Pierwszy Program"); glewInit(); init(); glutKeyboardFunc(keyboard); glutDisplayFunc(renderScene); glutIdleFunc(idle); glutReshapeFunc(onReshape); glutMainLoop(); shutdown(); return 0; }