#include #include #include #include #include #include #include #include #include #include #include void window_resize_callback(GLFWwindow* window, int width, int height); void mouse_callback(GLFWwindow* window, double xpos, double ypos); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); void processInput(GLFWwindow *window); int SCREEN_WIDTH = 1920; int SCREEN_HEIGHT = 1080; static bool drawWireframe = false; static bool wireframeHeld = false; static bool flashlight = true; Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); float lastX = SCREEN_WIDTH / 2.0f; float lastY = SCREEN_HEIGHT / 2.0f; bool firstMouse = true; float deltaTime = 0.0f; // time between current frame and last frame float lastFrame = 0.0f; int main(int argc, char* argv[]) { // Initialize GLFW glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Create GLFW Window GLFWwindow* window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Renderer", NULL, NULL); if (window == NULL) { std::cout << "Failed to create GLFW window" << std::endl; glfwTerminate(); return -1; } glfwMakeContextCurrent(window); // Initialize GLAD if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { std::cout << "Failed to initialize GLAD" << std::endl; return -1; } // Initialize Viewport & setup resize callback glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT); glfwSetFramebufferSizeCallback(window, window_resize_callback); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); glEnable(GL_DEPTH_TEST); // Hide & Lock Cursor glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE); /* Testing */ Shader shaderTest("assets/shaders/basicVertex.vert", "assets/shaders/basicFragment.frag"); Model ourModel = engine::assets::loadModel("assets/models/sponza/Sponza.gltf"); shaderTest.Use(); shaderTest.setInt("ourTexture", 0); shaderTest.setInt("material.diffuse", 0); shaderTest.setInt("material.specular", 1); // Set decals - TODO: Shift this to mesh.h with helpers shaderTest.setDecal(0, 2, 1, glm::vec4(0.5, 0.5, 0, 0)); shaderTest.setDecal(1, 2, 1, glm::vec4(0.5, 0.5, -0.75, -0.75)); shaderTest.setInt("numberOfDecals", 2); shaderTest.setInt("numberOfPointLights", 1); shaderTest.setInt("numberOfSpotLights", 1); // Render Loop float lastUpdate = 0; while (!glfwWindowShouldClose(window)) { // per-frame time logic float currentFrame = static_cast(glfwGetTime()); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; // crappy fps printout if (currentFrame - lastUpdate >= 1.0) { // std::cout << 1.0f / deltaTime << std::endl; lastUpdate += 1.0f; } // Input processing processInput(window); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shaderTest.Use(); camera.Update(shaderTest, SCREEN_WIDTH, SCREEN_HEIGHT); shaderTest.setFloat("material.shininess", 32.0f); shaderTest.setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f); shaderTest.setVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f); shaderTest.setVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f); shaderTest.setVec3("dirLight.specular", 0.8f, 0.8f, 0.8f); // ----------------------------------------------------------------------------- // Ground Floor - Right Corridor (Warm Light) // Placed halfway down the right hallway behind the arches // ----------------------------------------------------------------------------- shaderTest.setVec3("pointLights[0].position", -1.88f, 8.45f, -0.98f); shaderTest.setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f); shaderTest.setVec3("pointLights[0].diffuse", 1.0f, 0.7f, 0.4f); shaderTest.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f); shaderTest.setFloat("pointLights[0].constant", 1.0f); shaderTest.setFloat("pointLights[0].linear", 0.09f); shaderTest.setFloat("pointLights[0].quadratic", 0.032f); // spotLight1 shaderTest.setBool("spotLights[0].disabled", flashlight); shaderTest.setVec3("spotLights[0].position", camera.position); shaderTest.setVec3("spotLights[0].direction", camera.front); shaderTest.setVec3("spotLights[0].ambient", 0.0f, 0.0f, 0.0f); shaderTest.setVec3("spotLights[0].diffuse", 1.0f, 1.0f, 1.0f); shaderTest.setVec3("spotLights[0].specular", 1.0f, 1.0f, 1.0f); shaderTest.setFloat("spotLights[0].constant", 1.0f); shaderTest.setFloat("spotLights[0].linear", 0.09f); shaderTest.setFloat("spotLights[0].quadratic", 0.032f); shaderTest.setFloat("spotLights[0].cutOff", glm::cos(glm::radians(12.5f))); shaderTest.setFloat("spotLights[0].outerCutOff", glm::cos(glm::radians(15.0f))); // render the loaded model glm::mat4 model = glm::mat4(1.0f); model = glm::translate(model, glm::vec3(0.0f, 0.0f, 0.0f)); model = glm::scale(model, glm::vec3(0.02f, 0.02f, 0.02f)); shaderTest.setMat4("model", model); ourModel.Draw(shaderTest); // Call events & swap buffers glfwSwapBuffers(window); glfwPollEvents(); } // Clean up memory glfwTerminate(); return 0; } void window_resize_callback(GLFWwindow* window, int width, int height) { glViewport(0, 0, width, height); SCREEN_WIDTH = width; SCREEN_HEIGHT = height; } void processInput(GLFWwindow* window) { // Close on Escape if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) glfwSetWindowShouldClose(window, true); // Wireframe toggle if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_PRESS && !wireframeHeld) { wireframeHeld = true; drawWireframe = !drawWireframe; if (drawWireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); } else { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } if (glfwGetKey(window, GLFW_KEY_F1) == GLFW_RELEASE) wireframeHeld = false; // Flashlight toggle if (glfwGetKey(window, GLFW_KEY_F) == GLFW_PRESS && !wireframeHeld) { wireframeHeld = true; flashlight = !flashlight; } if (glfwGetKey(window, GLFW_KEY_F) == GLFW_RELEASE) wireframeHeld = false; // Camera if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera.processKeyboard(FORWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera.processKeyboard(BACKWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera.processKeyboard(LEFT, deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) camera.processKeyboard(RIGHT, deltaTime); if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) camera.processKeyboard(SPRINT, deltaTime); } // glfw: whenever the mouse moves, this callback is called // ------------------------------------------------------- void mouse_callback(GLFWwindow* window, double xposIn, double yposIn) { float xpos = static_cast(xposIn); float ypos = static_cast(yposIn); if (firstMouse) { lastX = xpos; lastY = ypos; firstMouse = false; } float xoffset = xpos - lastX; float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastX = xpos; lastY = ypos; camera.processMouseMovement(xoffset, yoffset); } // glfw: whenever the mouse scroll wheel scrolls, this callback is called // ---------------------------------------------------------------------- void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) { camera.processMouseScroll(static_cast(yoffset)); }