Compare commits
2 Commits
7233d67fb1
...
073288fc63
Author | SHA1 | Date | |
---|---|---|---|
|
073288fc63 | ||
|
557f6b2386 |
73
.vscode/settings.json
vendored
@ -4,6 +4,77 @@
|
||||
"*.js": "javascript",
|
||||
"*.c": "c",
|
||||
"*.scene": "yaml",
|
||||
"iostream": "cpp"
|
||||
"iostream": "cpp",
|
||||
"any": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"cctype": "cpp",
|
||||
"charconv": "cpp",
|
||||
"chrono": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"regex": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"format": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"text_encoding": "cpp",
|
||||
"thread": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"variant": "cpp"
|
||||
}
|
||||
}
|
@ -12,6 +12,8 @@
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "stb_image.h"
|
||||
#include <fstream>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
using std::vector;
|
||||
|
||||
@ -46,7 +48,6 @@ bool LoadIconTexture(const char* filepath, GLuint &texOut, ImTextureID &imTexOut
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Editor camera.
|
||||
struct EditorCamera {
|
||||
glm::vec3 position = glm::vec3(0.0f, 0.0f, 8.0f);
|
||||
@ -166,8 +167,6 @@ int main() {
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
|
||||
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
@ -213,6 +212,59 @@ int main() {
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
// New Panel: File Operations (Save/Load).
|
||||
ImGui::Begin("Scene File");
|
||||
if (ImGui::Button("Save")) {
|
||||
YAML::Emitter out;
|
||||
out << YAML::BeginMap;
|
||||
// Save an array of entities.
|
||||
out << YAML::Key << "entities" << YAML::Value << YAML::BeginSeq;
|
||||
for (auto e : entities) {
|
||||
out << YAML::BeginMap;
|
||||
// Save the type.
|
||||
out << YAML::Key << "type" << YAML::Value << (e->GetType() == EntityType::CUBE ? "cube" : "light");
|
||||
// Save transform.
|
||||
out << YAML::Key << "transform" << YAML::Value << e->transform.Save();
|
||||
// Save model component if cube.
|
||||
if (e->GetType() == EntityType::CUBE && e->modelComponent) {
|
||||
out << YAML::Key << "model" << YAML::Value << e->modelComponent->Save();
|
||||
}
|
||||
// Save light component if light.
|
||||
if (e->GetType() == EntityType::LIGHT && e->lightComponent) {
|
||||
out << YAML::Key << "light" << YAML::Value << e->lightComponent->Save();
|
||||
}
|
||||
out << YAML::EndMap;
|
||||
}
|
||||
out << YAML::EndSeq;
|
||||
out << YAML::EndMap;
|
||||
|
||||
std::ofstream fout("default.yaml");
|
||||
fout << out.c_str();
|
||||
fout.close();
|
||||
}
|
||||
if (ImGui::Button("Load")) {
|
||||
YAML::Node node = YAML::LoadFile("default.yaml");
|
||||
if (node["entities"]) {
|
||||
YAML::Node entitiesNode = node["entities"];
|
||||
int idx = 0;
|
||||
for (auto entityNode : entitiesNode) {
|
||||
if (idx < entities.size()) {
|
||||
// Load transform.
|
||||
if (entityNode["transform"])
|
||||
entities[idx]->transform.Load(entityNode["transform"]);
|
||||
// Load model for cubes.
|
||||
if (entities[idx]->GetType() == EntityType::CUBE && entityNode["model"])
|
||||
entities[idx]->modelComponent->Load(entityNode["model"]);
|
||||
// Load light for lights.
|
||||
if (entities[idx]->GetType() == EntityType::LIGHT && entityNode["light"])
|
||||
entities[idx]->lightComponent->Load(entityNode["light"]);
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
// Bottom Panel: Rendered Output.
|
||||
ImGui::Begin("Rendered Output");
|
||||
ImVec2 viewportSize = ImGui::GetContentRegionAvail();
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "Component.h"
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
// A simple Camera component that inherits from Component.
|
||||
class Camera : public Component {
|
||||
@ -32,6 +33,46 @@ public:
|
||||
float GetYaw() const;
|
||||
float GetPitch() const;
|
||||
|
||||
// Save the camera state to a YAML node.
|
||||
virtual YAML::Node Save() const override {
|
||||
YAML::Node node;
|
||||
node["position"] = YAML::Node();
|
||||
node["position"].push_back(position.x);
|
||||
node["position"].push_back(position.y);
|
||||
node["position"].push_back(position.z);
|
||||
|
||||
node["yaw"] = yaw;
|
||||
node["pitch"] = pitch;
|
||||
node["fov"] = fov;
|
||||
node["aspect"] = aspect;
|
||||
node["nearPlane"] = nearPlane;
|
||||
node["farPlane"] = farPlane;
|
||||
return node;
|
||||
}
|
||||
|
||||
// Load the camera state from a YAML node.
|
||||
virtual void Load(const YAML::Node &node) override {
|
||||
if (node["position"]) {
|
||||
position.x = node["position"][0].as<float>();
|
||||
position.y = node["position"][1].as<float>();
|
||||
position.z = node["position"][2].as<float>();
|
||||
}
|
||||
if (node["yaw"])
|
||||
yaw = node["yaw"].as<float>();
|
||||
if (node["pitch"])
|
||||
pitch = node["pitch"].as<float>();
|
||||
if (node["fov"])
|
||||
fov = node["fov"].as<float>();
|
||||
if (node["aspect"])
|
||||
aspect = node["aspect"].as<float>();
|
||||
if (node["nearPlane"])
|
||||
nearPlane = node["nearPlane"].as<float>();
|
||||
if (node["farPlane"])
|
||||
farPlane = node["farPlane"].as<float>();
|
||||
}
|
||||
|
||||
// (Other Camera methods remain unchanged.)
|
||||
|
||||
private:
|
||||
glm::vec3 position;
|
||||
float yaw;
|
||||
|
@ -1,12 +1,19 @@
|
||||
#ifndef COMPONENT_H
|
||||
#define COMPONENT_H
|
||||
|
||||
// Base Component class for all components.
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
class Component {
|
||||
public:
|
||||
virtual ~Component() {}
|
||||
|
||||
// Update the component each frame.
|
||||
virtual void Update(float deltaTime) = 0;
|
||||
|
||||
// Save the component's state to a YAML node.
|
||||
virtual YAML::Node Save() const = 0;
|
||||
// Load the component's state from a YAML node.
|
||||
virtual void Load(const YAML::Node &node) = 0;
|
||||
};
|
||||
|
||||
#endif // COMPONENT_H
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define LIGHT_COMPONENT_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
class LightComponent {
|
||||
public:
|
||||
@ -11,6 +12,28 @@ public:
|
||||
// Light properties.
|
||||
glm::vec3 color;
|
||||
float intensity;
|
||||
|
||||
// Save this light to a YAML node.
|
||||
YAML::Node Save() const {
|
||||
YAML::Node node;
|
||||
node["color"] = YAML::Node();
|
||||
node["color"].push_back(color.x);
|
||||
node["color"].push_back(color.y);
|
||||
node["color"].push_back(color.z);
|
||||
node["intensity"] = intensity;
|
||||
return node;
|
||||
}
|
||||
|
||||
// Load this light from a YAML node.
|
||||
void Load(const YAML::Node &node) {
|
||||
if (node["color"]) {
|
||||
color.x = node["color"][0].as<float>();
|
||||
color.y = node["color"][1].as<float>();
|
||||
color.z = node["color"][2].as<float>();
|
||||
}
|
||||
if (node["intensity"])
|
||||
intensity = node["intensity"].as<float>();
|
||||
}
|
||||
};
|
||||
|
||||
#endif // LIGHT_COMPONENT_H
|
||||
|
@ -1,183 +1,46 @@
|
||||
#include "ModelComponent.h"
|
||||
#include "stb_image.h"
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include "tiny_obj_loader.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
// Constructor: initialize material defaults, create default cube mesh, and load default textures.
|
||||
// Constructor: initialize default values.
|
||||
ModelComponent::ModelComponent()
|
||||
: diffuseColor(1.0f, 1.0f, 1.0f),
|
||||
: modelPath("./assets/models/sponza.obj"),
|
||||
diffuseColor(1.0f, 1.0f, 1.0f),
|
||||
specularColor(1.0f, 1.0f, 1.0f),
|
||||
shininess(32.0f),
|
||||
VAO(0), VBO(0), EBO(0),
|
||||
diffuseTexture(0), normalTexture(0)
|
||||
shininess(32.0f)
|
||||
{
|
||||
// Clear any previous data.
|
||||
vertices.clear();
|
||||
indices.clear();
|
||||
|
||||
// Create 24 vertices for a cube.
|
||||
// Front face (z = 0.5)
|
||||
Vertex v;
|
||||
v.Normal = glm::vec3(0, 0, 1);
|
||||
v.Tangent = glm::vec3(1, 0, 0);
|
||||
// Top-left
|
||||
v.Position = glm::vec3(-0.5f, 0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-left
|
||||
v.Position = glm::vec3(-0.5f, -0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-right
|
||||
v.Position = glm::vec3( 0.5f, -0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Top-right
|
||||
v.Position = glm::vec3( 0.5f, 0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
|
||||
// Right face (x = 0.5)
|
||||
v.Normal = glm::vec3(1, 0, 0);
|
||||
v.Tangent = glm::vec3(0, 0, -1);
|
||||
// Top-left
|
||||
v.Position = glm::vec3(0.5f, 0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-left
|
||||
v.Position = glm::vec3(0.5f, -0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-right
|
||||
v.Position = glm::vec3(0.5f, -0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Top-right
|
||||
v.Position = glm::vec3(0.5f, 0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
|
||||
// Back face (z = -0.5)
|
||||
v.Normal = glm::vec3(0, 0, -1);
|
||||
v.Tangent = glm::vec3(-1, 0, 0);
|
||||
// Top-left
|
||||
v.Position = glm::vec3( 0.5f, 0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-left
|
||||
v.Position = glm::vec3( 0.5f, -0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-right
|
||||
v.Position = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Top-right
|
||||
v.Position = glm::vec3(-0.5f, 0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
|
||||
// Left face (x = -0.5)
|
||||
v.Normal = glm::vec3(-1, 0, 0);
|
||||
v.Tangent = glm::vec3(0, 0, 1);
|
||||
// Top-left
|
||||
v.Position = glm::vec3(-0.5f, 0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-left
|
||||
v.Position = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-right
|
||||
v.Position = glm::vec3(-0.5f, -0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Top-right
|
||||
v.Position = glm::vec3(-0.5f, 0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
|
||||
// Top face (y = 0.5)
|
||||
v.Normal = glm::vec3(0, 1, 0);
|
||||
v.Tangent = glm::vec3(1, 0, 0);
|
||||
// Top-left
|
||||
v.Position = glm::vec3(-0.5f, 0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-left
|
||||
v.Position = glm::vec3(-0.5f, 0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-right
|
||||
v.Position = glm::vec3( 0.5f, 0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Top-right
|
||||
v.Position = glm::vec3( 0.5f, 0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
|
||||
// Bottom face (y = -0.5)
|
||||
v.Normal = glm::vec3(0, -1, 0);
|
||||
v.Tangent = glm::vec3(1, 0, 0);
|
||||
// Top-left
|
||||
v.Position = glm::vec3(-0.5f, -0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-left
|
||||
v.Position = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Bottom-right
|
||||
v.Position = glm::vec3( 0.5f, -0.5f, -0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 0.0f);
|
||||
vertices.push_back(v);
|
||||
// Top-right
|
||||
v.Position = glm::vec3( 0.5f, -0.5f, 0.5f);
|
||||
v.TexCoords = glm::vec2(1.0f, 1.0f);
|
||||
vertices.push_back(v);
|
||||
|
||||
// Define indices: 6 faces, 2 triangles per face, 3 indices per triangle.
|
||||
indices = {
|
||||
0, 1, 2, 0, 2, 3, // Front face
|
||||
4, 5, 6, 4, 6, 7, // Right face
|
||||
8, 9, 10, 8, 10, 11, // Back face
|
||||
12, 13, 14, 12, 14, 15, // Left face
|
||||
16, 17, 18, 16, 18, 19, // Top face
|
||||
20, 21, 22, 20, 22, 23 // Bottom face
|
||||
};
|
||||
|
||||
// Setup mesh with the new vertex/index data.
|
||||
SetupMesh();
|
||||
|
||||
// Load default textures.
|
||||
if(!LoadDiffuseTexture("./assets/bricks.png")) {
|
||||
std::cout << "Warning: Failed to load default diffuse texture 'bricks.png'\n";
|
||||
}
|
||||
if(!LoadNormalTexture("./assets/normal.png")) {
|
||||
std::cout << "Warning: Failed to load default normal texture 'normal.png'\n";
|
||||
}
|
||||
// Load the model on construction.
|
||||
LoadModel(modelPath);
|
||||
}
|
||||
|
||||
ModelComponent::~ModelComponent() {
|
||||
if(VAO) glDeleteVertexArrays(1, &VAO);
|
||||
if(VBO) glDeleteBuffers(1, &VBO);
|
||||
if(EBO) glDeleteBuffers(1, &EBO);
|
||||
if(diffuseTexture) glDeleteTextures(1, &diffuseTexture);
|
||||
if(normalTexture) glDeleteTextures(1, &normalTexture);
|
||||
// Clean up each submesh.
|
||||
for (auto &mesh : meshes) {
|
||||
if(mesh.VAO) glDeleteVertexArrays(1, &mesh.VAO);
|
||||
if(mesh.VBO) glDeleteBuffers(1, &mesh.VBO);
|
||||
if(mesh.EBO) glDeleteBuffers(1, &mesh.EBO);
|
||||
if(mesh.diffuseTexture) glDeleteTextures(1, &mesh.diffuseTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void ModelComponent::SetupMesh() {
|
||||
glGenVertexArrays(1, &VAO);
|
||||
glGenBuffers(1, &VBO);
|
||||
glGenBuffers(1, &EBO);
|
||||
void ModelComponent::SetupMesh(SubMesh &mesh) {
|
||||
glGenVertexArrays(1, &mesh.VAO);
|
||||
glGenBuffers(1, &mesh.VBO);
|
||||
glGenBuffers(1, &mesh.EBO);
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindVertexArray(mesh.VAO);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.VBO);
|
||||
glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(Vertex), &mesh.vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), &indices[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(GLuint), &mesh.indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// Vertex attributes:
|
||||
// Positions.
|
||||
@ -196,16 +59,15 @@ void ModelComponent::SetupMesh() {
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
// LoadDiffuseTexture loads a diffuse texture from file.
|
||||
bool ModelComponent::LoadDiffuseTexture(const std::string &filepath) {
|
||||
bool ModelComponent::LoadDiffuseTexture(const std::string &filepath, GLuint &textureID) {
|
||||
int w, h, channels;
|
||||
unsigned char* data = stbi_load(filepath.c_str(), &w, &h, &channels, 0);
|
||||
if (!data) {
|
||||
std::cout << "Failed to load diffuse texture: " << filepath << std::endl;
|
||||
return false;
|
||||
}
|
||||
glGenTextures(1, &diffuseTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, diffuseTexture);
|
||||
glGenTextures(1, &textureID);
|
||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||
GLenum format = (channels == 3) ? GL_RGB : GL_RGBA;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
@ -217,30 +79,135 @@ bool ModelComponent::LoadDiffuseTexture(const std::string &filepath) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// LoadNormalTexture loads a normal map texture from file.
|
||||
bool ModelComponent::LoadNormalTexture(const std::string &filepath) {
|
||||
int w, h, channels;
|
||||
unsigned char* data = stbi_load(filepath.c_str(), &w, &h, &channels, 0);
|
||||
if (!data) {
|
||||
std::cout << "Failed to load normal texture: " << filepath << std::endl;
|
||||
// Similar to LoadDiffuseTexture but for normalTexture; not used in this submesh example.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Loads a model using tiny_obj_loader and groups faces by material.
|
||||
bool ModelComponent::LoadModel(const std::string &filepath) {
|
||||
|
||||
std::cout << "[Info] Loading Model \'" << filepath << "\' " << std::endl;
|
||||
modelPath = filepath;
|
||||
tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
std::string warn, err;
|
||||
|
||||
// Get the directory of the OBJ file.
|
||||
std::string baseDir = "";
|
||||
size_t lastSlash = filepath.find_last_of("/\\");
|
||||
if (lastSlash != std::string::npos) {
|
||||
baseDir = filepath.substr(0, lastSlash + 1);
|
||||
}
|
||||
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filepath.c_str(), baseDir.c_str());
|
||||
if (!warn.empty()) {
|
||||
std::cout << "[Warning] " << warn << std::endl;
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << "[Error] " << err << std::endl;
|
||||
}
|
||||
if (!ret) {
|
||||
std::cerr << "[Error] Failed to load/parse OBJ file: " << filepath << std::endl;
|
||||
return false;
|
||||
}
|
||||
glGenTextures(1, &normalTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, normalTexture);
|
||||
GLenum format = (channels == 3) ? GL_RGB : GL_RGBA;
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, w, h, 0, format, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
stbi_image_free(data);
|
||||
|
||||
// Clear any existing submeshes.
|
||||
meshes.clear();
|
||||
|
||||
// For each shape in the OBJ file.
|
||||
for (size_t s = 0; s < shapes.size(); s++) {
|
||||
// Use a map to group faces by material ID.
|
||||
std::map<int, SubMesh> submeshMap;
|
||||
size_t index_offset = 0;
|
||||
// Iterate over each face.
|
||||
for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
||||
int fv = shapes[s].mesh.num_face_vertices[f];
|
||||
// Get material ID for this face.
|
||||
int matID = -1;
|
||||
if (shapes[s].mesh.material_ids.size() > f)
|
||||
matID = shapes[s].mesh.material_ids[f];
|
||||
// If submesh for this material does not exist, create it.
|
||||
if (submeshMap.find(matID) == submeshMap.end())
|
||||
submeshMap[matID] = SubMesh();
|
||||
|
||||
SubMesh ¤tMesh = submeshMap[matID];
|
||||
// Process each vertex in the face.
|
||||
for (size_t v = 0; v < fv; v++) {
|
||||
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
|
||||
Vertex vertex;
|
||||
// Position.
|
||||
vertex.Position = glm::vec3(
|
||||
attrib.vertices[3 * idx.vertex_index + 0],
|
||||
attrib.vertices[3 * idx.vertex_index + 1],
|
||||
attrib.vertices[3 * idx.vertex_index + 2]
|
||||
);
|
||||
// Normal.
|
||||
if (idx.normal_index >= 0 && 3 * idx.normal_index + 2 < attrib.normals.size()) {
|
||||
vertex.Normal = glm::vec3(
|
||||
attrib.normals[3 * idx.normal_index + 0],
|
||||
attrib.normals[3 * idx.normal_index + 1],
|
||||
attrib.normals[3 * idx.normal_index + 2]
|
||||
);
|
||||
} else {
|
||||
vertex.Normal = glm::vec3(0.0f);
|
||||
}
|
||||
// Texture Coordinates.
|
||||
if (idx.texcoord_index >= 0 && 2 * idx.texcoord_index + 1 < attrib.texcoords.size()) {
|
||||
vertex.TexCoords = glm::vec2(
|
||||
attrib.texcoords[2 * idx.texcoord_index + 0],
|
||||
attrib.texcoords[2 * idx.texcoord_index + 1]
|
||||
);
|
||||
} else {
|
||||
vertex.TexCoords = glm::vec2(0.0f);
|
||||
}
|
||||
// Tangent not provided.
|
||||
vertex.Tangent = glm::vec3(0.0f);
|
||||
|
||||
// Add vertex and index.
|
||||
currentMesh.vertices.push_back(vertex);
|
||||
currentMesh.indices.push_back(static_cast<GLuint>(currentMesh.vertices.size() - 1));
|
||||
}
|
||||
index_offset += fv;
|
||||
}
|
||||
|
||||
// For each group (submesh) in this shape, set material properties and create buffers.
|
||||
for (auto &pair : submeshMap) {
|
||||
int matID = pair.first;
|
||||
SubMesh &subMesh = pair.second;
|
||||
// If there is a valid material, assign its properties.
|
||||
if (matID >= 0 && matID < static_cast<int>(materials.size())) {
|
||||
tinyobj::material_t mat = materials[matID];
|
||||
subMesh.diffuseColor = glm::vec3(mat.diffuse[0], mat.diffuse[1], mat.diffuse[2]);
|
||||
subMesh.specularColor = glm::vec3(mat.specular[0], mat.specular[1], mat.specular[2]);
|
||||
subMesh.shininess = mat.shininess;
|
||||
if (!mat.diffuse_texname.empty()) {
|
||||
std::string texturePath = baseDir + mat.diffuse_texname;
|
||||
LoadDiffuseTexture(texturePath, subMesh.diffuseTexture);
|
||||
}
|
||||
}
|
||||
// Setup the OpenGL buffers for this submesh.
|
||||
SetupMesh(subMesh);
|
||||
// Add submesh to our model.
|
||||
meshes.push_back(subMesh);
|
||||
}
|
||||
}
|
||||
std::cout << "[Done] Loaded Model \'" << filepath << "\' " << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Draw the mesh using its VAO.
|
||||
// Draws the entire model by drawing each submesh.
|
||||
void ModelComponent::Draw() {
|
||||
glBindVertexArray(VAO);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indices.size()), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
for (auto &mesh : meshes) {
|
||||
// Bind the appropriate texture if available.
|
||||
if(mesh.diffuseTexture) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh.diffuseTexture);
|
||||
}
|
||||
glBindVertexArray(mesh.VAO);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mesh.indices.size()), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
#ifndef MODEL_COMPONENT_H
|
||||
#define MODEL_COMPONENT_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <GL/glew.h>
|
||||
#include <glm/glm.hpp>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
// Structure representing a single vertex.
|
||||
struct Vertex {
|
||||
@ -14,36 +15,95 @@ struct Vertex {
|
||||
glm::vec3 Tangent;
|
||||
};
|
||||
|
||||
// Structure representing a sub-mesh (a group of faces sharing the same material)
|
||||
struct SubMesh {
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<GLuint> indices;
|
||||
glm::vec3 diffuseColor;
|
||||
glm::vec3 specularColor;
|
||||
float shininess;
|
||||
GLuint diffuseTexture;
|
||||
// (Optional) If you add a normal texture per submesh.
|
||||
// GLuint normalTexture;
|
||||
GLuint VAO, VBO, EBO;
|
||||
|
||||
SubMesh()
|
||||
: diffuseColor(1.0f,1.0f,1.0f),
|
||||
specularColor(1.0f,1.0f,1.0f),
|
||||
shininess(32.0f),
|
||||
diffuseTexture(0),
|
||||
VAO(0), VBO(0), EBO(0)
|
||||
{}
|
||||
};
|
||||
|
||||
class ModelComponent {
|
||||
public:
|
||||
ModelComponent();
|
||||
~ModelComponent();
|
||||
|
||||
// Material properties.
|
||||
// Base model file path.
|
||||
std::string modelPath;
|
||||
// Submeshes.
|
||||
std::vector<SubMesh> meshes;
|
||||
|
||||
// Global material overrides (if any).
|
||||
glm::vec3 diffuseColor;
|
||||
glm::vec3 specularColor;
|
||||
float shininess;
|
||||
|
||||
// Mesh data.
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<GLuint> indices;
|
||||
|
||||
// OpenGL buffers.
|
||||
GLuint VAO, VBO, EBO;
|
||||
|
||||
// Texture handles.
|
||||
GLuint diffuseTexture;
|
||||
GLuint normalTexture;
|
||||
|
||||
// Set up the mesh by creating VAO, VBO, and EBO.
|
||||
void SetupMesh();
|
||||
|
||||
// Load textures from file.
|
||||
bool LoadDiffuseTexture(const std::string &filepath);
|
||||
bool LoadNormalTexture(const std::string &filepath);
|
||||
|
||||
// Draw the mesh.
|
||||
// Functions.
|
||||
bool LoadModel(const std::string &filepath);
|
||||
void Draw();
|
||||
|
||||
// Texture loading.
|
||||
bool LoadDiffuseTexture(const std::string &filepath, GLuint &textureID);
|
||||
bool LoadNormalTexture(const std::string &filepath);
|
||||
|
||||
// Setup mesh for a submesh.
|
||||
void SetupMesh(SubMesh &mesh);
|
||||
|
||||
// --- YAML Serialization Functions (Globals Only) ---
|
||||
// Save the global ModelComponent state to a YAML node.
|
||||
YAML::Node Save() const {
|
||||
YAML::Node node;
|
||||
node["modelPath"] = modelPath;
|
||||
|
||||
node["globalDiffuseColor"] = YAML::Node();
|
||||
node["globalDiffuseColor"].push_back(diffuseColor.x);
|
||||
node["globalDiffuseColor"].push_back(diffuseColor.y);
|
||||
node["globalDiffuseColor"].push_back(diffuseColor.z);
|
||||
|
||||
node["globalSpecularColor"] = YAML::Node();
|
||||
node["globalSpecularColor"].push_back(specularColor.x);
|
||||
node["globalSpecularColor"].push_back(specularColor.y);
|
||||
node["globalSpecularColor"].push_back(specularColor.z);
|
||||
|
||||
node["globalShininess"] = shininess;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// Load the global ModelComponent state from a YAML node.
|
||||
void Load(const YAML::Node &node) {
|
||||
if (node["modelPath"]) {
|
||||
modelPath = node["modelPath"].as<std::string>();
|
||||
}
|
||||
if (node["globalDiffuseColor"]) {
|
||||
diffuseColor.x = node["globalDiffuseColor"][0].as<float>();
|
||||
diffuseColor.y = node["globalDiffuseColor"][1].as<float>();
|
||||
diffuseColor.z = node["globalDiffuseColor"][2].as<float>();
|
||||
}
|
||||
if (node["globalSpecularColor"]) {
|
||||
specularColor.x = node["globalSpecularColor"][0].as<float>();
|
||||
specularColor.y = node["globalSpecularColor"][1].as<float>();
|
||||
specularColor.z = node["globalSpecularColor"][2].as<float>();
|
||||
}
|
||||
if (node["globalShininess"]) {
|
||||
shininess = node["globalShininess"].as<float>();
|
||||
}
|
||||
// Reload the model (populates meshes based on the modelPath).
|
||||
LoadModel(modelPath);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // MODEL_COMPONENT_H
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
class TransformComponent {
|
||||
public:
|
||||
@ -15,6 +16,46 @@ public:
|
||||
|
||||
// Returns the world transform matrix.
|
||||
glm::mat4 GetMatrix() const;
|
||||
|
||||
// Save this transform to a YAML node.
|
||||
YAML::Node Save() const {
|
||||
YAML::Node node;
|
||||
node["position"] = YAML::Node();
|
||||
node["position"].push_back(position.x);
|
||||
node["position"].push_back(position.y);
|
||||
node["position"].push_back(position.z);
|
||||
|
||||
node["rotation"] = YAML::Node();
|
||||
node["rotation"].push_back(rotation.x);
|
||||
node["rotation"].push_back(rotation.y);
|
||||
node["rotation"].push_back(rotation.z);
|
||||
|
||||
node["scale"] = YAML::Node();
|
||||
node["scale"].push_back(scale.x);
|
||||
node["scale"].push_back(scale.y);
|
||||
node["scale"].push_back(scale.z);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// Load this transform from a YAML node.
|
||||
void Load(const YAML::Node &node) {
|
||||
if (node["position"]) {
|
||||
position.x = node["position"][0].as<float>();
|
||||
position.y = node["position"][1].as<float>();
|
||||
position.z = node["position"][2].as<float>();
|
||||
}
|
||||
if (node["rotation"]) {
|
||||
rotation.x = node["rotation"][0].as<float>();
|
||||
rotation.y = node["rotation"][1].as<float>();
|
||||
rotation.z = node["rotation"][2].as<float>();
|
||||
}
|
||||
if (node["scale"]) {
|
||||
scale.x = node["scale"][0].as<float>();
|
||||
scale.y = node["scale"][1].as<float>();
|
||||
scale.z = node["scale"][2].as<float>();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // TRANSFORM_COMPONENT_H
|
||||
|
@ -185,55 +185,62 @@ bool Engine::SetupScene() {
|
||||
|
||||
// Fragment shader: uses a normal map and material properties.
|
||||
const char* fragmentShaderSrc = R"(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
// Fragment shader:
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoords;
|
||||
in vec3 Tangent;
|
||||
|
||||
uniform vec3 lightPositions[2];
|
||||
uniform vec3 lightColors[2];
|
||||
uniform int numLights;
|
||||
uniform vec3 viewPos;
|
||||
uniform sampler2D diffuseTexture;
|
||||
uniform sampler2D normalMap;
|
||||
uniform bool useNormalMap; // NEW uniform to control normal mapping
|
||||
|
||||
// Material properties.
|
||||
uniform vec3 materialDiffuse;
|
||||
uniform vec3 materialSpecular;
|
||||
uniform float materialShininess;
|
||||
|
||||
void main() {
|
||||
vec3 perturbedNormal = normalize(Normal);
|
||||
if(useNormalMap) {
|
||||
// Sample normal map.
|
||||
vec3 normMap = texture(normalMap, TexCoords).rgb;
|
||||
normMap = normalize(normMap * 2.0 - 1.0);
|
||||
// Flip Z if needed.
|
||||
normMap.z = -normMap.z;
|
||||
// Calculate tangent space basis.
|
||||
vec3 T = normalize(Tangent);
|
||||
vec3 B = normalize(cross(Normal, T));
|
||||
mat3 TBN = mat3(T, B, normalize(Normal));
|
||||
perturbedNormal = normalize(TBN * normMap);
|
||||
}
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoords;
|
||||
in vec3 Tangent;
|
||||
|
||||
uniform vec3 lightPositions[2];
|
||||
uniform vec3 lightColors[2];
|
||||
uniform int numLights;
|
||||
uniform vec3 viewPos;
|
||||
uniform sampler2D diffuseTexture;
|
||||
uniform sampler2D normalMap;
|
||||
|
||||
// Material properties.
|
||||
uniform vec3 materialDiffuse;
|
||||
uniform vec3 materialSpecular;
|
||||
uniform float materialShininess;
|
||||
|
||||
void main() {
|
||||
// Sample normal map.
|
||||
vec3 normMap = texture(normalMap, TexCoords).rgb;
|
||||
normMap = normalize(normMap * 2.0 - 1.0);
|
||||
normMap.z = -normMap.z;
|
||||
vec3 N = normalize(Normal);
|
||||
vec3 T = normalize(Tangent);
|
||||
vec3 B = normalize(cross(N, T));
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
vec3 perturbedNormal = normalize(TBN * normMap);
|
||||
|
||||
vec3 diffuseTex = texture(diffuseTexture, TexCoords).rgb;
|
||||
|
||||
vec3 ambient = 0.1 * materialDiffuse * diffuseTex;
|
||||
vec3 lighting = ambient;
|
||||
for(int i = 0; i < numLights; i++) {
|
||||
vec3 lightDir = normalize(lightPositions[i] - FragPos);
|
||||
float diff = max(dot(perturbedNormal, lightDir), 0.0);
|
||||
vec3 diffuse = diff * materialDiffuse * diffuseTex * lightColors[i];
|
||||
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, perturbedNormal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), materialShininess);
|
||||
vec3 specular = materialSpecular * spec * lightColors[i];
|
||||
|
||||
lighting += diffuse + specular;
|
||||
}
|
||||
FragColor = vec4(lighting, 1.0);
|
||||
}
|
||||
vec3 diffuseTex = texture(diffuseTexture, TexCoords).rgb;
|
||||
|
||||
vec3 ambient = 0.1 * materialDiffuse * diffuseTex;
|
||||
vec3 lighting = ambient;
|
||||
for(int i = 0; i < numLights; i++) {
|
||||
vec3 lightDir = normalize(lightPositions[i] - FragPos);
|
||||
float diff = max(dot(perturbedNormal, lightDir), 0.0);
|
||||
vec3 diffuse = diff * materialDiffuse * diffuseTex * lightColors[i];
|
||||
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, perturbedNormal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), materialShininess);
|
||||
vec3 specular = materialSpecular * spec * lightColors[i];
|
||||
|
||||
lighting += diffuse + specular;
|
||||
}
|
||||
FragColor = vec4(lighting, 1.0);
|
||||
}
|
||||
|
||||
)";
|
||||
|
||||
shaderProgram = CompileShader(vertexShaderSrc, fragmentShaderSrc);
|
||||
@ -278,26 +285,36 @@ ImTextureID Engine::RenderScene(const glm::mat4 &view, const glm::mat4 &projecti
|
||||
}
|
||||
|
||||
// Render each cube entity using its ModelComponent.
|
||||
for (auto e : entities) {
|
||||
if (e->GetType() == EntityType::CUBE && e->modelComponent) {
|
||||
glm::mat4 modelMatrix = e->transform.GetMatrix();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
glUniform3fv(glGetUniformLocation(shaderProgram, "materialDiffuse"), 1, glm::value_ptr(e->modelComponent->diffuseColor));
|
||||
glUniform3fv(glGetUniformLocation(shaderProgram, "materialSpecular"), 1, glm::value_ptr(e->modelComponent->specularColor));
|
||||
glUniform1f(glGetUniformLocation(shaderProgram, "materialShininess"), e->modelComponent->shininess);
|
||||
// Bind the diffuse texture to texture unit 0.
|
||||
for (auto e : entities) {
|
||||
if (e->GetType() == EntityType::CUBE && e->modelComponent) {
|
||||
glm::mat4 modelMatrix = e->transform.GetMatrix();
|
||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
||||
|
||||
// Loop through all submeshes in the model component.
|
||||
for (const auto &mesh : e->modelComponent->meshes) {
|
||||
// Set material properties for the current submesh.
|
||||
glUniform3fv(glGetUniformLocation(shaderProgram, "materialDiffuse"), 1, glm::value_ptr(mesh.diffuseColor));
|
||||
glUniform3fv(glGetUniformLocation(shaderProgram, "materialSpecular"), 1, glm::value_ptr(mesh.specularColor));
|
||||
glUniform1f(glGetUniformLocation(shaderProgram, "materialShininess"), mesh.shininess);
|
||||
|
||||
// Bind the diffuse texture.
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, e->modelComponent->diffuseTexture);
|
||||
glBindTexture(GL_TEXTURE_2D, mesh.diffuseTexture);
|
||||
glUniform1i(glGetUniformLocation(shaderProgram, "diffuseTexture"), 0);
|
||||
// Bind the normal texture to texture unit 1.
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, e->modelComponent->normalTexture);
|
||||
glUniform1i(glGetUniformLocation(shaderProgram, "normalMap"), 1);
|
||||
|
||||
// Draw the model.
|
||||
e->modelComponent->Draw();
|
||||
|
||||
// If you have a normal texture, bind it similarly (adjust as needed).
|
||||
// glActiveTexture(GL_TEXTURE1);
|
||||
// glBindTexture(GL_TEXTURE_2D, mesh.normalTexture);
|
||||
// glUniform1i(glGetUniformLocation(shaderProgram, "normalMap"), 1);
|
||||
|
||||
// Bind the submesh's VAO and draw its elements.
|
||||
glBindVertexArray(mesh.VAO);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mesh.indices.size()), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
return (ImTextureID)(intptr_t)colorTexture;
|
||||
|
6
Makefile
@ -1,12 +1,12 @@
|
||||
# Compiler and flags
|
||||
CXX := g++
|
||||
CXXFLAGS := -std=c++20 -Wall -Wextra -O2 -I/c/msys64/mingw64/include -Ivendor/imgui-docking -Ivendor/stb
|
||||
CXXFLAGS := -std=c++20 -Wall -Wextra -O2 -I/c/msys64/mingw64/include -Ivendor/imgui-docking -Ivendor/stb -Ivendor/tini_obj
|
||||
|
||||
# Use this to link against the correct import lib
|
||||
LDFLAGS := -Llib -lglfw3 -lopengl32 -lglew32 -lglu32
|
||||
LDFLAGS := -Llib -lglfw3 -lopengl32 -lglew32 -lglu32 -lyaml-cpp
|
||||
|
||||
# Source and build directories (including vendor folder)
|
||||
SRC_DIRS := . Editor Engine vendor/imgui-docking Engine/Components Engine/Entity
|
||||
SRC_DIRS := . Editor Engine vendor/imgui-docking Engine/Components Engine/Entity Engine/utils
|
||||
BUILD_DIR := build
|
||||
|
||||
# Find all source files
|
||||
|
BIN
Three-Labs.exe
306
assets/models/sponza.mtl
Normal file
@ -0,0 +1,306 @@
|
||||
# Blender MTL File: 'None'
|
||||
# Material Count: 25
|
||||
|
||||
newmtl Material__25
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/lion.tga
|
||||
map_Disp textures/lion_ddn.tga
|
||||
map_Ka textures/lion.tga
|
||||
|
||||
newmtl Material__298
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/background.tga
|
||||
map_Disp textures/background_ddn.tga
|
||||
map_Ka textures/background.tga
|
||||
|
||||
newmtl Material__47
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
|
||||
|
||||
newmtl Material__57
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Kd textures/vase_plant.tga
|
||||
map_d textures/vase_plant_mask.tga
|
||||
map_Ka textures/vase_plant.tga
|
||||
|
||||
newmtl arch
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_arch_diff.tga
|
||||
map_Ka textures/sponza_arch_diff.tga
|
||||
map_Disp textures/sponza_arch_ddn.tga
|
||||
|
||||
newmtl bricks
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/spnza_bricks_a_diff.tga
|
||||
map_Disp textures/spnza_bricks_a_ddn.tga
|
||||
map_Ka textures/spnza_bricks_a_diff.tga
|
||||
|
||||
newmtl ceiling
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_ceiling_a_diff.tga
|
||||
map_Ka textures/sponza_ceiling_a_diff.tga
|
||||
map_Disp textures/sponza_ceiling_a_ddn.tga
|
||||
|
||||
newmtl chain
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Kd textures/chain_texture.tga
|
||||
map_d textures/chain_texture_mask.tga
|
||||
map_Disp textures/chain_texture_ddn.tga
|
||||
map_Ka textures/chain_texture.tga
|
||||
|
||||
newmtl column_a
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_column_a_diff.tga
|
||||
map_Disp textures/sponza_column_a_ddn.tga
|
||||
map_Ka textures/sponza_column_a_diff.tga
|
||||
|
||||
newmtl column_b
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_column_b_diff.tga
|
||||
map_Disp textures/sponza_column_b_ddn.tga
|
||||
map_Ka textures/sponza_column_b_diff.tga
|
||||
|
||||
newmtl column_c
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_column_c_diff.tga
|
||||
map_Disp textures/sponza_column_c_ddn.tga
|
||||
map_Ka textures/sponza_column_c_diff.tga
|
||||
|
||||
newmtl details
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_details_diff.tga
|
||||
map_Ka textures/sponza_details_diff.tga
|
||||
map_Disp textures/sponza_details_ddn.tga
|
||||
|
||||
newmtl fabric_a
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_fabric_diff.tga
|
||||
map_Ka textures/sponza_fabric_diff.tga
|
||||
map_Disp textures/sponza_fabric_ddn.tga
|
||||
|
||||
newmtl fabric_c
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_curtain_diff.tga
|
||||
map_Ka textures/sponza_curtain_diff.tga
|
||||
map_Disp textures/sponza_curtain_ddn.tga
|
||||
|
||||
|
||||
newmtl fabric_d
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_fabric_blue_diff.tga
|
||||
map_Ka textures/sponza_fabric_blue_diff.tga
|
||||
map_Disp textures/sponza_fabric_ddn.tga
|
||||
|
||||
|
||||
newmtl fabric_e
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_fabric_green_diff.tga
|
||||
map_Ka textures/sponza_fabric_green_diff.tga
|
||||
map_Disp textures/sponza_fabric_ddn.tga
|
||||
|
||||
|
||||
newmtl fabric_f
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_curtain_green_diff.tga
|
||||
map_Ka textures/sponza_curtain_green_diff.tga
|
||||
map_Disp textures/sponza_curtain_ddn.tga
|
||||
|
||||
newmtl fabric_g
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_curtain_blue_diff.tga
|
||||
map_Ka textures/sponza_curtain_blue_diff.tga
|
||||
map_Disp textures/sponza_curtain_ddn.tga
|
||||
|
||||
|
||||
newmtl flagpole
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_flagpole_diff.tga
|
||||
map_Ka textures/sponza_flagpole_diff.tga
|
||||
map_Disp textures/sponza_flagpole_ddn.tga
|
||||
|
||||
newmtl floor
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_floor_a_diff.tga
|
||||
map_Ka textures/sponza_floor_a_diff.tga
|
||||
map_Disp textures/sponza_floor_a_ddn.tga
|
||||
|
||||
newmtl leaf
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 1.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_thorn_diff.tga
|
||||
map_d textures/sponza_thorn_mask.tga
|
||||
map_Disp textures/sponza_thorn_ddn.tga
|
||||
map_Ka textures/sponza_thorn_diff.tga
|
||||
|
||||
newmtl roof
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/sponza_roof_diff.tga
|
||||
map_Ka textures/sponza_roof_diff.tga
|
||||
map_Disp textures/sponza_roof_ddn.tga
|
||||
|
||||
newmtl vase
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/vase_dif.tga
|
||||
map_Ka textures/vase_dif.tga
|
||||
map_Disp textures/vase_ddn.tga
|
||||
|
||||
newmtl vase_hanging
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/vase_hanging.tga
|
||||
map_Ka textures/vase_hanging.tga
|
||||
map_Disp textures/vase_hanging_ddn.tga
|
||||
|
||||
newmtl vase_round
|
||||
Ns 7.843137
|
||||
Ka 0.000000 0.000000 0.000000
|
||||
Kd 0.470400 0.470400 0.470400
|
||||
Ks 0.000000 0.000000 0.000000
|
||||
Ni 1.000000
|
||||
d 0.000000
|
||||
illum 2
|
||||
map_Kd textures/vase_round.tga
|
||||
map_Disp textures/vase_round_ddn.tga
|
||||
map_Ka textures/vase_round.tga
|
BIN
assets/models/textures/Thumbs.db
Normal file
BIN
assets/models/textures/background.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/background_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/chain_texture.tga
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/models/textures/chain_texture_ddn.tga
Normal file
After Width: | Height: | Size: 768 KiB |
BIN
assets/models/textures/lion.tga
Normal file
After Width: | Height: | Size: 4.0 MiB |
BIN
assets/models/textures/lion2_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/lion_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/spnza_bricks_a_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/spnza_bricks_a_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_arch_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_arch_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_ceiling_a_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_ceiling_a_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_column_a_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_column_a_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_column_b_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_column_b_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_column_c_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_column_c_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_curtain_blue_diff.tga
Normal file
After Width: | Height: | Size: 12 MiB |
BIN
assets/models/textures/sponza_curtain_ddn.tga
Normal file
After Width: | Height: | Size: 12 MiB |
BIN
assets/models/textures/sponza_curtain_diff.tga
Normal file
After Width: | Height: | Size: 12 MiB |
BIN
assets/models/textures/sponza_curtain_green_diff.tga
Normal file
After Width: | Height: | Size: 12 MiB |
BIN
assets/models/textures/sponza_details_ddn.tga
Normal file
After Width: | Height: | Size: 4.0 MiB |
BIN
assets/models/textures/sponza_details_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_fabric_blue_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_fabric_ddn.tga
Normal file
After Width: | Height: | Size: 4.0 MiB |
BIN
assets/models/textures/sponza_fabric_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_fabric_green_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_flagpole_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_flagpole_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_floor_a_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_floor_a_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_roof_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_roof_diff.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/sponza_thorn_ddn.tga
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
assets/models/textures/sponza_thorn_diff.tga
Normal file
After Width: | Height: | Size: 1.0 MiB |
BIN
assets/models/textures/vase_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/vase_dif.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/vase_hanging.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/vase_hanging_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/vase_plant.tga
Normal file
After Width: | Height: | Size: 4.0 MiB |
BIN
assets/models/textures/vase_round.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
BIN
assets/models/textures/vase_round_ddn.tga
Normal file
After Width: | Height: | Size: 3.0 MiB |
91
default.yaml
Normal file
@ -0,0 +1,91 @@
|
||||
entities:
|
||||
- type: cube
|
||||
transform:
|
||||
position:
|
||||
- -2
|
||||
- 0
|
||||
- 0
|
||||
rotation:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
scale:
|
||||
- 1
|
||||
- 1
|
||||
- 1
|
||||
model:
|
||||
modelPath: ./assets/models/sponza.obj
|
||||
globalDiffuseColor:
|
||||
- 0.800000012
|
||||
- 0.200000003
|
||||
- 0.200000003
|
||||
globalSpecularColor:
|
||||
- 1
|
||||
- 1
|
||||
- 1
|
||||
globalShininess: 32
|
||||
- type: cube
|
||||
transform:
|
||||
position:
|
||||
- 2
|
||||
- 0
|
||||
- 0
|
||||
rotation:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
scale:
|
||||
- 0.00999999978
|
||||
- 0.00999999978
|
||||
- 0.00999999978
|
||||
model:
|
||||
modelPath: ./assets/models/sponza.obj
|
||||
globalDiffuseColor:
|
||||
- 0
|
||||
- 1
|
||||
- 0
|
||||
globalSpecularColor:
|
||||
- 1
|
||||
- 1
|
||||
- 1
|
||||
globalShininess: 16
|
||||
- type: light
|
||||
transform:
|
||||
position:
|
||||
- 0
|
||||
- 10
|
||||
- 0
|
||||
rotation:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
scale:
|
||||
- 1
|
||||
- 1
|
||||
- 1
|
||||
light:
|
||||
color:
|
||||
- 1
|
||||
- 1
|
||||
- 1
|
||||
intensity: 1.5
|
||||
- type: light
|
||||
transform:
|
||||
position:
|
||||
- 0
|
||||
- -10
|
||||
- 0
|
||||
rotation:
|
||||
- 0
|
||||
- 0
|
||||
- 0
|
||||
scale:
|
||||
- 1
|
||||
- 1
|
||||
- 1
|
||||
light:
|
||||
color:
|
||||
- 0.200000003
|
||||
- 0.200000003
|
||||
- 1
|
||||
intensity: 1
|
16
imgui.ini
@ -31,14 +31,22 @@ Collapsed=0
|
||||
DockId=0x00000004,0
|
||||
|
||||
[Window][Entity List]
|
||||
Pos=0,0
|
||||
Size=245,800
|
||||
Pos=0,78
|
||||
Size=245,722
|
||||
Collapsed=0
|
||||
DockId=0x00000005,0
|
||||
DockId=0x00000008,0
|
||||
|
||||
[Window][Scene File]
|
||||
Pos=0,0
|
||||
Size=245,76
|
||||
Collapsed=0
|
||||
DockId=0x00000007,0
|
||||
|
||||
[Docking][Data]
|
||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,0 Size=1280,800 Split=X Selected=0xB6999AB4
|
||||
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=245,800 Selected=0x5A1EAB5B
|
||||
DockNode ID=0x00000005 Parent=0x08BD597D SizeRef=245,800 Split=Y Selected=0x5A1EAB5B
|
||||
DockNode ID=0x00000007 Parent=0x00000005 SizeRef=245,76 Selected=0xE1A4FD08
|
||||
DockNode ID=0x00000008 Parent=0x00000005 SizeRef=245,722 Selected=0x5A1EAB5B
|
||||
DockNode ID=0x00000006 Parent=0x08BD597D SizeRef=1033,800 Split=X
|
||||
DockNode ID=0x00000003 Parent=0x00000006 SizeRef=772,800 Split=X
|
||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=272,800 Selected=0x5098C5B2
|
||||
|