#define _USE_MATH_DEFINES #include #include "scene.hpp" #include "utils.hpp" #include void framebuffer_size_callback(GLFWwindow *window, int width, int height); void init_glfw() { glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); #ifdef __APPLE__ glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); #endif } void framebuffer_size_callback(GLFWwindow *, int width, int height) { glViewport(0, 0, width, height); } void mouse_callback(GLFWwindow *window, double xpos, double ypos) { Scene* scene = static_cast(glfwGetWindowUserPointer(window)); scene->camera.mouse_move(xpos, ypos); } void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) { Scene* scene = static_cast(glfwGetWindowUserPointer(window)); scene->camera.mouse_scroll(xoffset, yoffset); } GLFWwindow* create_window() { GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); dbc::check(window != NULL, "failed to open window"); glfwMakeContextCurrent(window); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); auto good = gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); dbc::check(good, "failed to load GLAD"); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); glfwSetCursorPosCallback(window, mouse_callback); glfwSetScrollCallback(window, scroll_callback); return window; } void process_input(GLFWwindow *window, Scene& scene) { if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); } if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { scene.camera.forward(); } if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { scene.camera.back(); } if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { scene.camera.left(); } if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { scene.camera.right(); } if(glfwGetKey(window, GLFW_KEY_R) == GLFW_PRESS) { scene.reflect_on = !scene.reflect_on; } if(glfwGetKey(window, GLFW_KEY_L) == GLFW_PRESS) { scene.light.camera.on = !scene.light.camera.on; scene.shader.apply_lighting(scene.light); } if(glfwGetKey(window, GLFW_KEY_O) == GLFW_PRESS) { for(auto& light : scene.light.directional) { light.adjust(-0.01f); } scene.shader.apply_lighting(scene.light); } if(glfwGetKey(window, GLFW_KEY_P) == GLFW_PRESS) { for(auto& light : scene.light.directional) { light.adjust(0.01f); } scene.shader.apply_lighting(scene.light); } } Scene setup() { glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glEnable(GL_CULL_FACE); glEnable(GL_MULTISAMPLE); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthFunc(GL_LESS); components::Scene config = utils::load_scene_config("config.json"); return {config}; } void update(GLFWwindow* window, Scene& scene) { glfwPollEvents(); process_input(window, scene); scene.update(); } void render(GLFWwindow* window, Scene& scene, Text& text) { scene.render(window); float scale = 0.5f; float X_height = text.characters['X'].size.y * scale + 0.5f; float y = 0.0f; for(int i = 0; i < 100; i++) { y += X_height; text.render(std::format("y={}", y), 25.0f, y, scale, glm::vec3(1.0, 0.0f, 0.0f)); } glfwSwapBuffers(window); } void quit(GLFWwindow* window, Scene& scene) { scene.cleanup(); glfwTerminate(); } int main() { init_glfw(); auto window = create_window(); auto scene = setup(); Text text; glfwSetWindowUserPointer(window, &scene); while(!glfwWindowShouldClose(window)) { update(window, scene); render(window, scene, text); } quit(window, scene); return 0; }