its broke, idk. fix latter
This commit is contained in:
parent
55b521d9bc
commit
fdac328a3f
45
shaders/basic.frag
Normal file
45
shaders/basic.frag
Normal file
@ -0,0 +1,45 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoords;
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
uniform Light light;
|
||||
uniform Material material;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Ambient
|
||||
vec3 ambient = light.ambient * texture(material.diffuse, TexCoords).rgb;
|
||||
|
||||
// Diffuse
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(light.position - FragPos);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = light.diffuse * diff * texture(material.diffuse, TexCoords).rgb;
|
||||
|
||||
// Specular
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
vec3 specular = light.specular * spec * texture(material.specular, TexCoords).rgb;
|
||||
|
||||
vec3 result = ambient + diffuse + specular;
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
21
shaders/basic.vert
Normal file
21
shaders/basic.vert
Normal file
@ -0,0 +1,21 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec2 aTexCoords;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
out vec2 TexCoords;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragPos = vec3(model * vec4(aPos, 1.0));
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
TexCoords = aTexCoords;
|
||||
|
||||
gl_Position = projection * view * vec4(FragPos, 1.0);
|
||||
}
|
5
src/CameraComponent.cpp
Normal file
5
src/CameraComponent.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
// src/CameraComponent.cpp
|
||||
#include "CameraComponent.h"
|
||||
|
||||
// All methods are defined inline in the header for simplicity.
|
||||
// You can move them to the cpp file if desired.
|
108
src/CameraComponent.h
Normal file
108
src/CameraComponent.h
Normal file
@ -0,0 +1,108 @@
|
||||
// src/CameraComponent.h
|
||||
#pragma once
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
struct CameraComponent {
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Front;
|
||||
glm::vec3 Up;
|
||||
glm::vec3 Right;
|
||||
glm::vec3 WorldUp;
|
||||
|
||||
// Euler Angles
|
||||
float Yaw;
|
||||
float Pitch;
|
||||
|
||||
// Camera options
|
||||
float MovementSpeed;
|
||||
float MouseSensitivity;
|
||||
float Zoom;
|
||||
|
||||
CameraComponent(
|
||||
glm::vec3 position = glm::vec3(0.0f, 0.0f, 3.0f),
|
||||
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f),
|
||||
float yaw = -90.0f,
|
||||
float pitch = 0.0f
|
||||
) : Front(glm::vec3(0.0f, 0.0f, -1.0f)),
|
||||
MovementSpeed(2.5f),
|
||||
MouseSensitivity(0.1f),
|
||||
Zoom(45.0f)
|
||||
{
|
||||
Position = position;
|
||||
WorldUp = up;
|
||||
Yaw = yaw;
|
||||
Pitch = pitch;
|
||||
// Calculate the initial Front, Right, and Up vectors
|
||||
glm::vec3 front;
|
||||
front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||
front.y = sin(glm::radians(Pitch));
|
||||
front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||
Front = glm::normalize(front);
|
||||
Right = glm::normalize(glm::cross(Front, WorldUp));
|
||||
Up = glm::normalize(glm::cross(Right, Front));
|
||||
}
|
||||
|
||||
// Returns the view matrix calculated using Euler Angles and the LookAt Matrix
|
||||
glm::mat4 GetViewMatrix()
|
||||
{
|
||||
return glm::lookAt(Position, Position + Front, Up);
|
||||
}
|
||||
|
||||
// Processes input received from any keyboard-like input system.
|
||||
void ProcessKeyboard(int direction, float deltaTime)
|
||||
{
|
||||
float velocity = MovementSpeed * deltaTime;
|
||||
if (direction == 0) // Forward
|
||||
Position += Front * velocity;
|
||||
if (direction == 1) // Backward
|
||||
Position -= Front * velocity;
|
||||
if (direction == 2) // Left
|
||||
Position -= Right * velocity;
|
||||
if (direction == 3) // Right
|
||||
Position += Right * velocity;
|
||||
if (direction == 4) // Up
|
||||
Position += Up * velocity;
|
||||
if (direction == 5) // Down
|
||||
Position -= Up * velocity;
|
||||
}
|
||||
|
||||
// Processes input received from a mouse input system.
|
||||
void ProcessMouseMovement(float xoffset, float yoffset, bool constrainPitch = true)
|
||||
{
|
||||
xoffset *= MouseSensitivity;
|
||||
yoffset *= MouseSensitivity;
|
||||
|
||||
Yaw += xoffset;
|
||||
Pitch += yoffset;
|
||||
|
||||
// Make sure that when pitch is out of bounds, screen doesn't get flipped
|
||||
if(constrainPitch)
|
||||
{
|
||||
if(Pitch > 89.0f)
|
||||
Pitch = 89.0f;
|
||||
if(Pitch < -89.0f)
|
||||
Pitch = -89.0f;
|
||||
}
|
||||
|
||||
// Update Front, Right and Up Vectors using the updated Euler angles
|
||||
glm::vec3 front;
|
||||
front.x = cos(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||
front.y = sin(glm::radians(Pitch));
|
||||
front.z = sin(glm::radians(Yaw)) * cos(glm::radians(Pitch));
|
||||
Front = glm::normalize(front);
|
||||
Right = glm::normalize(glm::cross(Front, WorldUp));
|
||||
Up = glm::normalize(glm::cross(Right, Front));
|
||||
}
|
||||
|
||||
// Processes input received from a mouse scroll-wheel event.
|
||||
void ProcessMouseScroll(float yoffset)
|
||||
{
|
||||
Zoom -= yoffset;
|
||||
if(Zoom < 1.0f)
|
||||
Zoom = 1.0f;
|
||||
if(Zoom > 45.0f)
|
||||
Zoom = 45.0f;
|
||||
}
|
||||
};
|
40
src/CameraSystem.h
Normal file
40
src/CameraSystem.h
Normal file
@ -0,0 +1,40 @@
|
||||
// src/CameraSystem.h
|
||||
#pragma once
|
||||
|
||||
#include "ECS.h"
|
||||
#include "CameraComponent.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
class CameraSystem {
|
||||
public:
|
||||
CameraSystem(GLFWwindow* window, float deltaTime)
|
||||
: window(window), deltaTime(deltaTime) {}
|
||||
|
||||
void ProcessInput(EntityManager& em, ComponentManager& cm) {
|
||||
// Iterate through entities with CameraComponent
|
||||
const auto& entities = em.GetActiveEntities();
|
||||
for(auto entity : entities) {
|
||||
if(cm.HasComponent<CameraComponent>(entity)) {
|
||||
auto& camera = cm.GetComponent<CameraComponent>(entity);
|
||||
// Implement camera movement based on input
|
||||
if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
camera.ProcessKeyboard(0, deltaTime); // Forward
|
||||
if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
camera.ProcessKeyboard(1, deltaTime); // Backward
|
||||
if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
camera.ProcessKeyboard(2, deltaTime); // Left
|
||||
if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
camera.ProcessKeyboard(3, deltaTime); // Right
|
||||
if(glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
|
||||
camera.ProcessKeyboard(4, deltaTime); // Up
|
||||
if(glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
|
||||
camera.ProcessKeyboard(5, deltaTime); // Down
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
GLFWwindow* window;
|
||||
float deltaTime;
|
||||
};
|
4
src/MeshComponent.cpp
Normal file
4
src/MeshComponent.cpp
Normal file
@ -0,0 +1,4 @@
|
||||
// src/MeshComponent.cpp
|
||||
#include "MeshComponent.h"
|
||||
|
||||
// You can add functions related to MeshComponent here if needed
|
22
src/MeshComponent.h
Normal file
22
src/MeshComponent.h
Normal file
@ -0,0 +1,22 @@
|
||||
// src/MeshComponent.h
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <GL/glew.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
struct Vertex {
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Normal;
|
||||
glm::vec2 TexCoords;
|
||||
};
|
||||
|
||||
struct MeshComponent {
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
GLuint VAO, VBO, EBO;
|
||||
|
||||
MeshComponent() : VAO(0), VBO(0), EBO(0) {}
|
||||
};
|
57
src/Meshes.h
Normal file
57
src/Meshes.h
Normal file
@ -0,0 +1,57 @@
|
||||
// src/Meshes.h
|
||||
#pragma once
|
||||
|
||||
#include "MeshComponent.h"
|
||||
|
||||
MeshComponent CreateCubeMesh() {
|
||||
MeshComponent mesh;
|
||||
|
||||
// Define cube vertices
|
||||
Vertex v1 = { glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(0.0f, 0.0f) };
|
||||
Vertex v2 = { glm::vec3( 0.5f, -0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(1.0f, 0.0f) };
|
||||
Vertex v3 = { glm::vec3( 0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(1.0f, 1.0f) };
|
||||
Vertex v4 = { glm::vec3(-0.5f, 0.5f, -0.5f), glm::vec3(0.0f, 0.0f, -1.0f), glm::vec2(0.0f, 1.0f) };
|
||||
// ... define other vertices for the cube
|
||||
|
||||
// For brevity, only defining front face. Define all 6 faces similarly.
|
||||
|
||||
// Front face
|
||||
mesh.vertices = {
|
||||
v1, v2, v3, v4,
|
||||
// Define other vertices
|
||||
};
|
||||
|
||||
// Define indices
|
||||
mesh.indices = {
|
||||
0, 1, 2,
|
||||
2, 3, 0,
|
||||
// Define other indices for other faces
|
||||
};
|
||||
|
||||
// Generate buffers
|
||||
glGenVertexArrays(1, &mesh.VAO);
|
||||
glGenBuffers(1, &mesh.VBO);
|
||||
glGenBuffers(1, &mesh.EBO);
|
||||
|
||||
glBindVertexArray(mesh.VAO);
|
||||
|
||||
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, mesh.EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(unsigned int), &mesh.indices[0], GL_STATIC_DRAW);
|
||||
|
||||
// Position attribute
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0);
|
||||
glEnableVertexAttribArray(0);
|
||||
// Normal attribute
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal));
|
||||
glEnableVertexAttribArray(1);
|
||||
// Texture coords attribute
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords));
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
return mesh;
|
||||
}
|
120
src/ShaderComponent.cpp
Normal file
120
src/ShaderComponent.cpp
Normal file
@ -0,0 +1,120 @@
|
||||
// src/ShaderComponent.cpp
|
||||
#include "ShaderComponent.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
Shader::Shader(const char* vertexPath, const char* fragmentPath)
|
||||
{
|
||||
// 1. Retrieve the vertex/fragment source code from filePath
|
||||
std::string vertexCode;
|
||||
std::string fragmentCode;
|
||||
std::ifstream vShaderFile;
|
||||
std::ifstream fShaderFile;
|
||||
|
||||
// Ensure ifstream objects can throw exceptions:
|
||||
vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||
fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||
try
|
||||
{
|
||||
// Open files
|
||||
vShaderFile.open(vertexPath);
|
||||
fShaderFile.open(fragmentPath);
|
||||
std::stringstream vShaderStream, fShaderStream;
|
||||
|
||||
// Read file's buffer contents into streams
|
||||
vShaderStream << vShaderFile.rdbuf();
|
||||
fShaderStream << fShaderFile.rdbuf();
|
||||
|
||||
// Close file handlers
|
||||
vShaderFile.close();
|
||||
fShaderFile.close();
|
||||
|
||||
// Convert stream into string
|
||||
vertexCode = vShaderStream.str();
|
||||
fragmentCode = fShaderStream.str();
|
||||
}
|
||||
catch(std::ifstream::failure& e)
|
||||
{
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ");
|
||||
}
|
||||
const char* vShaderCode = vertexCode.c_str();
|
||||
const char * fShaderCode = fragmentCode.c_str();
|
||||
|
||||
// 2. Compile shaders
|
||||
GLuint vertex, fragment;
|
||||
int success;
|
||||
char infoLog[512];
|
||||
|
||||
// Vertex Shader
|
||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||
glCompileShader(vertex);
|
||||
// Print compile errors if any
|
||||
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
|
||||
if(!success)
|
||||
{
|
||||
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, std::string("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n") + infoLog);
|
||||
};
|
||||
|
||||
// Fragment Shader
|
||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||
glCompileShader(fragment);
|
||||
// Print compile errors if any
|
||||
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
|
||||
if(!success)
|
||||
{
|
||||
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, std::string("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n") + infoLog);
|
||||
};
|
||||
|
||||
// Shader Program
|
||||
ID = glCreateProgram();
|
||||
glAttachShader(ID, vertex);
|
||||
glAttachShader(ID, fragment);
|
||||
glLinkProgram(ID);
|
||||
// Print linking errors if any
|
||||
glGetProgramiv(ID, GL_LINK_STATUS, &success);
|
||||
if(!success) {
|
||||
glGetProgramInfoLog(ID, 512, NULL, infoLog);
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, std::string("ERROR::SHADER::PROGRAM::LINKING_FAILED\n") + infoLog);
|
||||
}
|
||||
|
||||
// Delete the shaders as they're linked into our program now and no longer necessary
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
}
|
||||
|
||||
void Shader::Use()
|
||||
{
|
||||
glUseProgram(ID);
|
||||
}
|
||||
|
||||
void Shader::SetBool(const std::string &name, bool value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
||||
}
|
||||
|
||||
void Shader::SetInt(const std::string &name, int value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
|
||||
void Shader::SetFloat(const std::string &name, float value) const
|
||||
{
|
||||
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
|
||||
void Shader::SetMat4(const std::string &name, const glm::mat4 &mat) const
|
||||
{
|
||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
|
||||
void Shader::SetVec3(const std::string &name, const glm::vec3 &vec) const
|
||||
{
|
||||
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &vec[0]);
|
||||
}
|
22
src/ShaderComponent.h
Normal file
22
src/ShaderComponent.h
Normal file
@ -0,0 +1,22 @@
|
||||
// src/ShaderComponent.h
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <GL/glew.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
GLuint ID;
|
||||
|
||||
Shader() : ID(0) {}
|
||||
Shader(const char* vertexPath, const char* fragmentPath);
|
||||
void Use();
|
||||
void SetBool(const std::string &name, bool value) const;
|
||||
void SetInt(const std::string &name, int value) const;
|
||||
void SetFloat(const std::string &name, float value) const;
|
||||
void SetMat4(const std::string &name, const glm::mat4 &mat) const;
|
||||
void SetVec3(const std::string &name, const glm::vec3 &vec) const;
|
||||
};
|
289
src/main.cpp
289
src/main.cpp
@ -5,21 +5,26 @@
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_opengl3.h"
|
||||
#include "../IconsFontAwesome6.h"
|
||||
#include "../IconsFontAwesome6.h" // Ensure correct path
|
||||
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h" // Include stb_image.h
|
||||
|
||||
#include "ECS.h" // Include the ECS header
|
||||
#include "Logger.h" // Include the Logger header
|
||||
#include "TextureManager.h" // Include the TextureManager header
|
||||
#include "UI.h" // Include the UI header
|
||||
#include "Meshes.h" // Include the Meshes header
|
||||
#include "ShaderComponent.h" // Include the ShaderComponent header
|
||||
#include "CameraSystem.h" // Include the CameraSystem header
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
// =====================
|
||||
// Callback for GLFW errors
|
||||
@ -30,6 +35,28 @@ static void glfw_error_callback(int error, const char* description)
|
||||
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Global Variables for Camera Control
|
||||
// =====================
|
||||
|
||||
bool firstMouse = true;
|
||||
float lastX = 1280.0f / 2.0f;
|
||||
float lastY = 720.0f / 2.0f;
|
||||
bool mouseCaptured = true;
|
||||
|
||||
// =====================
|
||||
// Forward Declarations
|
||||
// =====================
|
||||
|
||||
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
|
||||
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
|
||||
|
||||
// =====================
|
||||
// Camera Entity ID
|
||||
// =====================
|
||||
|
||||
Entity cameraEntity = UINT32_MAX;
|
||||
|
||||
// =====================
|
||||
// Main Function
|
||||
// =====================
|
||||
@ -37,29 +64,42 @@ static void glfw_error_callback(int error, const char* description)
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup Logger
|
||||
//LOGPOINT("Loading Engine");
|
||||
Logger::GetInstance().Log(LogLevel::INFO, "Loading engine...");
|
||||
Logger::GetInstance().Log(LogLevel::INFO, "Loading Engine...");
|
||||
|
||||
// Setup GLFW error callback
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
|
||||
// Initialize GLFW
|
||||
if (!glfwInit())
|
||||
return 1;
|
||||
{
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, "Failed to initialize GLFW.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// GL 3.0 + GLSL 130
|
||||
// GL 3.3 + GLSL 330
|
||||
const char* glsl_version = "#version 330";
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac
|
||||
#endif
|
||||
|
||||
// Create window with graphics context
|
||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Tesseract Engine", NULL, NULL);
|
||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Tesseract Engine - 3D", NULL, NULL);
|
||||
if (window == NULL)
|
||||
return 1;
|
||||
{
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, "Failed to create GLFW window.");
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1); // Enable vsync
|
||||
|
||||
|
||||
// Set viewport
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
@ -73,7 +113,7 @@ int main(int, char**)
|
||||
fontConfig.MergeMode = true;
|
||||
fontConfig.PixelSnapH = true;
|
||||
|
||||
// Path to your fonts
|
||||
// Paths to your fonts
|
||||
const char* font_path = "./assets/fonts/Roboto-Medium.ttf"; // Replace with your default font
|
||||
const char* fa_font_path = "./assets/fonts/fa-solid-900.ttf"; // Replace with your Font Awesome font
|
||||
|
||||
@ -81,8 +121,8 @@ int main(int, char**)
|
||||
ImFont* default_font = io.Fonts->AddFontFromFileTTF(font_path, 16.0f);
|
||||
if (!default_font)
|
||||
{
|
||||
fprintf(stderr, "Failed to load default font!\n");
|
||||
return 1;
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, "Failed to load default font!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Define the Font Awesome icon range
|
||||
@ -91,11 +131,10 @@ int main(int, char**)
|
||||
// Merge Font Awesome icons
|
||||
fontConfig.GlyphMinAdvanceX = 13.0f; // Adjust if necessary
|
||||
ImFont* fa_font = io.Fonts->AddFontFromFileTTF(fa_font_path, 16.0f, &fontConfig, icons_ranges);
|
||||
|
||||
if (!fa_font)
|
||||
{
|
||||
fprintf(stderr, "Failed to load Font Awesome font!\n");
|
||||
return 1;
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, "Failed to load Font Awesome font!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Build the font atlas
|
||||
@ -124,17 +163,67 @@ int main(int, char**)
|
||||
ComponentManager componentManager;
|
||||
entityManager.Init();
|
||||
componentManager.RegisterComponent<TransformComponent>();
|
||||
componentManager.RegisterComponent<SpriteComponent>();
|
||||
componentManager.RegisterComponent<MeshComponent>();
|
||||
componentManager.RegisterComponent<Shader>();
|
||||
componentManager.RegisterComponent<CameraComponent>();
|
||||
|
||||
// Create a default entity with TransformComponent (without SpriteComponent)
|
||||
// Create a default entity with TransformComponent, MeshComponent, Shader, and CameraComponent
|
||||
Entity defaultEntity = entityManager.CreateEntity();
|
||||
componentManager.AddComponent<TransformComponent>(defaultEntity, TransformComponent());
|
||||
componentManager.AddComponent<MeshComponent>(defaultEntity, CreateCubeMesh());
|
||||
Shader shader("shaders/basic.vert", "shaders/basic.frag");
|
||||
componentManager.AddComponent<Shader>(defaultEntity, shader);
|
||||
componentManager.AddComponent<CameraComponent>(defaultEntity, CameraComponent());
|
||||
|
||||
Logger::GetInstance().Log(LogLevel::INFO, "Engine initialized successfully.");
|
||||
|
||||
// Instantiate TextureManager
|
||||
TextureManager textureManager;
|
||||
|
||||
// Load Textures if necessary
|
||||
// GLuint diffuseMap = textureManager.LoadTexture("path_to_diffuse_map.png");
|
||||
// GLuint specularMap = textureManager.LoadTexture("path_to_specular_map.png");
|
||||
|
||||
// Setup Framebuffer Object (FBO) for rendering
|
||||
GLuint framebuffer;
|
||||
glGenFramebuffers(1, &framebuffer);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
|
||||
// Create a color attachment texture
|
||||
GLuint texColorBuffer;
|
||||
glGenTextures(1, &texColorBuffer);
|
||||
glBindTexture(GL_TEXTURE_2D, texColorBuffer);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, display_w, display_h, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texColorBuffer, 0);
|
||||
|
||||
// Create a renderbuffer object for depth and stencil attachment
|
||||
GLuint rbo;
|
||||
glGenRenderbuffers(1, &rbo);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rbo);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, display_w, display_h);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo);
|
||||
|
||||
// Check if framebuffer is complete
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
Logger::GetInstance().Log(LogLevel::ERROR, "ERROR::FRAMEBUFFER:: Framebuffer is not complete!");
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// Setup Camera System
|
||||
float deltaTime = 0.0f; // Time between current frame and last frame
|
||||
float lastFrame = 0.0f; // Time of last frame
|
||||
CameraSystem cameraSystem(window, deltaTime);
|
||||
|
||||
// Setup Mouse Callbacks
|
||||
glfwSetCursorPosCallback(window, mouse_callback);
|
||||
glfwSetScrollCallback(window, scroll_callback);
|
||||
|
||||
// Capture the mouse cursor
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
// Variables for Console
|
||||
bool show_console = true;
|
||||
|
||||
@ -144,6 +233,11 @@ int main(int, char**)
|
||||
// Main loop
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
// Per-frame time logic
|
||||
float currentFrame = static_cast<float>(glfwGetTime());
|
||||
deltaTime = currentFrame - lastFrame;
|
||||
lastFrame = currentFrame;
|
||||
|
||||
// Poll and handle events (inputs, window resize, etc.)
|
||||
glfwPollEvents();
|
||||
|
||||
@ -152,19 +246,101 @@ int main(int, char**)
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Bind to framebuffer and draw scene as we normally would to color texture
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||
glEnable(GL_DEPTH_TEST); // Enable depth testing for 3D
|
||||
|
||||
// Clear buffers
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Use shader
|
||||
Shader& activeShader = componentManager.GetComponent<Shader>(defaultEntity);
|
||||
activeShader.Use();
|
||||
|
||||
// Retrieve camera view and projection matrices
|
||||
glm::mat4 view;
|
||||
glm::mat4 projection;
|
||||
glm::vec3 cameraPos;
|
||||
for(auto entity : entityManager.GetActiveEntities()) {
|
||||
if(componentManager.HasComponent<CameraComponent>(entity)) {
|
||||
auto& camera = componentManager.GetComponent<CameraComponent>(entity);
|
||||
view = camera.GetViewMatrix();
|
||||
cameraPos = camera.Position;
|
||||
}
|
||||
}
|
||||
|
||||
projection = glm::perspective(glm::radians(45.0f),
|
||||
(float)display_w / (float)display_h,
|
||||
0.1f, 100.0f);
|
||||
|
||||
// Set uniforms
|
||||
activeShader.SetMat4("view", view);
|
||||
activeShader.SetMat4("projection", projection);
|
||||
activeShader.SetVec3("viewPos", cameraPos);
|
||||
|
||||
// Set light properties
|
||||
activeShader.SetVec3("light.position", glm::vec3(1.2f, 1.0f, 2.0f));
|
||||
activeShader.SetVec3("light.ambient", glm::vec3(0.2f, 0.2f, 0.2f));
|
||||
activeShader.SetVec3("light.diffuse", glm::vec3(0.5f, 0.5f, 0.5f));
|
||||
activeShader.SetVec3("light.specular", glm::vec3(1.0f, 1.0f, 1.0f));
|
||||
|
||||
// Set material properties
|
||||
activeShader.SetInt("material.diffuse", 0);
|
||||
activeShader.SetInt("material.specular", 1);
|
||||
activeShader.SetFloat("material.shininess", 32.0f);
|
||||
|
||||
// Bind textures if any
|
||||
// For example:
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
// glBindTexture(GL_TEXTURE_2D, diffuseMap);
|
||||
// glActiveTexture(GL_TEXTURE1);
|
||||
// glBindTexture(GL_TEXTURE_2D, specularMap);
|
||||
|
||||
// Render all meshes
|
||||
for(auto entity : entityManager.GetActiveEntities()) {
|
||||
if(componentManager.HasComponent<MeshComponent>(entity) && componentManager.HasComponent<TransformComponent>(entity)) {
|
||||
auto& mesh = componentManager.GetComponent<MeshComponent>(entity);
|
||||
auto& transform = componentManager.GetComponent<TransformComponent>(entity);
|
||||
|
||||
// Create model matrix
|
||||
glm::mat4 model = glm::mat4(1.0f);
|
||||
model = glm::translate(model, transform.position);
|
||||
model = glm::rotate(model, glm::radians(transform.rotation.x), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
model = glm::rotate(model, glm::radians(transform.rotation.y), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
model = glm::rotate(model, glm::radians(transform.rotation.z), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
model = glm::scale(model, transform.scale);
|
||||
|
||||
activeShader.SetMat4("model", model);
|
||||
|
||||
// Bind VAO and draw
|
||||
glBindVertexArray(mesh.VAO);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(mesh.indices.size()), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Unbind framebuffer
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
// Disable depth testing for UI rendering
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// Start ImGui frame
|
||||
ImGui::NewFrame();
|
||||
|
||||
// Create DockSpace
|
||||
ImGuiWindowFlags dockspace_flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||
const ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
const ImGuiViewport* viewport_main = ImGui::GetMainViewport();
|
||||
|
||||
// Adjust the docking space position by 20 pixels to avoid overlapping with the main menu bar
|
||||
ImGui::SetNextWindowPos(ImVec2(viewport->Pos.x, viewport->Pos.y + 20));
|
||||
ImGui::SetNextWindowSize(ImVec2(viewport->Size.x, viewport->Size.y - 20));
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
ImGui::SetNextWindowPos(ImVec2(viewport_main->Pos.x, viewport_main->Pos.y));
|
||||
ImGui::SetNextWindowSize(ImVec2(viewport_main->Size.x, viewport_main->Size.y));
|
||||
ImGui::SetNextWindowViewport(viewport_main->ID);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||
ImGui::Begin("DockSpace", nullptr, dockspace_flags);
|
||||
ImGui::Begin("DockSpaceWindow", nullptr, dockspace_flags);
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// DockSpace
|
||||
@ -178,16 +354,18 @@ int main(int, char**)
|
||||
|
||||
// Show GUI windows
|
||||
ShowMainMenuBar();
|
||||
ShowViewport(textureManager, entityManager, componentManager); // Pass references
|
||||
ShowConsole(&show_console);
|
||||
|
||||
// Show ECS UI panels
|
||||
ShowEntityTree(entityManager, componentManager, selectedEntity);
|
||||
ShowInspector(entityManager, componentManager, selectedEntity);
|
||||
ShowInspector(componentManager, selectedEntity);
|
||||
|
||||
// Render the framebuffer texture in the Viewport panel
|
||||
ImGui::Begin("Viewport");
|
||||
ImGui::Text("3D Viewport");
|
||||
ImGui::Image((void*)(intptr_t)texColorBuffer, ImVec2(1280, 720), ImVec2(0,1), ImVec2(1,0));
|
||||
ImGui::End();
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
int display_w, display_h;
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
glViewport(0, 0, display_w, display_h);
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); // Dark background
|
||||
@ -206,8 +384,16 @@ int main(int, char**)
|
||||
*/
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
|
||||
// Process camera input
|
||||
cameraSystem.ProcessInput(entityManager, componentManager);
|
||||
}
|
||||
|
||||
// Cleanup framebuffer objects
|
||||
glDeleteFramebuffers(1, &framebuffer);
|
||||
glDeleteTextures(1, &texColorBuffer);
|
||||
glDeleteRenderbuffers(1, &rbo);
|
||||
|
||||
// Cleanup
|
||||
textureManager.Cleanup();
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
@ -219,3 +405,46 @@ int main(int, char**)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Mouse Movement Callback
|
||||
// =====================
|
||||
|
||||
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
if (cameraEntity == UINT32_MAX)
|
||||
return;
|
||||
|
||||
auto& camera = EntityManager::GetInstance().GetComponent<CameraComponent>(cameraEntity); // Assuming GetInstance exists
|
||||
if (!cameraEntity) return;
|
||||
|
||||
if (firstMouse)
|
||||
{
|
||||
lastX = static_cast<float>(xpos);
|
||||
lastY = static_cast<float>(ypos);
|
||||
firstMouse = false;
|
||||
}
|
||||
|
||||
float xoffset = static_cast<float>(xpos) - lastX;
|
||||
float yoffset = lastY - static_cast<float>(ypos); // Reversed since y-coordinates go from bottom to top
|
||||
|
||||
lastX = static_cast<float>(xpos);
|
||||
lastY = static_cast<float>(ypos);
|
||||
|
||||
camera.ProcessMouseMovement(xoffset, yoffset);
|
||||
}
|
||||
|
||||
// =====================
|
||||
// Scroll Callback
|
||||
// =====================
|
||||
|
||||
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
|
||||
{
|
||||
if (cameraEntity == UINT32_MAX)
|
||||
return;
|
||||
|
||||
auto& camera = EntityManager::GetInstance().GetComponent<CameraComponent>(cameraEntity); // Assuming GetInstance exists
|
||||
if (!cameraEntity) return;
|
||||
|
||||
camera.ProcessMouseScroll(static_cast<float>(yoffset));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user