Added a simple scene system
This commit is contained in:
parent
557f6b2386
commit
073288fc63
@ -12,6 +12,8 @@
|
|||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include "stb_image.h"
|
#include "stb_image.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
@ -46,7 +48,6 @@ bool LoadIconTexture(const char* filepath, GLuint &texOut, ImTextureID &imTexOut
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Editor camera.
|
// Editor camera.
|
||||||
struct EditorCamera {
|
struct EditorCamera {
|
||||||
glm::vec3 position = glm::vec3(0.0f, 0.0f, 8.0f);
|
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);
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
ImGui_ImplGlfw_NewFrame();
|
ImGui_ImplGlfw_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
@ -213,6 +212,59 @@ int main() {
|
|||||||
}
|
}
|
||||||
ImGui::End();
|
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.
|
// Bottom Panel: Rendered Output.
|
||||||
ImGui::Begin("Rendered Output");
|
ImGui::Begin("Rendered Output");
|
||||||
ImVec2 viewportSize = ImGui::GetContentRegionAvail();
|
ImVec2 viewportSize = ImGui::GetContentRegionAvail();
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Component.h"
|
#include "Component.h"
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
// A simple Camera component that inherits from Component.
|
// A simple Camera component that inherits from Component.
|
||||||
class Camera : public Component {
|
class Camera : public Component {
|
||||||
@ -32,6 +33,46 @@ public:
|
|||||||
float GetYaw() const;
|
float GetYaw() const;
|
||||||
float GetPitch() 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:
|
private:
|
||||||
glm::vec3 position;
|
glm::vec3 position;
|
||||||
float yaw;
|
float yaw;
|
||||||
|
@ -1,12 +1,19 @@
|
|||||||
#ifndef COMPONENT_H
|
#ifndef COMPONENT_H
|
||||||
#define COMPONENT_H
|
#define COMPONENT_H
|
||||||
|
|
||||||
// Base Component class for all components.
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
class Component {
|
class Component {
|
||||||
public:
|
public:
|
||||||
virtual ~Component() {}
|
virtual ~Component() {}
|
||||||
|
|
||||||
// Update the component each frame.
|
// Update the component each frame.
|
||||||
virtual void Update(float deltaTime) = 0;
|
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
|
#endif // COMPONENT_H
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define LIGHT_COMPONENT_H
|
#define LIGHT_COMPONENT_H
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
class LightComponent {
|
class LightComponent {
|
||||||
public:
|
public:
|
||||||
@ -11,6 +12,28 @@ public:
|
|||||||
// Light properties.
|
// Light properties.
|
||||||
glm::vec3 color;
|
glm::vec3 color;
|
||||||
float intensity;
|
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
|
#endif // LIGHT_COMPONENT_H
|
||||||
|
@ -86,6 +86,8 @@ bool ModelComponent::LoadNormalTexture(const std::string &filepath) {
|
|||||||
|
|
||||||
// Loads a model using tiny_obj_loader and groups faces by material.
|
// Loads a model using tiny_obj_loader and groups faces by material.
|
||||||
bool ModelComponent::LoadModel(const std::string &filepath) {
|
bool ModelComponent::LoadModel(const std::string &filepath) {
|
||||||
|
|
||||||
|
std::cout << "[Info] Loading Model \'" << filepath << "\' " << std::endl;
|
||||||
modelPath = filepath;
|
modelPath = filepath;
|
||||||
tinyobj::attrib_t attrib;
|
tinyobj::attrib_t attrib;
|
||||||
std::vector<tinyobj::shape_t> shapes;
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
@ -121,7 +123,6 @@ bool ModelComponent::LoadModel(const std::string &filepath) {
|
|||||||
size_t index_offset = 0;
|
size_t index_offset = 0;
|
||||||
// Iterate over each face.
|
// Iterate over each face.
|
||||||
for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
for (size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
||||||
std::cout << "[Info] AssetManager: Loading Mesh: "<< i << std::endl;
|
|
||||||
int fv = shapes[s].mesh.num_face_vertices[f];
|
int fv = shapes[s].mesh.num_face_vertices[f];
|
||||||
// Get material ID for this face.
|
// Get material ID for this face.
|
||||||
int matID = -1;
|
int matID = -1;
|
||||||
@ -192,6 +193,7 @@ bool ModelComponent::LoadModel(const std::string &filepath) {
|
|||||||
meshes.push_back(subMesh);
|
meshes.push_back(subMesh);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << "[Done] Loaded Model \'" << filepath << "\' " << std::endl;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#ifndef MODEL_COMPONENT_H
|
#ifndef MODEL_COMPONENT_H
|
||||||
#define MODEL_COMPONENT_H
|
#define MODEL_COMPONENT_H
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
// Structure representing a single vertex.
|
// Structure representing a single vertex.
|
||||||
struct Vertex {
|
struct Vertex {
|
||||||
@ -22,6 +23,8 @@ struct SubMesh {
|
|||||||
glm::vec3 specularColor;
|
glm::vec3 specularColor;
|
||||||
float shininess;
|
float shininess;
|
||||||
GLuint diffuseTexture;
|
GLuint diffuseTexture;
|
||||||
|
// (Optional) If you add a normal texture per submesh.
|
||||||
|
// GLuint normalTexture;
|
||||||
GLuint VAO, VBO, EBO;
|
GLuint VAO, VBO, EBO;
|
||||||
|
|
||||||
SubMesh()
|
SubMesh()
|
||||||
@ -38,11 +41,16 @@ public:
|
|||||||
ModelComponent();
|
ModelComponent();
|
||||||
~ModelComponent();
|
~ModelComponent();
|
||||||
|
|
||||||
// Base model path.
|
// Base model file path.
|
||||||
std::string modelPath;
|
std::string modelPath;
|
||||||
// Submeshes
|
// Submeshes.
|
||||||
std::vector<SubMesh> meshes;
|
std::vector<SubMesh> meshes;
|
||||||
|
|
||||||
|
// Global material overrides (if any).
|
||||||
|
glm::vec3 diffuseColor;
|
||||||
|
glm::vec3 specularColor;
|
||||||
|
float shininess;
|
||||||
|
|
||||||
// Functions.
|
// Functions.
|
||||||
bool LoadModel(const std::string &filepath);
|
bool LoadModel(const std::string &filepath);
|
||||||
void Draw();
|
void Draw();
|
||||||
@ -53,11 +61,49 @@ public:
|
|||||||
|
|
||||||
// Setup mesh for a submesh.
|
// Setup mesh for a submesh.
|
||||||
void SetupMesh(SubMesh &mesh);
|
void SetupMesh(SubMesh &mesh);
|
||||||
|
|
||||||
// (Optional) Global material properties if needed.
|
// --- YAML Serialization Functions (Globals Only) ---
|
||||||
glm::vec3 diffuseColor;
|
// Save the global ModelComponent state to a YAML node.
|
||||||
glm::vec3 specularColor;
|
YAML::Node Save() const {
|
||||||
float shininess;
|
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
|
#endif // MODEL_COMPONENT_H
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
class TransformComponent {
|
class TransformComponent {
|
||||||
public:
|
public:
|
||||||
@ -15,6 +16,46 @@ public:
|
|||||||
|
|
||||||
// Returns the world transform matrix.
|
// Returns the world transform matrix.
|
||||||
glm::mat4 GetMatrix() const;
|
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
|
#endif // TRANSFORM_COMPONENT_H
|
||||||
|
@ -185,55 +185,62 @@ bool Engine::SetupScene() {
|
|||||||
|
|
||||||
// Fragment shader: uses a normal map and material properties.
|
// Fragment shader: uses a normal map and material properties.
|
||||||
const char* fragmentShaderSrc = R"(
|
const char* fragmentShaderSrc = R"(
|
||||||
#version 330 core
|
// Fragment shader:
|
||||||
out vec4 FragColor;
|
#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;
|
vec3 diffuseTex = texture(diffuseTexture, TexCoords).rgb;
|
||||||
in vec3 Normal;
|
|
||||||
in vec2 TexCoords;
|
vec3 ambient = 0.1 * materialDiffuse * diffuseTex;
|
||||||
in vec3 Tangent;
|
vec3 lighting = ambient;
|
||||||
|
for(int i = 0; i < numLights; i++) {
|
||||||
uniform vec3 lightPositions[2];
|
vec3 lightDir = normalize(lightPositions[i] - FragPos);
|
||||||
uniform vec3 lightColors[2];
|
float diff = max(dot(perturbedNormal, lightDir), 0.0);
|
||||||
uniform int numLights;
|
vec3 diffuse = diff * materialDiffuse * diffuseTex * lightColors[i];
|
||||||
uniform vec3 viewPos;
|
|
||||||
uniform sampler2D diffuseTexture;
|
vec3 viewDir = normalize(viewPos - FragPos);
|
||||||
uniform sampler2D normalMap;
|
vec3 reflectDir = reflect(-lightDir, perturbedNormal);
|
||||||
|
float spec = pow(max(dot(viewDir, reflectDir), 0.0), materialShininess);
|
||||||
// Material properties.
|
vec3 specular = materialSpecular * spec * lightColors[i];
|
||||||
uniform vec3 materialDiffuse;
|
|
||||||
uniform vec3 materialSpecular;
|
lighting += diffuse + specular;
|
||||||
uniform float materialShininess;
|
}
|
||||||
|
FragColor = vec4(lighting, 1.0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
)";
|
)";
|
||||||
|
|
||||||
shaderProgram = CompileShader(vertexShaderSrc, fragmentShaderSrc);
|
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.
|
// Render each cube entity using its ModelComponent.
|
||||||
for (auto e : entities) {
|
for (auto e : entities) {
|
||||||
if (e->GetType() == EntityType::CUBE && e->modelComponent) {
|
if (e->GetType() == EntityType::CUBE && e->modelComponent) {
|
||||||
glm::mat4 modelMatrix = e->transform.GetMatrix();
|
glm::mat4 modelMatrix = e->transform.GetMatrix();
|
||||||
glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "model"), 1, GL_FALSE, glm::value_ptr(modelMatrix));
|
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));
|
// Loop through all submeshes in the model component.
|
||||||
glUniform1f(glGetUniformLocation(shaderProgram, "materialShininess"), e->modelComponent->shininess);
|
for (const auto &mesh : e->modelComponent->meshes) {
|
||||||
// Bind the diffuse texture to texture unit 0.
|
// 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);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, e->modelComponent->diffuseTexture);
|
glBindTexture(GL_TEXTURE_2D, mesh.diffuseTexture);
|
||||||
glUniform1i(glGetUniformLocation(shaderProgram, "diffuseTexture"), 0);
|
glUniform1i(glGetUniformLocation(shaderProgram, "diffuseTexture"), 0);
|
||||||
// Bind the normal texture to texture unit 1.
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
// If you have a normal texture, bind it similarly (adjust as needed).
|
||||||
glBindTexture(GL_TEXTURE_2D, e->modelComponent->normalTexture);
|
// glActiveTexture(GL_TEXTURE1);
|
||||||
glUniform1i(glGetUniformLocation(shaderProgram, "normalMap"), 1);
|
// glBindTexture(GL_TEXTURE_2D, mesh.normalTexture);
|
||||||
|
// glUniform1i(glGetUniformLocation(shaderProgram, "normalMap"), 1);
|
||||||
// Draw the model.
|
|
||||||
e->modelComponent->Draw();
|
// 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);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
return (ImTextureID)(intptr_t)colorTexture;
|
return (ImTextureID)(intptr_t)colorTexture;
|
||||||
|
2
Makefile
2
Makefile
@ -3,7 +3,7 @@ CXX := g++
|
|||||||
CXXFLAGS := -std=c++20 -Wall -Wextra -O2 -I/c/msys64/mingw64/include -Ivendor/imgui-docking -Ivendor/stb -Ivendor/tini_obj
|
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
|
# 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)
|
# Source and build directories (including vendor folder)
|
||||||
SRC_DIRS := . Editor Engine vendor/imgui-docking Engine/Components Engine/Entity Engine/utils
|
SRC_DIRS := . Editor Engine vendor/imgui-docking Engine/Components Engine/Entity Engine/utils
|
||||||
|
BIN
Three-Labs.exe
BIN
Three-Labs.exe
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
91
default.yaml
Normal file
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
16
imgui.ini
@ -31,14 +31,22 @@ Collapsed=0
|
|||||||
DockId=0x00000004,0
|
DockId=0x00000004,0
|
||||||
|
|
||||||
[Window][Entity List]
|
[Window][Entity List]
|
||||||
Pos=0,0
|
Pos=0,78
|
||||||
Size=245,800
|
Size=245,722
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000005,0
|
DockId=0x00000008,0
|
||||||
|
|
||||||
|
[Window][Scene File]
|
||||||
|
Pos=0,0
|
||||||
|
Size=245,76
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000007,0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x08BD597D Window=0x1BBC0F80 Pos=0,0 Size=1280,800 Split=X Selected=0xB6999AB4
|
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=0x00000006 Parent=0x08BD597D SizeRef=1033,800 Split=X
|
||||||
DockNode ID=0x00000003 Parent=0x00000006 SizeRef=772,800 Split=X
|
DockNode ID=0x00000003 Parent=0x00000006 SizeRef=772,800 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=272,800 Selected=0x5098C5B2
|
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=272,800 Selected=0x5098C5B2
|
||||||
|
Loading…
Reference in New Issue
Block a user