#include "glew.h" #include #include "glm.hpp" #include "ext.hpp" #include #include #include #include "Shader_Loader.h" #include "Render_Utils.h" #include "Texture.h" #include "Box.cpp" #include #include #include #include const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024; int WIDTH = 900, HEIGHT = 900; namespace models { Core::RenderContext spaceshipContext; Core::RenderContext sphereContext; Core::RenderContext windowFrame; Core::RenderContext bookShelf; Core::RenderContext window; Core::RenderContext potPlant; Core::RenderContext officeChair; Core::RenderContext lamp; Core::RenderContext door; Core::RenderContext ceilingLamp; Core::RenderContext desk; Core::RenderContext bed; } namespace textures { GLuint sunTexture; GLuint windowFrameTexture; GLuint bookShelfTexture; GLuint potPlantTexture; GLuint officeChariTexture; GLuint lampTexture; GLuint doorTexture; GLuint deskTexture; GLuint ceilingLampTexture; GLuint bedTexture; GLuint flashlightTexture; } GLuint depthMapFBO; GLuint depthMap; GLuint program; GLuint programSun; GLuint programTex; GLuint programDepth; GLuint programSkybox; bool flashOff = false; double prevTime = 0.0; double currTime = 0.0; double timeDiff; unsigned int counter = 0; glm::vec3 position = glm::vec3(0, 0, 5); float horizontalAngle = 3.14f; float verticalAngle = 0.0f; float speed = 0.1f; float sensitivity = 100.0f; double xpos, ypos; glm::vec3 Position; glm::vec3 Orientation = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 Up = glm::vec3(0.0f, 1.0f, 0.0f); Core::Shader_Loader shaderLoader; Core::RenderContext shipContext; Core::RenderContext sphereContext; glm::vec3 sunPos = glm::vec3(-4.740971f, 2.149999f, 0.369280f); glm::vec3 sunDir = glm::vec3(-0.93633f, 0.351106, 0.003226f); glm::vec3 sunColor = glm::vec3(0.9f, 0.9f, 0.7f)*5; glm::vec3 cameraPos = glm::vec3(0.479490f, 1.250000f, -2.124680f); glm::vec3 cameraDir = glm::vec3(-0.354510f, 0.000000f, 0.935054f); glm::vec3 spaceshipPos = glm::vec3(0.065808f, 1.250000f, -2.189549f); glm::vec3 spaceshipDir = glm::vec3(-0.490263f, 0.000000f, 0.871578f); GLuint VAO,VBO; float aspectRatio = 1.f; float exposition = 1.f; glm::vec3 pointlightPos = glm::vec3(0, 2, 0); glm::vec3 pointlightColor = glm::vec3(0.9, 0.6, 0.6); glm::vec3 spotlightPos = glm::vec3(0, 0, 0); glm::vec3 spotlightConeDir = glm::vec3(0, 0, 0); glm::vec3 spotlightColor = glm::vec3(0.4, 0.4, 0.9)*3; float spotlightPhi = 3.14 / 4; float lastTime = -1.f; float deltaTime = 0.f; void updateDeltaTime(float time) { if (lastTime < 0) { lastTime = time; return; } deltaTime = time - lastTime; if (deltaTime > 0.1) deltaTime = 0.1; lastTime = time; } glm::mat4 createCameraMatrix() { glm::vec3 cameraSide = glm::normalize(glm::cross(cameraDir,glm::vec3(0.f,1.f,0.f))); glm::vec3 cameraUp = glm::normalize(glm::cross(cameraSide,cameraDir)); glm::mat4 cameraRotrationMatrix = glm::mat4({ cameraSide.x,cameraSide.y,cameraSide.z,0, cameraUp.x,cameraUp.y,cameraUp.z ,0, -cameraDir.x,-cameraDir.y,-cameraDir.z,0, 0.,0.,0.,1., }); cameraRotrationMatrix = glm::transpose(cameraRotrationMatrix); glm::mat4 cameraMatrix = cameraRotrationMatrix * glm::translate(-cameraPos); return cameraMatrix; } glm::mat4 createPerspectiveMatrix() { glm::mat4 perspectiveMatrix; float n = 0.05; float f = 20.; float a1 = glm::min(aspectRatio, 1.f); float a2 = glm::min(1 / aspectRatio, 1.f); perspectiveMatrix = glm::mat4({ 1,0.,0.,0., 0.,aspectRatio,0.,0., 0.,0.,(f+n) / (n - f),2*f * n / (n - f), 0.,0.,-1.,0., }); perspectiveMatrix=glm::transpose(perspectiveMatrix); return perspectiveMatrix; } void drawObjectPBR(Core::RenderContext& context, glm::mat4 modelMatrix, GLuint texture, float roughness, float metallic) { glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); glm::mat4 transformation = viewProjectionMatrix * modelMatrix; glUniformMatrix4fv(glGetUniformLocation(program, "transformation"), 1, GL_FALSE, (float*)&transformation); glUniformMatrix4fv(glGetUniformLocation(program, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); glUniform1f(glGetUniformLocation(program, "exposition"), exposition); glUniform1f(glGetUniformLocation(program, "roughness"), roughness); glUniform1f(glGetUniformLocation(program, "metallic"), metallic); glUniform3f(glGetUniformLocation(program, "cameraPos"), cameraPos.x, cameraPos.y, cameraPos.z); glUniform3f(glGetUniformLocation(program, "sunDir"), sunDir.x, sunDir.y, sunDir.z); glUniform3f(glGetUniformLocation(program, "sunColor"), sunColor.x, sunColor.y, sunColor.z); glUniform3f(glGetUniformLocation(program, "lightPos"), pointlightPos.x, pointlightPos.y, pointlightPos.z); glUniform3f(glGetUniformLocation(program, "lightColor"), pointlightColor.x, pointlightColor.y, pointlightColor.z); glUniform3f(glGetUniformLocation(program, "spotlightConeDir"), spotlightConeDir.x, spotlightConeDir.y, spotlightConeDir.z); glUniform3f(glGetUniformLocation(program, "spotlightPos"), spotlightPos.x, spotlightPos.y, spotlightPos.z); glUniform3f(glGetUniformLocation(program, "spotlightColor"), spotlightColor.x, spotlightColor.y, spotlightColor.z); glUniform1f(glGetUniformLocation(program, "spotlightPhi"), spotlightPhi); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, depthMap); glm::mat4 lightVP = glm::ortho(-3.f, 2.3f, -1.3f, 3.f, -1.0f, 40.0f) * glm::lookAt(sunPos, sunPos - sunDir, glm::vec3(0, 1, 0)); glUniformMatrix4fv(glGetUniformLocation(program, "LightVP"), 1, GL_FALSE, (float*)&lightVP); Core::SetActiveTexture(texture, "colorTexture", program, texture); Core::DrawContext(context); } void drawObjectDepth(Core::RenderContext& RenderContext, glm::mat4 viewProjection, glm::mat4 modelMatrix) { glUniformMatrix4fv(glGetUniformLocation(programDepth, "viewProjectionMatrix"), 1, GL_FALSE, (float*)&viewProjection); glUniformMatrix4fv(glGetUniformLocation(programDepth, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix); Core::DrawContext(RenderContext); } void renderShadowapSun() { float time = glfwGetTime(); //ustawianie przestrzeni rysowania glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT); //bindowanie FBO glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); //czyszczenie mapy głębokości glClear(GL_DEPTH_BUFFER_BIT); //ustawianie programu glUseProgram(programDepth); glm::mat4 lightVP = glm::ortho(-3.f, 2.3f, -1.3f, 3.f, -1.0f, 40.0f) * glm::lookAt(sunPos, sunPos - sunDir, glm::vec3(0, 1, 0)); drawObjectDepth(sphereContext, lightVP, glm::translate(pointlightPos) * glm::scale(glm::vec3(0.1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::scale(glm::vec3(0.3f))); drawObjectDepth(sphereContext, lightVP, glm::translate(pointlightPos) * glm::scale(glm::vec3(0.1)) * glm::eulerAngleY(time / 3) * glm::translate(glm::vec3(4.f, 0, 0)) * glm::eulerAngleY(time) * glm::translate(glm::vec3(1.f, 0, 0)) * glm::scale(glm::vec3(0.1f))); //drawObjectDepth(models::bedContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::chairContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::deskContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::doorContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::drawerContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::marbleBustContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::materaceContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::pencilsContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::planeContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::roomContext, // lightVP, // glm::mat4()); //drawObjectDepth(models::windowContext, // lightVP, // glm::mat4()); glBindFramebuffer(GL_FRAMEBUFFER, 0); glViewport(0, 0, WIDTH, HEIGHT); } void renderScene(GLFWwindow* window) { glClearColor(0.4f, 0.4f, 0.8f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); float time = glfwGetTime(); updateDeltaTime(time); renderShadowapSun(); //space lamp glUseProgram(programSun); glm::mat4 viewProjectionMatrix = createPerspectiveMatrix() * createCameraMatrix(); glm::mat4 transformation = viewProjectionMatrix * glm::translate(pointlightPos) * glm::scale(glm::vec3(0.1)); glUniformMatrix4fv(glGetUniformLocation(programSun, "transformation"), 1, GL_FALSE, (float*)&transformation); glUniform3f(glGetUniformLocation(programSun, "color"), sunColor.x / 2, sunColor.y / 2, sunColor.z / 2); glUniform1f(glGetUniformLocation(programSun, "exposition"), exposition); Core::DrawContext(sphereContext); glUseProgram(program); drawObjectPBR(models::window, glm::mat4(), textures::windowFrameTexture, 0.2, 0.1 ); drawObjectPBR(models::potPlant, glm::mat4() * glm::scale(glm::vec3(0.2f)) * glm::translate(glm::vec3(-5.0f, 55.0f, -6.0f)), textures::potPlantTexture, 1.0f, 0.2f ); drawObjectPBR(models::officeChair, glm::mat4(), textures::officeChariTexture, 0.2f, 0.0f ); drawObjectPBR(models::lamp, glm::mat4() * glm::scale(glm::vec3(0.001f)), textures::lampTexture, 0.3f, 0.0f ); drawObjectPBR(models::door, glm::mat4(), textures::doorTexture, 0.4f, 0.0f ); drawObjectPBR(models::desk, glm::mat4(), textures::deskTexture, 0.4f, 0.0f ); drawObjectPBR(models::ceilingLamp, glm::mat4(), textures::ceilingLampTexture, 0.2f, 0.0f ); drawObjectPBR(models::bed, glm::mat4(), textures::bedTexture, 0.3f, 0.0f ); drawObjectPBR(models::windowFrame, glm::mat4(), textures::windowFrameTexture, 0.2f, 0.0f); drawObjectPBR(models::bookShelf, glm::mat4() * glm::scale(glm::vec3(0.01)), textures::bookShelfTexture, 0.4f, 0.1f); glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f, 1.f, 0.f))); glm::vec3 spaceshipUp = glm::normalize(glm::cross(spaceshipSide, spaceshipDir)); glm::mat4 specshipCameraRotrationMatrix = glm::mat4({ spaceshipSide.x,spaceshipSide.y,spaceshipSide.z,0, spaceshipUp.x,spaceshipUp.y,spaceshipUp.z ,0, -spaceshipDir.x,-spaceshipDir.y,-spaceshipDir.z,0, 0.,0.,0.,1., }); //drawObjectColor(shipContext, // glm::translate(cameraPos + 1.5 * cameraDir + cameraUp * -0.5f) * inveseCameraRotrationMatrix * glm::eulerAngleY(glm::pi()), // glm::vec3(0.3, 0.3, 0.5) // ); drawObjectPBR(shipContext, glm::translate(spaceshipPos) * specshipCameraRotrationMatrix * glm::eulerAngleY(glm::pi()) * glm::scale(glm::vec3(0.03f)), textures::flashlightTexture, 0.0, 0.0 ); spotlightPos = spaceshipPos + 0.2 * spaceshipDir; if (!flashOff) spotlightConeDir = spaceshipDir; else spotlightConeDir = -spaceshipDir; glUseProgram(0); glfwSwapBuffers(window); } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { aspectRatio = width / float(height); glViewport(0, 0, width, height); WIDTH = width; HEIGHT = height; } void loadModelToContext(std::string path, Core::RenderContext& context) { Assimp::Importer import; const aiScene* scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_CalcTangentSpace); if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { std::cout << "ERROR::ASSIMP::" << import.GetErrorString() << std::endl; return; } context.initFromAssimpMesh(scene->mMeshes[0]); } void initDepthMap() { glGenFramebuffers(1, &depthMapFBO); glGenTextures(1, &depthMap); glBindTexture(GL_TEXTURE_2D, depthMap); glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0); glDrawBuffer(GL_NONE); glReadBuffer(GL_NONE); glBindFramebuffer(GL_FRAMEBUFFER, 0); } void init(GLFWwindow* window) { glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); initDepthMap(); glEnable(GL_DEPTH_TEST); program = shaderLoader.CreateProgram("shaders/shader_9_1.vert", "shaders/shader_9_1.frag"); programSun = shaderLoader.CreateProgram("shaders/shader_8_sun.vert", "shaders/shader_8_sun.frag"); programDepth = shaderLoader.CreateProgram("shaders/shader_depth.vert", "shaders/shader_depth.frag"); loadModelToContext("./models/sphere.obj", sphereContext); loadModelToContext("./models/spaceship.obj", shipContext); loadModelToContext("./models/spaceship.obj", models::spaceshipContext); loadModelToContext("./models/sphere.obj", models::sphereContext); loadModelToContext("./models2/Frame/Frame.obj", models::windowFrame); loadModelToContext("./models2/bookshelf/shelf.obj", models::bookShelf); loadModelToContext("./models2/potplant/Pot.obj", models::potPlant); loadModelToContext("./models2/lamp/Lamp_LOVMANAD_OBJ.obj", models::lamp); loadModelToContext("./models2/door/source/door.obj", models::door); textures::flashlightTexture = Core::LoadTexture("./models/FlashlightTexture.png"); textures::sunTexture = Core::LoadTexture("./models/sun.jpeg"); textures::windowFrameTexture = Core::LoadTexture("./models2/Frame/frame.png"); textures::bookShelfTexture = Core::LoadTexture("./models2/bookshelf/SHELF_TEXTURE.bmp"); textures::potPlantTexture = Core::LoadTexture("./models2/potplant/b3.bmp"); textures::lampTexture = Core::LoadTexture("./models2/lamp/_Base_color.png"); textures::doorTexture = Core::LoadTexture("./models2/door/textures/Door_albedo.bmp"); } void shutdown(GLFWwindow* window) { shaderLoader.DeleteProgram(program); } //obsluga wejscia void processInput(GLFWwindow* window) { glm::vec3 spaceshipSide = glm::normalize(glm::cross(spaceshipDir, glm::vec3(0.f,1.f,0.f))); glm::vec3 spaceshipUp = glm::vec3(0.f, 1.f, 0.f); float angleSpeed = 0.05f * deltaTime * 60; float moveSpeed = 0.05f * deltaTime * 60; if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); } if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) spaceshipPos += spaceshipDir * moveSpeed; if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) spaceshipPos -= spaceshipDir * moveSpeed; if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) spaceshipPos += spaceshipSide * moveSpeed; if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) spaceshipPos -= spaceshipSide * moveSpeed; if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS) spaceshipPos += spaceshipUp * moveSpeed; if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS) spaceshipPos -= spaceshipUp * moveSpeed; if (glfwGetKey(window, GLFW_KEY_Z) == GLFW_PRESS) spaceshipDir = glm::vec3(glm::eulerAngleY(angleSpeed) * glm::vec4(spaceshipDir, 0)); if (glfwGetKey(window, GLFW_KEY_X) == GLFW_PRESS) spaceshipDir = glm::vec3(glm::eulerAngleY(-angleSpeed) * glm::vec4(spaceshipDir, 0)); if (glfwGetKey(window, GLFW_KEY_4) == GLFW_PRESS) flashOff = false; if (glfwGetKey(window, GLFW_KEY_5) == GLFW_PRESS) flashOff = true; if (glfwGetKey(window, GLFW_KEY_6) == GLFW_RELEASE) { glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); glfwGetCursorPos(window, &xpos, &ypos); float rotX = sensitivity * (float)(xpos - (HEIGHT / 2)) / HEIGHT; float rotY = sensitivity * (float)(ypos - (WIDTH / 2)) / WIDTH; glm::vec3 newOrientation = glm::rotate(spaceshipDir, glm::radians(-rotY), glm::normalize(glm::cross(spaceshipDir, Up))); // Decides whether or not the next vertical Orientation is legal or not if (abs(glm::angle(newOrientation, Up) - glm::radians(90.0f)) <= glm::radians(85.0f)) { spaceshipDir = newOrientation; } // Rotates the Orientation left and right spaceshipDir = glm::rotate(spaceshipDir, glm::radians(-rotX), Up); glfwSetCursorPos(window, WIDTH/2, HEIGHT/2); } cameraPos = spaceshipPos - 0.6 * spaceshipDir + glm::vec3(0, 1, 0) * 0.26f; cameraDir = spaceshipDir; if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS) exposition -= 0.05; if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS) exposition += 0.05; if (glfwGetKey(window, GLFW_KEY_3) == GLFW_PRESS) { printf("spaceshipPos = glm::vec3(%ff, %ff, %ff);\n", spaceshipPos.x, spaceshipPos.y, spaceshipPos.z); printf("spaceshipDir = glm::vec3(%ff, %ff, %ff);\n", spaceshipDir.x, spaceshipDir.y, spaceshipDir.z); } //cameraDir = glm::normalize(-cameraPos); } // funkcja jest glowna petla void renderLoop(GLFWwindow* window) { while (!glfwWindowShouldClose(window)) { currTime = glfwGetTime(); timeDiff = currTime - prevTime; counter++; if (timeDiff >= 1.0 / 30.0) { std::string FPS = std::to_string((1.0 / timeDiff) * counter); std::string newTitle = "Super Gra - " + FPS + " FPS"; glfwSetWindowTitle(window, newTitle.c_str()); prevTime = currTime; counter = 0; } processInput(window); renderScene(window); glfwPollEvents(); } } //}