Huge stuff. camera, input manager (mouse + keyboard), can move around scene now

This commit is contained in:
2026-05-04 00:41:34 -04:00
parent 9a8e618bbb
commit 3c756d6230
17 changed files with 624 additions and 119 deletions

View File

@@ -8,14 +8,16 @@
#include "glm/ext/matrix_transform.hpp"
#define STB_IMAGE_IMPLEMENTATION
#include "FreeCamera.h"
#include "InputManager.h"
#include "stb_image.h"
#include "Model.h"
#include "ModelLoader.h"
#include "ModelManager.h"
#include "ShaderManager.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "TextureLoader.h"
#include "TextureManager.h"
GLFWwindow* gWindow = nullptr;
int gWindowWidth = 800;
@@ -24,9 +26,11 @@ int gWindowHeight = 600;
int glVersionMajor = 0;
int glVersionMinor = 0;
auto cameraPosition = glm::vec3{0, 0, 0};
auto view = glm::mat4{0};
auto projection = glm::mat4{0};
float gAspectRatio = 0.f;
float gMouseSensitivity = 0.1f;
FreeCamera gCamera {};
void glfw_error_callback(int error, const char* description);
void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
@@ -36,10 +40,16 @@ void init_glfw();
void create_main_window();
void load_gl();
void init_camera();
void load_default_textures();
void load_shaders();
void loop();
std::shared_ptr<Model> load_model(std::string_view _path);
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 start");
@@ -49,30 +59,33 @@ int main() {
load_gl();
stbi_set_flip_vertically_on_load(true);
init_camera();
// create a default texture
unsigned char defaultDiffuseData[4] = {static_cast<unsigned char>(255), 255, 255, 255};
TextureLoader::textures["default_diffuse"] = TextureLoader::load_from_data(reinterpret_cast<unsigned char*>(&defaultDiffuseData), 1, 1, 4);
stbi_set_flip_vertically_on_load(true);
// create a default specular map
unsigned char defaultSpecularData[4] = {static_cast<unsigned char>(128), 128, 128, 255};
TextureLoader::textures["default_specular"] = TextureLoader::load_from_data(reinterpret_cast<unsigned char*>(&defaultSpecularData), 1, 1, 4);
load_default_textures();
ShaderManager::shaders["phong_shader"] = ShaderManager::load("./resources/standard.vert", "./resources/standard.frag");
if (ShaderManager::shaders["phong_shader"] == nullptr)
{
std::exit(1);
}
load_shaders();
/*ModelLoader::models["cube"] = ModelLoader::load_from_file("./resources/cube.obj", true);*/
ModelLoader::models["backpack"] = ModelLoader::load_from_file("./resources/backpack/backpack.obj");
/*ModelLoader::models["male"] = ModelLoader::load_from_file("./resources/male.obj");*/
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("exit_application", {{GLFW_KEY_ESCAPE, KEY_DOWN}});
spdlog::info("loading models");
ModelManager::models["cube"] = ModelManager::load_from_file("./resources/cube.obj");
ModelManager::models["backpack"] = ModelManager::load_from_file("./resources/backpack/backpack.obj");
ModelManager::models["male"] = ModelManager::load_from_file("./resources/male.obj");
spdlog::info("done");
loop();
ShaderManager::shaders.clear();
TextureManager::textures.clear();
ModelManager::models.clear();
glfwDestroyWindow(gWindow);
glfwTerminate();
@@ -83,14 +96,10 @@ void glfw_error_callback(int error, const char* description) {
spdlog::error("glfw error: {}", description);
}
void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GL_TRUE);
}
}
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()
@@ -103,13 +112,14 @@ void init_glfw()
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.1", nullptr, nullptr);
gWindow = glfwCreateWindow(gWindowWidth, gWindowHeight, "b_engine v0.0.2", nullptr, nullptr);
if (!gWindow) {
spdlog::error("failed to create glfw window");
std::exit(1);
@@ -117,8 +127,12 @@ void create_main_window()
glfwMakeContextCurrent(gWindow);
glfwSetKeyCallback(gWindow, glfw_key_callback);
glfwSetKeyCallback(gWindow, InputManager::key_callback);
glfwSetCursorPosCallback(gWindow, InputManager::mouse_pos_callback);
glfwSetFramebufferSizeCallback(gWindow, glfw_framebuffer_size_callback);
glfwSetInputMode(gWindow, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
}
void load_gl()
@@ -132,63 +146,131 @@ void load_gl()
{
int fbWidth, fbHeight;
glfwGetFramebufferSize(gWindow, &fbWidth, &fbHeight);
glViewport(0, 0, fbWidth, fbHeight);
gAspectRatio = (float)fbWidth / (float)fbHeight;
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_MULTISAMPLE);
}
void init_camera()
{
cameraPosition = glm::vec3{10, 0, 10};
auto cameraTarget = glm::vec3{0, 0, 0};
void init_camera() {
gCamera = {{5.f, 5.f, 5.f}, 0, 0, gAspectRatio};
gCamera.rotate_yaw(-135.f);
gCamera.rotate_pitch(-35.f);
view = glm::lookAt(cameraPosition, cameraTarget, glm::vec3(0.0f, 1.0f, 0.0f));
InputManager::add_mouse_listener([](float xoff, float yoff) {
gCamera.rotate_yaw(xoff * gMouseSensitivity);
gCamera.rotate_pitch(yoff * gMouseSensitivity);
});
}
float aspectRatio = static_cast<float>(gWindowWidth) / static_cast<float>(gWindowHeight);
projection = glm::perspective(glm::radians(75.f), aspectRatio, 0.1f, 100.0f);
void load_default_textures() {
spdlog::info("creating default textures");
unsigned char defaultDiffuseData[4] = {static_cast<unsigned char>(255), 255, 255, 255};
TextureManager::textures["default_diffuse"] = TextureManager::load_from_data(reinterpret_cast<unsigned char*>(&defaultDiffuseData), 1, 1, 4);
unsigned char defaultSpecularData[4] = {static_cast<unsigned char>(64), 64, 64, 255};
TextureManager::textures["default_specular"] = TextureManager::load_from_data(reinterpret_cast<unsigned char*>(&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 loop() {
Texture* defaultDiffuse = TextureLoader::textures["default_diffuse"].get();
Texture* defaultSpecular = TextureLoader::textures["default_specular"].get();
std::shared_ptr<Texture> defaultDiffuse = TextureManager::textures["default_diffuse"];
std::shared_ptr<Texture> defaultSpecular = TextureManager::textures["default_specular"];
auto model = glm::identity<glm::mat4>();
ShaderProgram* shader = ShaderManager::shaders["phong_shader"].get();
const auto cube = ModelManager::models["cube"];
const auto backpack = ModelManager::models["backpack"];
const auto male = ModelManager::models["male"];
const auto& activeModel = backpack;
while (!glfwWindowShouldClose(gWindow)) {
auto model = glm::identity<glm::mat4>();
// model = glm::translate(model, glm::vec3(0, -5.f, 0));
// model = glm::scale(model, glm::vec3(.5f, .5f, .5f));
glfwPollEvents();
// check inputs
if (InputManager::check_action_performed("exit_application")) {
glfwSetWindowShouldClose(gWindow, true);
continue;
}
if (InputManager::check_action_performed("move_forward")) {
gCamera.move(CAMERA_MOVEMENT::FORWARD, .05);
}
if (InputManager::check_action_performed("move_backward")) {
gCamera.move(CAMERA_MOVEMENT::BACKWARD, .05);
}
if (InputManager::check_action_performed("move_left")) {
gCamera.move(CAMERA_MOVEMENT::LEFT, .05);
}
if (InputManager::check_action_performed("move_right")) {
gCamera.move(CAMERA_MOVEMENT::RIGHT, .05);
}
// gl frame prep
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderProgram* shader = ShaderManager::shaders["phong_shader"].get();
const Model* cube = ModelLoader::models["cube"].get();
const Model* backpack = ModelLoader::models["backpack"].get();
const Model* male = ModelLoader::models["male"].get();
if (shader) {
Material* mat = backpack->materials[0].get();
// draw the stuff
if (shader && activeModel) {
shader->bind();
shader->setMat4("projection", projection);
shader->setMat4("view", view);
shader->setMat4("projection", gCamera.projection());
shader->setMat4("view", gCamera.view());
shader->setMat4("model", model);
shader->setVec3("viewPosition", cameraPosition);
shader->setVec3("viewPosition", gCamera.position());
shader->setVec3("phongAmbient", glm::vec3(0.3f, 0.3f, 0.3f));
shader->setVec3("phongDiffuse", glm::vec3(0.8f, 0.8f, 0.8f));
shader->setVec3("phongSpecular", glm::vec3(1.0f, 1.0f, 1.0f));
shader->setFloat("phongShininess", 32.0f);
shader->setVec3("lightDirection", glm::vec3(-.5f, -.5f, -.5f));
shader->setVec3("lightPosition", glm::vec3{-2.f, 0, 2.0f});
shader->setVec3("lightDirection", glm::vec3(1, -1, -1));
shader->setVec3("lightAmbient", glm::vec3(0.3f, 0.3f, 0.3f));
shader->setVec3("lightDiffuse", glm::vec3(1.0f, 1.0f, 1.0f));
shader->setVec3("lightDiffuse", glm::vec3(0.5f, 0.5f, 0.5f));
shader->setVec3("lightSpecular", glm::vec3(1.0f, 1.0f, 1.0f));
for (const auto& mesh: backpack->meshes) {
for (const auto& mesh: activeModel->meshes) {
unsigned int materialId = mesh->materialId;
if (materialId >= activeModel->materials.size()) {
materialId = 0;
}
const std::shared_ptr<Material> mat = activeModel->materials[1];
shader->setVec3("phongAmbient", mat->phong.ambient);
shader->setVec3("phongDiffuse", mat->phong.diffuse);
shader->setVec3("phongSpecular", mat->phong.specular);
shader->setFloat("phongShininess", mat->phong.shininess);
glActiveTexture(GL_TEXTURE0);
auto diffuse = mat->diffuse;
if (!diffuse) {
diffuse = defaultDiffuse;
}
diffuse->bind();
shader->setInt("diffuseMap", 0);
glActiveTexture(GL_TEXTURE1);
auto specular = mat->specular;
if (!specular) {
specular = defaultSpecular;
}
specular->bind();
shader->setInt("specularMap", 1);
glBindVertexArray(mesh.get()->vao);
glDrawElements(GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, 0);
}
@@ -197,6 +279,7 @@ void loop() {
ShaderProgram::unbind();
}
// gl end frame stuff
glfwSwapBuffers(gWindow);
}
}