started fixing stuff with model imports

This commit is contained in:
2026-05-03 00:08:13 -05:00
parent 782bbcbadc
commit 68020255d0
13 changed files with 199571 additions and 81 deletions

BIN
resources/backpack/ao.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@@ -0,0 +1,16 @@
# Blender MTL File: 'None'
# Material Count: 1
newmtl Scene_-_Root
Ns 225.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.0 0.0 0.0
Ni 1.450000
d 1.000000
illum 2
map_Kd diffuse.jpg
map_Bump normal.png
map_Ks specular.jpg

199481
resources/backpack/backpack.obj Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 MiB

View File

@@ -0,0 +1,3 @@
Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36
Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup.

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 MiB

View File

@@ -8,35 +8,25 @@ in vec3 Normal;
uniform vec3 viewPosition; uniform vec3 viewPosition;
uniform sampler2D diffuse1;
uniform sampler2D specular1;
uniform vec3 phongAmbient; uniform vec3 phongAmbient;
uniform vec3 phongDiffuse; uniform vec3 phongDiffuse;
uniform vec3 phongSpecular; uniform vec3 phongSpecular;
uniform float phongShininess; uniform float phongShininess;
uniform vec3 lightPos; uniform vec3 lightDirection;
uniform vec3 lightAmbient; uniform vec3 lightAmbient;
uniform vec3 lightDiffuse; uniform vec3 lightDiffuse;
uniform vec3 lightSpecular; uniform vec3 lightSpecular;
void main() { void main() {
vec3 diffColor = texture(diffuse1, TexCoord).rgb;
vec3 specColor = texture(specular1, TexCoord).rgb;
vec3 ambient = (phongAmbient * diffColor) * lightAmbient;
vec3 norm = normalize(Normal); vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - Position); vec3 lightDir = normalize(-lightDirection);
vec3 ambient = (phongAmbient);
float diffImpact = max(dot(norm, lightDir), 0.0); float diffImpact = max(dot(norm, lightDir), 0.0);
vec3 diffuse = (phongDiffuse * diffImpact * diffColor) * lightDiffuse; vec3 diffuse = (phongDiffuse * diffImpact);
vec3 viewDir = normalize(viewPosition - Position); vec3 result = ambient + diffuse;
vec3 halfwayDir = normalize(lightDir + viewDir);
float specImpact = pow(max(dot(norm, halfwayDir), 0.0), phongShininess);
vec3 specular = (phongSpecular * specImpact * specColor) * lightSpecular;
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0); FragColor = vec4(result, 1.0);
} }

View File

@@ -7,8 +7,7 @@ Mesh::Mesh(const std::vector<float> &positions, const std::vector<float> &uvs, c
vao = 0; vao = 0;
ebo = 0; ebo = 0;
numIndices = indices.size(); numIndices = indices.size();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// positions // positions
GLuint positionVbo = 0; GLuint positionVbo = 0;
@@ -28,10 +27,7 @@ Mesh::Mesh(const std::vector<float> &positions, const std::vector<float> &uvs, c
glBindBuffer(GL_ARRAY_BUFFER, normalVbo); glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float), normals.data(), GL_STATIC_DRAW); glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(float), normals.data(), GL_STATIC_DRAW);
glGenBuffers(1, &ebo); // build the vao
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
glGenVertexArrays(1, &vao); glGenVertexArrays(1, &vao);
glBindVertexArray(vao); glBindVertexArray(vao);
@@ -47,5 +43,9 @@ Mesh::Mesh(const std::vector<float> &positions, const std::vector<float> &uvs, c
glBindBuffer(GL_ARRAY_BUFFER, normalVbo); glBindBuffer(GL_ARRAY_BUFFER, normalVbo);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glGenBuffers(1, &ebo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), indices.data(), GL_STATIC_DRAW);
glBindVertexArray(0); glBindVertexArray(0);
} }

View File

@@ -12,11 +12,13 @@
#include <cstring> #include <cstring>
#include "glm/ext/matrix_transform.hpp"
std::unordered_map<std::string, std::shared_ptr<Model>> ModelLoader::models; std::unordered_map<std::string, std::shared_ptr<Model>> ModelLoader::models;
Mesh process_ai_mesh(aiMesh* aiMesh);
void process_ai_node(aiNode* node, const aiScene* scene, Model* model); void process_ai_node(aiNode* node, const aiScene* scene, Model* model);
Mesh process_ai_mesh(const aiMesh* aiMesh);
Material process_ai_material(aiMaterial* mat); Material process_ai_material(aiMaterial* mat);
std::shared_ptr<Model> ModelLoader::load_from_file(std::string_view _path) std::shared_ptr<Model> ModelLoader::load_from_file(std::string_view _path)
@@ -25,9 +27,8 @@ std::shared_ptr<Model> ModelLoader::load_from_file(std::string_view _path)
const aiScene* scene = importer.ReadFile(_path.data(), const aiScene* scene = importer.ReadFile(_path.data(),
aiProcess_Triangulate | aiProcess_Triangulate |
aiProcess_GenSmoothNormals | aiProcess_GenNormals |
aiProcess_FlipUVs | aiProcess_FlipUVs);
aiProcess_CalcTangentSpace);
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
{ {
@@ -37,64 +38,65 @@ std::shared_ptr<Model> ModelLoader::load_from_file(std::string_view _path)
auto model = std::make_shared<Model>(); auto model = std::make_shared<Model>();
model->materials.resize(scene->mNumMaterials); process_ai_node(scene->mRootNode, scene, model.get());
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; return model;
} }
void process_ai_node(aiNode* node, const aiScene* scene, Model* model) void process_ai_node(aiNode* node, const aiScene* scene, glm::mat4 transform, Model* model)
{ {
for (unsigned int i = 0; i < node->mNumChildren; i++) { auto t = node->mTransformation;
transform = transform * glm::mat4(nTransform)
for (unsigned int i = 0; i < node->mNumMeshes; i++)
{
aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
model->meshes.push_back(std::make_shared<Mesh>(process_ai_mesh(mesh)));
}
for (unsigned int i = 0; i < node->mNumChildren; i++)
{
process_ai_node(node->mChildren[i], scene, model);
} }
} }
Mesh process_ai_mesh(const aiMesh* aiMesh) Mesh process_ai_mesh(aiMesh* aiMesh)
{ {
auto positions = std::vector<float>(aiMesh->mNumVertices * 3); auto positions = std::vector<float>(aiMesh->mNumVertices * 3);
auto uvs = std::vector<float>(aiMesh->mNumVertices * 2); auto uvs = std::vector<float>(aiMesh->mNumVertices * 2);
auto normals = std::vector<float>(aiMesh->mNumVertices * 3); auto normals = std::vector<float>(aiMesh->mNumVertices * 3);
auto indices = std::vector<unsigned int>(aiMesh->mNumFaces * 3); auto indices = std::vector<unsigned int>();
for (unsigned int i = 0; i < aiMesh->mNumVertices; i++) for (unsigned int i = 0; i < aiMesh->mNumVertices; i++)
{ {
auto position = aiMesh->mVertices[i]; auto position = aiMesh->mVertices[i];
positions.push_back(position.x); positions[3 * i] = position.x;
positions.push_back(position.y); positions[3 * i + 1] = position.y;
positions.push_back(position.z); positions[3 * i + 2] = position.z;
if (aiMesh->HasNormals()) if (aiMesh->HasNormals())
{ {
normals.push_back(aiMesh->mNormals[i].x); aiVector3D norm = aiMesh->mNormals[i];
normals.push_back(aiMesh->mNormals[i].y); normals[3 * i] = norm.x;
normals.push_back(aiMesh->mNormals[i].z); normals[3 * i + 1] = norm.y;
normals[3 * i + 2] = norm.z;
} }
else else
{ {
normals.push_back(0); normals[3 * i] = 0;
normals.push_back(0); normals[3 * i + 1] = 0;
normals.push_back(0); normals[3 * i + 2] = 0;
} }
if (aiMesh->HasTextureCoords(0)) if (aiMesh->HasTextureCoords(0))
{ {
uvs.push_back(aiMesh->mTextureCoords[0][i].x); uvs[2 * i] = aiMesh->mTextureCoords[0][i].x;
uvs.push_back(aiMesh->mTextureCoords[0][i].y); uvs[2 * i + 1] = aiMesh->mTextureCoords[0][i].y;
} }
else else
{ {
uvs.push_back(0); uvs[2 * i] = 0;
uvs.push_back(0); uvs[2 * i + 1] = 0;
} }
} }

View File

@@ -5,6 +5,8 @@
#ifndef B_ENGINE_SHADERLOADER_H #ifndef B_ENGINE_SHADERLOADER_H
#define B_ENGINE_SHADERLOADER_H #define B_ENGINE_SHADERLOADER_H
#include <string>
#include <string_view>
#include <memory> #include <memory>
#include "ShaderProgram.h" #include "ShaderProgram.h"

View File

@@ -68,6 +68,7 @@ int main() {
} }
ModelLoader::models["cube"] = ModelLoader::load_from_file("./resources/cube.obj"); ModelLoader::models["cube"] = ModelLoader::load_from_file("./resources/cube.obj");
ModelLoader::models["backpack"] = ModelLoader::load_from_file("./resources/backpack/backpack.obj");
loop(); loop();
@@ -132,11 +133,13 @@ void load_gl()
glfwGetFramebufferSize(gWindow, &fbWidth, &fbHeight); glfwGetFramebufferSize(gWindow, &fbWidth, &fbHeight);
glViewport(0, 0, fbWidth, fbHeight); glViewport(0, 0, fbWidth, fbHeight);
} }
glEnable(GL_DEPTH_TEST);
} }
void init_camera() void init_camera()
{ {
cameraPosition = glm::vec3{0, 5, 5}; cameraPosition = glm::vec3{5, 0, 5};
auto cameraTarget = glm::vec3{0, 0, 0}; auto cameraTarget = glm::vec3{0, 0, 0};
auto behind = glm::normalize(cameraPosition - cameraTarget); auto behind = glm::normalize(cameraPosition - cameraTarget);
@@ -153,49 +156,42 @@ void loop() {
Texture* defaultSpecular = TextureLoader::textures["default_specular"].get(); Texture* defaultSpecular = TextureLoader::textures["default_specular"].get();
while (!glfwWindowShouldClose(gWindow)) { while (!glfwWindowShouldClose(gWindow)) {
auto modelMatrix = glm::identity<glm::mat4>(); auto model = glm::identity<glm::mat4>();
glfwPollEvents(); glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
ShaderProgram* shader = ShaderLoader::shaders["phong_shader"].get(); ShaderProgram* shader = ShaderLoader::shaders["phong_shader"].get();
Model* model = ModelLoader::models["cube"].get(); const Model* cube = ModelLoader::models["cube"].get();
const Model* backpack = ModelLoader::models["backpack"].get();
if (shader && model) { if (shader && backpack) {
Material* mat = model->materials[0].get();
shader->bind(); shader->bind();
shader->setMat4("projection", projection); shader->setMat4("projection", projection);
shader->setMat4("view", view); shader->setMat4("view", view);
shader->setMat4("model", modelMatrix); shader->setMat4("model", model);
shader->setVec3("viewPosition", cameraPosition); shader->setVec3("viewPosition", cameraPosition);
if (mat) { shader->setVec3("phongAmbient", glm::vec3(0.3f, 0.3f, 0.3f));
shader->setVec3("phongAmbient", mat->phong.ambient); shader->setVec3("phongDiffuse", glm::vec3(0.8f, 0.8f, 0.8f));
shader->setVec3("phongDiffuse", mat->phong.diffuse); shader->setVec3("phongSpecular", glm::vec3(1.0f, 1.0f, 1.0f));
shader->setVec3("phongSpecular", mat->phong.specular); shader->setFloat("phongShininess", 32.0f);
shader->setFloat("phongShininess", mat->phong.shininess);
}
shader->setVec3("lightPosition", glm::vec3(5.f, 5.f, 5.f)); shader->setVec3("lightDirection", glm::vec3(0, 1, 0));
shader->setVec3("lightAmbient", glm::vec3{.1f, .1f, .1f}); shader->setVec3("lightAmbient", glm::vec3(0.3f, 0.3f, 0.3f));
shader->setVec3("lightDiffuse", glm::vec3{.8f, .8f, .8f}); shader->setVec3("lightDiffuse", glm::vec3(1.0f, 1.0f, 1.0f));
shader->setVec3("lightSpecular", glm::vec3{1.f, 1.f, 1.f}); shader->setVec3("lightSpecular", glm::vec3(1.0f, 1.0f, 1.0f));
glActiveTexture(GL_TEXTURE0); for (const auto& mesh: backpack->meshes) {
defaultDiffuse->bind();
shader->setInt("diffuse1", 0);
glActiveTexture(GL_TEXTURE1);
defaultSpecular->bind();
shader->setInt("specular1", 1);
for (auto mesh: model->meshes) {
glBindVertexArray(mesh.get()->vao); glBindVertexArray(mesh.get()->vao);
glDrawElements(GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, 0); glDrawElements(GL_TRIANGLES, mesh->numIndices, GL_UNSIGNED_INT, 0);
} }
glBindVertexArray(0);
ShaderProgram::unbind();
} }
glfwSwapBuffers(gWindow); glfwSwapBuffers(gWindow);