#include "glad/gl.h" #include "GLFW/glfw3.h" #include "spdlog/spdlog.h" #include "glm/glm.hpp" #include "glm/ext/matrix_clip_space.hpp" #include "glm/ext/matrix_transform.hpp" #include "entt/entt.hpp" #define STB_IMAGE_IMPLEMENTATION #include "Components.h" #include "FreeCamera.h" #include "InputManager.h" #include "stb_image.h" #include "Model.h" #include "ModelManager.h" #include "Scene.h" #include "ShaderManager.h" #include "ShaderProgram.h" #include "Texture.h" #include "TextureManager.h" GLFWwindow* gWindow = nullptr; int gWindowWidth = 800; int gWindowHeight = 600; int glVersionMajor = 0; int glVersionMinor = 0; float gAspectRatio = 0.f; float gMouseSensitivity = 0.1f; FreeCamera gCamera {}; Scene gScene{}; void glfw_error_callback(int error, const char* description); void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods); void glfw_framebuffer_size_callback(GLFWwindow* window, int width, int height); void init_glfw(); void create_main_window(); void load_gl(); void init_camera(); void load_default_textures(); void load_shaders(); void load_inputs(); void load_default_models(); void loop(); auto xAxis = glm::vec3{1.f, 0.f, 0.f}; auto yAxis = glm::vec3{0.f, 1.f, 0.f}; auto zAxis = glm::vec3{0.f, 0.f, 1.f}; int main() { spdlog::info("b_engine v0.0.3 start"); init_glfw(); create_main_window(); load_gl(); init_camera(); stbi_set_flip_vertically_on_load(true); load_default_textures(); load_shaders(); load_inputs(); load_default_models(); entt::entity dirLight = gScene.create_game_object(); auto& [direction, ambient, diffuse, specular] = gScene.attach_component(dirLight); direction = {1, -1, 1}; ambient = {0.3f, 0.3f, 0.3f}; diffuse = {0.5f, 0.5f, 0.5f}; specular = {1.0f, 1.0f, 1.0f}; loop(); ShaderManager::shaders.clear(); TextureManager::textures.clear(); ModelManager::models.clear(); glfwDestroyWindow(gWindow); glfwTerminate(); return 0; } void glfw_error_callback(int error, const char* description) { spdlog::error("glfw error: {}", description); } void glfw_framebuffer_size_callback(GLFWwindow *window, int width, int height) { glViewport(0, 0, width, height); gAspectRatio = (float)width / (float)height; gCamera.update_aspect_ratio(gAspectRatio); } void init_glfw() { if (!glfwInit()) { spdlog::error("could not initialize glfw"); std::exit(1); } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_SAMPLES, 4); glfwSetErrorCallback(glfw_error_callback); } void create_main_window() { gWindow = glfwCreateWindow(gWindowWidth, gWindowHeight, "b_engine v0.0.3", nullptr, nullptr); if (!gWindow) { spdlog::error("failed to create glfw window"); std::exit(1); } glfwMakeContextCurrent(gWindow); glfwSetKeyCallback(gWindow, InputManager::key_callback); glfwSetCursorPosCallback(gWindow, InputManager::mouse_pos_callback); glfwSetFramebufferSizeCallback(gWindow, glfw_framebuffer_size_callback); #ifndef GLFW_CONTEXT_DEBUG glfwSetInputMode(gWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED); #endif } void load_gl() { int version = gladLoadGL(glfwGetProcAddress); glVersionMajor = GLAD_VERSION_MAJOR(version); glVersionMinor = GLAD_VERSION_MINOR(version); spdlog::info("gl version {}.{}", glVersionMajor, glVersionMinor); if (gWindow) { int fbWidth, fbHeight; glfwGetFramebufferSize(gWindow, &fbWidth, &fbHeight); gAspectRatio = (float)fbWidth / (float)fbHeight; } glEnable(GL_DEPTH_TEST); glEnable(GL_MULTISAMPLE); } void init_camera() { gCamera = {{5.f, 5.f, 5.f}, 0, 0, gAspectRatio}; gCamera.rotate_yaw(-135.f); gCamera.rotate_pitch(-35.f); InputManager::add_mouse_listener([](float xoff, float yoff) { gCamera.rotate_yaw(xoff * gMouseSensitivity); gCamera.rotate_pitch(yoff * gMouseSensitivity); }); } void load_default_textures() { spdlog::info("creating default textures"); unsigned char defaultDiffuseData[4] = {static_cast(255), 255, 255, 255}; TextureManager::textures["default_diffuse"] = TextureManager::load_from_data(reinterpret_cast(&defaultDiffuseData), 1, 1, 4); unsigned char defaultSpecularData[4] = {static_cast(64), 64, 64, 255}; TextureManager::textures["default_specular"] = TextureManager::load_from_data(reinterpret_cast(&defaultSpecularData), 1, 1, 4); } void load_shaders() { spdlog::info("compiling shaders"); ShaderManager::shaders["phong_shader"] = ShaderManager::load("./resources/standard.vert", "./resources/standard.frag"); if (ShaderManager::shaders["phong_shader"] == nullptr) { spdlog::error("failed to compile phong shader"); std::exit(1); } } void load_inputs() { InputManager::generate_input_action("move_forward", {{GLFW_KEY_W, KEY_DOWN}}); InputManager::generate_input_action("move_backward", {{GLFW_KEY_S, KEY_DOWN}}); InputManager::generate_input_action("move_right", {{GLFW_KEY_D, KEY_DOWN}}); InputManager::generate_input_action("move_left", {{GLFW_KEY_A, KEY_DOWN}}); InputManager::generate_input_action("move_up", {{GLFW_KEY_SPACE, KEY_DOWN}}); InputManager::generate_input_action("move_down", {{GLFW_KEY_LEFT_SHIFT, KEY_DOWN}}); InputManager::generate_input_action("exit_application", {{GLFW_KEY_ESCAPE, KEY_DOWN}}); } void load_default_models() { spdlog::info("loading default models"); ModelManager::models["cube"] = ModelManager::load_from_file("./resources/cube.obj"); ModelManager::models["vette"] = ModelManager::load_from_file("./resources/c4/C4Fixed.obj"); ModelManager::models["male"] = ModelManager::load_from_file("./resources/male.obj"); } void loop() { while (!glfwWindowShouldClose(gWindow)) { glfwPollEvents(); // check inputs if (InputManager::check_action_performed("exit_application")) { glfwSetWindowShouldClose(gWindow, true); continue; } if (InputManager::check_action_performed("move_forward")) { gCamera.move(FORWARD, .05); } if (InputManager::check_action_performed("move_backward")) { gCamera.move(BACKWARD, .05); } if (InputManager::check_action_performed("move_left")) { gCamera.move(LEFT, .05); } if (InputManager::check_action_performed("move_right")) { gCamera.move(RIGHT, .05); } if (InputManager::check_action_performed("move_up")) { gCamera.move(UP, .05); } if (InputManager::check_action_performed("move_down")) { gCamera.move(DOWN, .05); } // gl frame prep glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); const auto shader = ShaderManager::shaders["phong_shader"]; shader->bind(); shader->setMat4("projection", gCamera.projection()); shader->setMat4("view", gCamera.view()); shader->setVec3("viewPosition", gCamera.position()); gScene.draw_scene(shader.get()); glBindVertexArray(0); ShaderProgram::unbind(); // gl end frame stuff glfwSwapBuffers(gWindow); } }