revamped resource system

This commit is contained in:
2026-05-02 21:24:21 -04:00
parent f9010eea81
commit 782bbcbadc
16 changed files with 374 additions and 177 deletions

View File

@@ -5,7 +5,6 @@ set(CMAKE_CXX_STANDARD 20)
set (GLAD_SOURCE_DIR _ThirdParty/glad/src)
set (GLAD_INCLUDE_DIR _ThirdParty/glad/include)
include_directories(${GLAD_INCLUDE_DIR})
set (GLFW_BUILD_EXAMPLES OFF)
@@ -20,7 +19,9 @@ add_subdirectory(_ThirdParty/assimp)
add_subdirectory(glm)
add_executable(${PROJECT_NAME} src/main.cpp ${GLAD_SOURCE_DIR}/gl.c
add_executable(${PROJECT_NAME}
src/main.cpp
${GLAD_SOURCE_DIR}/gl.c
src/Mesh.cpp
src/Mesh.h
src/Model.cpp
@@ -31,8 +32,11 @@ add_executable(${PROJECT_NAME} src/main.cpp ${GLAD_SOURCE_DIR}/gl.c
src/ModelLoader.h
src/ShaderProgram.cpp
src/ShaderProgram.h
src/Texture.cpp
src/Texture.h)
src/Texture.h
src/TextureLoader.cpp
src/TextureLoader.h
src/ShaderLoader.cpp
src/ShaderLoader.h)
target_link_libraries(${PROJECT_NAME} glfw spdlog assimp glm)
target_include_directories(${PROJECT_NAME} PRIVATE ${ASSIMP_INCLUDE_INSTALL_DIR})

46
resources/cube.obj Normal file
View File

@@ -0,0 +1,46 @@
# Blender v2.76 (sub 0) OBJ File: ''
# www.blender.org
mtllib cube.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 1.000000 0.333333
vt 1.000000 0.666667
vt 0.666667 0.666667
vt 0.666667 0.333333
vt 0.666667 0.000000
vt 0.000000 0.333333
vt 0.000000 0.000000
vt 0.333333 0.000000
vt 0.333333 1.000000
vt 0.000000 1.000000
vt 0.000000 0.666667
vt 0.333333 0.333333
vt 0.333333 0.666667
vt 1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -0.000000 0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
usemtl Material
s off
f 2/1/1 3/2/1 4/3/1
f 8/1/2 7/4/2 6/5/2
f 5/6/3 6/7/3 2/8/3
f 6/8/4 7/5/4 3/4/4
f 3/9/5 7/10/5 8/11/5
f 1/12/6 4/13/6 8/11/6
f 1/4/1 2/1/1 4/3/1
f 5/14/2 8/1/2 6/5/2
f 1/12/3 5/6/3 2/8/3
f 2/12/4 6/8/4 3/4/4
f 4/13/5 3/9/5 8/11/5
f 5/6/6 1/12/6 8/11/6

View File

@@ -5,23 +5,27 @@
#ifndef B_ENGINE_MATERIAL_H
#define B_ENGINE_MATERIAL_H
#include <memory>
#include <glm/glm.hpp>
#include "Texture.h"
typedef struct
{
alignas(16) glm::vec3 ambient;
alignas(16) glm::vec3 diffuse;
alignas(16) glm::vec3 specular;
glm::vec3 ambient;
glm::vec3 diffuse;
glm::vec3 specular;
float shininess;
} PhongProperties;
typedef struct
{
Texture* diffuse;
Texture* specular;
Texture* normal;
std::shared_ptr<Texture> diffuse;
std::shared_ptr<Texture> specular;
std::shared_ptr<Texture> normal;
std::string name;
PhongProperties phong;
} Material;

View File

@@ -6,6 +6,7 @@
Mesh::Mesh(const std::vector<float> &positions, const std::vector<float> &uvs, const std::vector<float> &normals, const std::vector<unsigned int> &indices) {
vao = 0;
ebo = 0;
numIndices = indices.size();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
@@ -27,6 +28,7 @@ Mesh::Mesh(const std::vector<float> &positions, const std::vector<float> &uvs, c
glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float), normals.data(), GL_STATIC_DRAW);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);

View File

@@ -20,6 +20,7 @@ public:
GLuint vao;
GLuint ebo;
unsigned int numIndices;
};
#endif //B_ENGINE_MESH_H

View File

@@ -5,7 +5,7 @@
#ifndef B_ENGINE_MODEL_H
#define B_ENGINE_MODEL_H
#include <string>
#include <string_view>
#include <vector>
#include "Mesh.h"
@@ -14,9 +14,10 @@
class Model
{
public:
int numMeshes;
std::vector<Mesh> meshes;
std::vector<Material> materials;
static std::shared_ptr<Model> load_from_file(std::string_view filename);
std::vector<std::shared_ptr<Mesh>> meshes;
std::vector<std::shared_ptr<Material>> materials;
};
#endif //B_ENGINE_MODEL_H

View File

@@ -10,16 +10,23 @@
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <cstring>
std::unordered_map<std::string, std::shared_ptr<Model>> ModelLoader::models;
void process_ai_node(aiNode* node, const aiScene* scene, Model* model);
Mesh process_ai_mesh(aiMesh* aiMesh, const aiScene* scene, Model* model);
Mesh process_ai_mesh(const aiMesh* aiMesh);
Material process_ai_material(aiMaterial* mat);
std::shared_ptr<Model> ModelLoader::load_from_file(std::string_view _path)
{
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(_path.data(),
/*aiProcess_CalcTangentSpace |*/
aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs |
aiProcess_Triangulate |
aiProcess_GenSmoothNormals |
aiProcess_FlipUVs |
aiProcess_CalcTangentSpace);
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
@@ -30,21 +37,29 @@ std::shared_ptr<Model> ModelLoader::load_from_file(std::string_view _path)
auto model = std::make_shared<Model>();
process_ai_node(scene->mRootNode, scene, model.get());
model->materials.resize(scene->mNumMaterials);
for (unsigned int i = 0; i < scene->mNumMaterials; i++) {
aiMaterial* mat = scene->mMaterials[i];
model->materials[i] = std::make_shared<Material>(process_ai_material(mat));
}
model->meshes.resize(scene->mNumMeshes);
for (unsigned int i = 0; i < scene->mNumMeshes; i++) {
aiMesh* mesh = scene->mMeshes[i];
model->meshes[i] = std::make_shared<Mesh>(process_ai_mesh(mesh));
}
return model;
}
void process_ai_node(aiNode* node, const aiScene* scene, Model* model)
{
for (unsigned int i = 0; i < node->mNumMeshes; i++)
{
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
model->meshes.push_back(process_ai_mesh(mesh, scene, model));
for (unsigned int i = 0; i < node->mNumChildren; i++) {
}
}
Mesh process_ai_mesh(aiMesh* aiMesh, const aiScene* scene, Model* model)
Mesh process_ai_mesh(const aiMesh* aiMesh)
{
auto positions = std::vector<float>(aiMesh->mNumVertices * 3);
auto uvs = std::vector<float>(aiMesh->mNumVertices * 2);
@@ -92,3 +107,48 @@ Mesh process_ai_mesh(aiMesh* aiMesh, const aiScene* scene, Model* model)
return {positions, uvs, normals, indices};
}
Material process_ai_material(aiMaterial *mat) {
aiString matName;
aiReturn ret = mat->Get(AI_MATKEY_NAME, matName);
if (ret != AI_SUCCESS) {
spdlog::error("Could not find material name");
}
aiColor3D ambientColor {0.f, 0.f, 0.f};
ret = mat->Get(AI_MATKEY_COLOR_DIFFUSE, ambientColor);
if (ret != AI_SUCCESS) {
spdlog::error("Could not find ambient color for material: {}", matName.C_Str());
ambientColor = {.3f, .3f, .3f};
}
aiColor3D diffuseColor {1.f, 1.f, 1.f};
ret = mat->Get(AI_MATKEY_COLOR_DIFFUSE, diffuseColor);
if (ret != AI_SUCCESS) {
spdlog::error("Could not find diffuse color for material: {}", matName.C_Str());
diffuseColor = {1.f, 1.f, 1.f};
}
aiColor3D specularColor {1.f, 1.f, 1.f};
ret = mat->Get(AI_MATKEY_COLOR_SPECULAR, specularColor);
if (ret != AI_SUCCESS) {
spdlog::error("Could not find specular color for material: {}", matName.C_Str());
specularColor = {1.f, 1.f, 1.f};
}
float shininess = 32.f;
ret = mat->Get(AI_MATKEY_SHININESS, shininess);
if (ret != AI_SUCCESS) {
spdlog::error("Could not find shininess for material: {}", matName.C_Str());
shininess = 32.f;
}
Material material;
material.name = matName.C_Str();
material.phong.ambient = glm::vec3{ambientColor.r, ambientColor.g, ambientColor.b};
material.phong.diffuse = glm::vec3{diffuseColor.r, diffuseColor.g, diffuseColor.b};
material.phong.specular = glm::vec3{specularColor.r, specularColor.g, specularColor.b};
material.phong.shininess = shininess;
return material;
}

View File

@@ -13,6 +13,8 @@
class ModelLoader
{
public:
static std::unordered_map<std::string, std::shared_ptr<Model>> models;
static std::shared_ptr<Model> load_from_file(std::string_view _path);
};

97
src/ShaderLoader.cpp Normal file
View File

@@ -0,0 +1,97 @@
//
// Created by slinky on 5/1/26.
//
#include "ShaderLoader.h"
#include "glad/gl.h"
#include <fstream>
#include <sstream>
#include <spdlog/spdlog.h>
void log_shader_compile_errors(GLuint shader, std::string_view shaderType);
void log_program_compile_errors(GLuint program);
std::unordered_map<std::string, std::shared_ptr<ShaderProgram>> ShaderLoader::shaders;
std::shared_ptr<ShaderProgram> ShaderLoader::load(std::string_view vertexPath, std::string_view fragmentPath)
{
std::string vertexSource;
std::string fragmentSource;
std::ifstream vertexFile {};
std::ifstream fragmentFile {};
try
{
vertexFile.open(vertexPath.data());
fragmentFile.open(fragmentPath.data());
std::stringstream vertexSourceStream {};
vertexSourceStream << vertexFile.rdbuf();
vertexSource = vertexSourceStream.str();
std::stringstream fragmentSourceStream {};
fragmentSourceStream << fragmentFile.rdbuf();
fragmentSource = fragmentSourceStream.str();
vertexFile.close();
fragmentFile.close();
} catch (std::ifstream::failure& e) {
spdlog::error("Failed to load shader program {}, {}: {}", vertexPath, fragmentPath, std::string(e.what()).c_str());
return nullptr;
}
unsigned int vertex;
unsigned int fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
const char* vertex_str = vertexSource.data();
glShaderSource(vertex, 1, &vertex_str, NULL);
glCompileShader(vertex);
log_shader_compile_errors(vertex, "vertex");
fragment = glCreateShader(GL_FRAGMENT_SHADER);
const char* frag_str = fragmentSource.data();
glShaderSource(fragment, 1, &frag_str, NULL);
glCompileShader(fragment);
log_shader_compile_errors(fragment, "fragment");
int shaderId = glCreateProgram();
glAttachShader(shaderId, vertex);
glAttachShader(shaderId, fragment);
glLinkProgram(shaderId);
log_program_compile_errors(shaderId);
glDeleteShader(vertex);
glDeleteShader(fragment);
return std::make_shared<ShaderProgram>(ShaderProgram(shaderId));
}
void log_shader_compile_errors(GLuint shader, std::string_view shaderType)
{
GLint success;
GLchar infoLog[1024];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
spdlog::error("Failed to compile {} shader: {}", shaderType, infoLog);
}
}
void log_program_compile_errors(GLuint program)
{
GLint success;
GLchar infoLog[1024];
glGetProgramiv(program, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(program, 1024, NULL, infoLog);
spdlog::error("Failed to compile program: {}", infoLog);
}
}

19
src/ShaderLoader.h Normal file
View File

@@ -0,0 +1,19 @@
//
// Created by slinky on 5/1/26.
//
#ifndef B_ENGINE_SHADERLOADER_H
#define B_ENGINE_SHADERLOADER_H
#include <memory>
#include "ShaderProgram.h"
class ShaderLoader {
public:
static std::unordered_map<std::string, std::shared_ptr<ShaderProgram>> shaders;
static std::shared_ptr<ShaderProgram> load(std::string_view vertexPath, std::string_view fragmentPath);
};
#endif //B_ENGINE_SHADERLOADER_H

View File

@@ -5,68 +5,8 @@
#include "ShaderProgram.h"
#include <fstream>
#include <string>
#include <sstream>
#include "glad/gl.h"
#include "spdlog/spdlog.h"
void log_shader_compile_errors(GLuint shader, std::string_view shaderType);
void log_program_compile_errors(GLuint program);
std::shared_ptr<ShaderProgram> ShaderProgram::load(std::string_view vertexPath, std::string_view fragmentPath)
{
std::string vertexSource;
std::string fragmentSource;
std::ifstream vertexFile {};
std::ifstream fragmentFile {};
try
{
std::stringstream ss;
vertexFile.open(vertexPath.data());
fragmentFile.open(fragmentPath.data());
ss << vertexFile.rdbuf();
vertexSource = ss.str();
ss.clear();
ss << fragmentFile.rdbuf();
fragmentSource = ss.str();
vertexFile.close();
fragmentFile.close();
} catch (std::ifstream::failure& e) {
spdlog::error("Failed to load shader program {}, {}: {}", vertexPath, fragmentPath, std::string(e.what()).c_str());
return nullptr;
}
unsigned int vertex;
unsigned int fragment;
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, reinterpret_cast<const GLchar* const*>(vertexSource.data()), NULL);
glCompileShader(vertex);
log_shader_compile_errors(vertex, "vertex");
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, reinterpret_cast<const GLchar* const*>(fragmentSource.data()), NULL);
glCompileShader(fragment);
log_shader_compile_errors(fragment, "fragment");
ShaderProgram program;
program.id = glCreateProgram();
glAttachShader(program.id, vertex);
glAttachShader(program.id, fragment);
glLinkProgram(program.id);
log_program_compile_errors(program.id);
glDeleteShader(vertex);
glDeleteShader(fragment);
return std::make_shared<ShaderProgram>(program);
}
#include <glad/gl.h>
void ShaderProgram::bind()
{
@@ -80,49 +20,26 @@ void ShaderProgram::unbind()
void ShaderProgram::setFloat(std::string_view name, float value) const
{
glUniform1f(glGetUniformLocation(id, name.data()), value);
}
void ShaderProgram::setVec2(std::string_view name, const glm::vec2& value) const
void ShaderProgram::setInt(std::string_view name, int value) const
{
glUniform1i(glGetUniformLocation(id, name.data()), value);
}
void ShaderProgram::setVec3(std::string_view name, const glm::vec3& value) const
{
glUniform3fv(glGetUniformLocation(id, name.data()), 1, &value[0]);
}
void ShaderProgram::setVec4(std::string_view name, const glm::vec4& value) const
{
glUniform4fv(glGetUniformLocation(id, name.data()), 1, &value[0]);
}
void ShaderProgram::setMat4(std::string_view name, const glm::mat4& value) const
{
glUniformMatrix4fv(glGetUniformLocation(id, name.data()), 1, GL_FALSE, &value[0][0]);
}
void log_shader_compile_errors(GLuint shader, std::string_view shaderType)
{
GLint success;
GLchar infoLog[1024];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
spdlog::error("Failed to compile {} shader: {}", shaderType, infoLog);
}
}
void log_program_compile_errors(GLuint program)
{
GLint success;
GLchar infoLog[1024];
glGetProgramiv(program, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(program, 1024, NULL, infoLog);
spdlog::error("Failed to compile program: {}", infoLog);
}
}

View File

@@ -15,13 +15,13 @@
class ShaderProgram
{
public:
static std::shared_ptr<ShaderProgram> load(std::string_view vertexPath, std::string_view fragmentPath);
explicit ShaderProgram(GLuint id) : id(id) {}
void bind();
void unbind();
static void unbind();
void setFloat(std::string_view name, float value) const;
void setVec2(std::string_view name, const glm::vec2 &value) const;
void setInt(std::string_view name, int value) const;
void setVec3(std::string_view name, const glm::vec3 &value) const;
void setMat4(std::string_view name, const glm::mat4 &mat) const;
void setVec4(std::string_view name, const glm::vec4 &value) const;

View File

@@ -5,21 +5,21 @@
#ifndef B_ENGINE_TEXTURE_H
#define B_ENGINE_TEXTURE_H
#include <memory>
#include <string_view>
#include <string>
#include <glad/gl.h>
class Texture
{
public:
static std::shared_ptr<Texture> load_from_file(std::string_view filePath);
static std::shared_ptr<Texture> load_from_data(unsigned char* data, int width, int height, int channels);
Texture(unsigned int id, std::string_view filePath, int width, int height, int channels)
: id(id), filePath(filePath), width(width), height(height), channels(channels) {}
Texture() = default;
~Texture();
~Texture() { glDeleteTextures(1, &id); }
void bind(unsigned int slot);
void unbind();
void bind() const {glBindTexture(GL_TEXTURE_2D, id);}
static void unbind() {glBindTexture(GL_TEXTURE_2D, 0);}
[[nodiscard]] int get_width() const { return width; }
[[nodiscard]] int get_height() const { return height; }

View File

@@ -1,8 +1,8 @@
//
// Created by lbmas on 4/29/2026.
// Created by slinky on 5/1/26.
//
#include "Texture.h"
#include "TextureLoader.h"
#include "stb_image.h"
@@ -10,7 +10,9 @@
#include "glad/gl.h"
std::shared_ptr<Texture> Texture::load_from_file(std::string_view filePath)
std::unordered_map<std::string, std::shared_ptr<Texture>> TextureLoader::textures;
std::shared_ptr<Texture> TextureLoader::load_from_file(std::string_view filePath)
{
int width, height, channels;
unsigned char *data = stbi_load(filePath.data(), &width, &height, &channels, 0);
@@ -20,9 +22,9 @@ std::shared_ptr<Texture> Texture::load_from_file(std::string_view filePath)
return nullptr;
}
Texture texture = {};
glGenTextures(1, &texture.id);
glBindTexture(GL_TEXTURE_2D, texture.id);
unsigned int textureID = 0;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -36,18 +38,14 @@ std::shared_ptr<Texture> Texture::load_from_file(std::string_view filePath)
stbi_image_free(data);
texture.filePath = filePath;
texture.width = width;
texture.height = height;
texture.channels = channels;
return std::make_shared<Texture>(texture);
return std::make_shared<Texture>(textureID, filePath, width, height, channels);
}
std::shared_ptr<Texture> Texture::load_from_data(unsigned char* data, int width, int height, int channels)
std::shared_ptr<Texture> TextureLoader::load_from_data(unsigned char* data, int width, int height, int channels)
{
Texture texture = {};
glGenTextures(1, &texture.id);
glBindTexture(GL_TEXTURE_2D, texture.id);
unsigned int textureID = 0;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
@@ -59,24 +57,5 @@ std::shared_ptr<Texture> Texture::load_from_data(unsigned char* data, int width,
glTexImage2D(GL_TEXTURE_2D, 0, (GLint)format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
texture.filePath = "";
texture.width = width;
texture.height = height;
texture.channels = channels;
return std::make_shared<Texture>(texture);
}
Texture::~Texture()
{
glDeleteTextures(1, &id);
}
void Texture::bind(unsigned int slot)
{
}
void Texture::unbind()
{
}
return std::make_shared<Texture>(textureID, "memory", width, height, channels);
}

21
src/TextureLoader.h Normal file
View File

@@ -0,0 +1,21 @@
//
// Created by slinky on 5/1/26.
//
#ifndef B_ENGINE_TEXTURELOADER_H
#define B_ENGINE_TEXTURELOADER_H
#include <memory>
#include <unordered_map>
#include "Texture.h"
class TextureLoader {
public:
static std::unordered_map<std::string, std::shared_ptr<Texture>> textures;
static std::shared_ptr<Texture> load_from_file(std::string_view filePath);
static std::shared_ptr<Texture> load_from_data(unsigned char* data, int width, int height, int channels);
};
#endif //B_ENGINE_TEXTURELOADER_H

View File

@@ -11,8 +11,11 @@
#include "stb_image.h"
#include "Model.h"
#include "ModelLoader.h"
#include "ShaderLoader.h"
#include "ShaderProgram.h"
#include "Texture.h"
#include "TextureLoader.h"
GLFWwindow* gWindow = nullptr;
int gWindowWidth = 800;
@@ -25,10 +28,6 @@ auto cameraPosition = glm::vec3{0, 0, 0};
auto view = glm::mat4{0};
auto projection = glm::mat4{0};
std::unordered_map<std::string, std::shared_ptr<Model>> gModels = {};
std::unordered_map<std::string, std::shared_ptr<Texture>> gTextures = {};
std::unordered_map<std::string, std::shared_ptr<ShaderProgram>> gShaders = {};
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);
@@ -37,6 +36,7 @@ void init_glfw();
void create_main_window();
void load_gl();
void init_camera();
void loop();
std::shared_ptr<Model> load_model(std::string_view _path);
@@ -55,26 +55,21 @@ int main() {
// create a default texture
unsigned char defaultDiffuseData[4] = {static_cast<unsigned char>(255), 255, 255, 255};
gTextures["default_diffuse"] = Texture::load_from_data(reinterpret_cast<unsigned char*>(&defaultDiffuseData), 1, 1, 4);
TextureLoader::textures["default_diffuse"] = TextureLoader::load_from_data(reinterpret_cast<unsigned char*>(&defaultDiffuseData), 1, 1, 4);
// create a default specular map
unsigned char defaultSpecularData[4] = {static_cast<unsigned char>(128), 128, 128, 255};
gTextures["default_specular"] = Texture::load_from_data(reinterpret_cast<unsigned char*>(&defaultSpecularData), 1, 1, 4);
TextureLoader::textures["default_specular"] = TextureLoader::load_from_data(reinterpret_cast<unsigned char*>(&defaultSpecularData), 1, 1, 4);
gShaders["phong_shader"] = ShaderProgram::load("./resources/standard.frag", "./resources/standard.vert");
if (gShaders["phong_shader"] == nullptr)
ShaderLoader::shaders["phong_shader"] = ShaderLoader::load("./resources/standard.vert", "./resources/standard.frag");
if (ShaderLoader::shaders["phong_shader"] == nullptr)
{
std::exit(1);
}
while (!glfwWindowShouldClose(gWindow)) {
glfwPollEvents();
ModelLoader::models["cube"] = ModelLoader::load_from_file("./resources/cube.obj");
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glfwSwapBuffers(gWindow);
}
loop();
glfwDestroyWindow(gWindow);
glfwTerminate();
@@ -153,7 +148,56 @@ void init_camera()
projection = glm::perspective(glm::radians(75.f), aspectRatio, 0.1f, 100.0f);
}
std::shared_ptr<Model> load_model(std::string_view _path)
{
return std::make_shared<Model>();
void loop() {
Texture* defaultDiffuse = TextureLoader::textures["default_diffuse"].get();
Texture* defaultSpecular = TextureLoader::textures["default_specular"].get();
while (!glfwWindowShouldClose(gWindow)) {
auto modelMatrix = glm::identity<glm::mat4>();
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
ShaderProgram* shader = ShaderLoader::shaders["phong_shader"].get();
Model* model = ModelLoader::models["cube"].get();
if (shader && model) {
Material* mat = model->materials[0].get();
shader->bind();
shader->setMat4("projection", projection);
shader->setMat4("view", view);
shader->setMat4("model", modelMatrix);
shader->setVec3("viewPosition", cameraPosition);
if (mat) {
shader->setVec3("phongAmbient", mat->phong.ambient);
shader->setVec3("phongDiffuse", mat->phong.diffuse);
shader->setVec3("phongSpecular", mat->phong.specular);
shader->setFloat("phongShininess", mat->phong.shininess);
}
shader->setVec3("lightPosition", glm::vec3(5.f, 5.f, 5.f));
shader->setVec3("lightAmbient", glm::vec3{.1f, .1f, .1f});
shader->setVec3("lightDiffuse", glm::vec3{.8f, .8f, .8f});
shader->setVec3("lightSpecular", glm::vec3{1.f, 1.f, 1.f});
glActiveTexture(GL_TEXTURE0);
defaultDiffuse->bind();
shader->setInt("diffuse1", 0);
glActiveTexture(GL_TEXTURE1);
defaultSpecular->bind();
shader->setInt("specular1", 1);
for (auto mesh: model->meshes) {
glBindVertexArray(mesh.get()->vao);
glDrawElements(GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, 0);
}
}
glfwSwapBuffers(gWindow);
}
}