Updated Lighting and compont.
This commit is contained in:
parent
4dfd637972
commit
4ba7e8f888
17
build.log
17
build.log
@ -1,14 +1,15 @@
|
|||||||
[COMPILE] g++ -std=c++20 -Wall -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -MMD -MP -c src\src\Renderer.cpp -o src\build\src\Renderer.oIn file included from C:/msys64/mingw64/include/yaml-cpp/parser.h:13,
|
[COMPILE] g++ -std=c++20 -Wall -Isrc/include -Isrc/vendor -Isrc/vendor/imgui -IC:/msys64/mingw64/include -MMD -MP -c src\src\Engine.cpp -o src\build\src\Engine.oIn file included from C:/msys64/mingw64/include/yaml-cpp/parser.h:13,
|
||||||
from C:/msys64/mingw64/include/yaml-cpp/yaml.h:10,
|
from C:/msys64/mingw64/include/yaml-cpp/yaml.h:10,
|
||||||
from src\src\Components/Component.h:5,
|
from src\src\Entitys/Object.h:7,
|
||||||
from src\src\Components/SpriteComponent.h:3,
|
from src\src\Engine.cpp:2:
|
||||||
from src\src\Renderer.cpp:2:
|
|
||||||
C:/msys64/mingw64/include/yaml-cpp/dll.h:22:65: note: '#pragma message: Defining YAML_CPP_API for DLL import'
|
C:/msys64/mingw64/include/yaml-cpp/dll.h:22:65: note: '#pragma message: Defining YAML_CPP_API for DLL import'
|
||||||
22 | # pragma message( "Defining YAML_CPP_API for DLL import" )
|
22 | # pragma message( "Defining YAML_CPP_API for DLL import" )
|
||||||
| ^
|
| ^
|
||||||
|
src\src\Engine.cpp: In function 'void DrawInspectorUI(std::shared_ptr<Object>)':
|
||||||
|
src\src\Engine.cpp:219:13: warning: unused variable 'type' [-Wunused-variable]
|
||||||
|
219 | int type = light->GetType();
|
||||||
|
| ^~~~
|
||||||
|
|
||||||
[LINK] g++ src\build\src\Engine.o src\build\src\main.o src\build\src\Renderer.o src\build\src\Components\CameraComponent.o src\build\src\Components\SpriteComponent.o src\build\src\Entitys\Object.o src\build\src\utils\FileDialog.o src\build\src\utils\Shader.o src\build\vendor\imgui\imgui.o src\build\vendor\imgui\imgui_demo.o src\build\vendor\imgui\imgui_draw.o src\build\vendor\imgui\imgui_impl_glfw.o src\build\vendor\imgui\imgui_impl_opengl3.o src\build\vendor\imgui\imgui_tables.o src\build\vendor\imgui\imgui_widgets.o -o src\build\app.exe -LC:/msys64/mingw64/lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
[LINK] g++ src\build\src\Engine.o src\build\src\main.o src\build\src\Renderer.o src\build\src\Components\CameraComponent.o src\build\src\Components\LightComponent.o src\build\src\Components\SpriteComponent.o src\build\src\Entitys\Object.o src\build\src\utils\FileDialog.o src\build\src\utils\Logging.o src\build\src\utils\Shader.o src\build\src\utils\utils.o src\build\vendor\imgui\imgui.o src\build\vendor\imgui\imgui_demo.o src\build\vendor\imgui\imgui_draw.o src\build\vendor\imgui\imgui_impl_glfw.o src\build\vendor\imgui\imgui_impl_opengl3.o src\build\vendor\imgui\imgui_tables.o src\build\vendor\imgui\imgui_widgets.o -o src\build\app.exe -LC:/msys64/mingw64/lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
||||||
|
|
||||||
[TIME] Build duration: 2.75s
|
[TIME] Build duration: 6.67s
|
||||||
[ERROR] Runtime crash
|
|
||||||
Command 'src\build\app.exe' returned non-zero exit status 1.
|
|
||||||
|
29
imgui.ini
29
imgui.ini
@ -15,9 +15,9 @@ Collapsed=0
|
|||||||
|
|
||||||
[Window][Inspector]
|
[Window][Inspector]
|
||||||
Pos=873,19
|
Pos=873,19
|
||||||
Size=407,701
|
Size=407,505
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000004,0
|
DockId=0x00000005,0
|
||||||
|
|
||||||
[Window][Scene Tree]
|
[Window][Scene Tree]
|
||||||
Pos=0,19
|
Pos=0,19
|
||||||
@ -27,19 +27,34 @@ DockId=0x00000001,0
|
|||||||
|
|
||||||
[Window][Viewport]
|
[Window][Viewport]
|
||||||
Pos=265,19
|
Pos=265,19
|
||||||
Size=606,701
|
Size=606,412
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000002,0
|
DockId=0x00000007,0
|
||||||
|
|
||||||
[Window][##MainMenuBar]
|
[Window][##MainMenuBar]
|
||||||
Pos=0,0
|
|
||||||
Size=1280,19
|
Size=1280,19
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Performance Info]
|
||||||
|
Pos=873,526
|
||||||
|
Size=407,194
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000006,0
|
||||||
|
|
||||||
|
[Window][Console]
|
||||||
|
Pos=265,433
|
||||||
|
Size=606,287
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x00000008,0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
||||||
DockNode ID=0x00000003 Parent=0x11111111 SizeRef=1511,1158 Split=X
|
DockNode ID=0x00000003 Parent=0x11111111 SizeRef=1511,1158 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=263,701 HiddenTabBar=1 Selected=0x12EF0F59
|
DockNode ID=0x00000001 Parent=0x00000003 SizeRef=263,701 HiddenTabBar=1 Selected=0x12EF0F59
|
||||||
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1246,701 CentralNode=1 Selected=0xC450F867
|
DockNode ID=0x00000002 Parent=0x00000003 SizeRef=1246,701 Split=Y Selected=0xC450F867
|
||||||
DockNode ID=0x00000004 Parent=0x11111111 SizeRef=407,1158 HiddenTabBar=1 Selected=0x36DC96AB
|
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,869 CentralNode=1 Selected=0xC450F867
|
||||||
|
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,287 Selected=0xEA83D666
|
||||||
|
DockNode ID=0x00000004 Parent=0x11111111 SizeRef=407,1158 Split=Y Selected=0x36DC96AB
|
||||||
|
DockNode ID=0x00000005 Parent=0x00000004 SizeRef=407,835 HiddenTabBar=1 Selected=0x36DC96AB
|
||||||
|
DockNode ID=0x00000006 Parent=0x00000004 SizeRef=407,321 HiddenTabBar=1 Selected=0x3FC1A724
|
||||||
|
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
engine_version: 0.1.0
|
engine_version: 0.1.0
|
||||||
scene_name: test
|
scene_name: test
|
||||||
scene_hash: b3488ddfbb343e554cb1782c1b79598e15545d752cfec63be97f90c8d422aaf5
|
scene_hash: beb59668150f92192118ae530ea3d931789cec7c937e2620b25516e0f88ac8a7
|
||||||
format_version: 1
|
format_version: 1
|
||||||
objects:
|
objects:
|
||||||
- name: Sprite Object
|
- name: Sprite Object
|
||||||
position: [438, 0]
|
position: [0, 0]
|
||||||
layer: 0
|
layer: 0
|
||||||
components:
|
components:
|
||||||
- type: CameraComponent
|
- type: CameraComponent
|
||||||
fov: 45
|
fov: 45
|
||||||
aspect: 1.76999998
|
aspect: 1.76999998
|
||||||
zoom: 1
|
zoom: 1
|
||||||
|
primary: true
|
||||||
- type: SpriteComponent
|
- type: SpriteComponent
|
||||||
texture: C:\Users\spenc\OneDrive\Pictures\49555.jpg
|
texture: C:\Users\spenc\OneDrive\Pictures\49555.jpg
|
||||||
normalMap: ""
|
normalMap: ""
|
||||||
@ -39,3 +40,17 @@ objects:
|
|||||||
texture: C:\Users\spenc\OneDrive\Pictures\49555.jpg
|
texture: C:\Users\spenc\OneDrive\Pictures\49555.jpg
|
||||||
normalMap: ""
|
normalMap: ""
|
||||||
children: []
|
children: []
|
||||||
|
- name: Light
|
||||||
|
position: [-5000, -5000]
|
||||||
|
layer: 1
|
||||||
|
components:
|
||||||
|
- type: LightComponent
|
||||||
|
color:
|
||||||
|
- 1
|
||||||
|
- 1
|
||||||
|
- 1
|
||||||
|
intensity: 10
|
||||||
|
radius: 100000000
|
||||||
|
falloff: 0.100000001
|
||||||
|
type: 0
|
||||||
|
children: []
|
@ -1,9 +1,46 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
in vec2 vUV;
|
in vec2 vUV;
|
||||||
|
in vec2 vFragScreenPos;
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
uniform sampler2D uTex;
|
uniform sampler2D uTex;
|
||||||
|
uniform sampler2D uNormalMap;
|
||||||
|
|
||||||
void main() {
|
uniform int uLightCount;
|
||||||
FragColor = texture(uTex, vUV);
|
uniform vec2 uLightPos[8];
|
||||||
|
uniform vec3 uLightColor[8];
|
||||||
|
uniform float uLightIntensity[8];
|
||||||
|
uniform float uLightRadius[8];
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 texColor = texture(uTex, vUV);
|
||||||
|
if (texColor.a < 0.1)
|
||||||
|
discard;
|
||||||
|
|
||||||
|
vec3 normal = texture(uNormalMap, vUV).rgb * 2.0 - 1.0;
|
||||||
|
normal = normalize(normal);
|
||||||
|
|
||||||
|
vec3 finalLight = vec3(0.0);
|
||||||
|
|
||||||
|
for (int i = 0; i < uLightCount; ++i)
|
||||||
|
{
|
||||||
|
vec2 lightVec = uLightPos[i] - vFragScreenPos;
|
||||||
|
float dist = length(lightVec);
|
||||||
|
|
||||||
|
if (dist < uLightRadius[i])
|
||||||
|
{
|
||||||
|
vec2 lightDir2D = normalize(lightVec);
|
||||||
|
vec3 lightDir = normalize(vec3(lightDir2D, 1.0)); // pseudo-3D
|
||||||
|
|
||||||
|
float attenuation = 1.0 - dist / uLightRadius[i];
|
||||||
|
float diff = max(dot(normal, lightDir), 0.0);
|
||||||
|
vec3 light = uLightColor[i] * diff * attenuation * uLightIntensity[i];
|
||||||
|
finalLight += light;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 result = texColor.rgb * finalLight;
|
||||||
|
FragColor = vec4(result, texColor.a);
|
||||||
}
|
}
|
@ -1,16 +1,25 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
layout(location = 0) in vec2 aPos;
|
layout(location = 0) in vec2 aPos;
|
||||||
layout(location = 1) in vec2 aUV;
|
layout(location = 1) in vec2 aUV;
|
||||||
|
|
||||||
|
out vec2 vUV;
|
||||||
|
out vec2 vFragScreenPos;
|
||||||
|
|
||||||
uniform vec2 uPos;
|
uniform vec2 uPos;
|
||||||
uniform vec2 uSize;
|
uniform vec2 uSize;
|
||||||
uniform vec2 uScreen;
|
uniform vec2 uScreen;
|
||||||
|
|
||||||
out vec2 vUV;
|
void main()
|
||||||
|
{
|
||||||
|
vUV = aUV;
|
||||||
|
|
||||||
void main() {
|
vec2 worldPos = uPos + aPos * uSize;
|
||||||
vec2 scaled = aPos * uSize + uPos;
|
|
||||||
vec2 ndc = scaled / uScreen * 2.0 - 1.0;
|
vFragScreenPos = worldPos;
|
||||||
gl_Position = vec4(ndc.x, -ndc.y, 0.0, 1.0);
|
|
||||||
vUV = vec2(aUV.x, 1.0 - aUV.y);
|
vec2 ndc = (worldPos / uScreen) * 2.0 - 1.0;
|
||||||
|
ndc.y *= -1.0;
|
||||||
|
|
||||||
|
gl_Position = vec4(ndc, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
[Window][WindowOverViewport_11111111]
|
|
||||||
Pos=0,19
|
|
||||||
Size=1280,701
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Debug##Default]
|
|
||||||
Pos=60,60
|
|
||||||
Size=400,400
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Scene Tree]
|
|
||||||
Pos=60,60
|
|
||||||
Size=128,48
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Window][Inspector]
|
|
||||||
Pos=1123,19
|
|
||||||
Size=157,701
|
|
||||||
Collapsed=0
|
|
||||||
DockId=0x00000002,0
|
|
||||||
|
|
||||||
[Window][Viewport]
|
|
||||||
Pos=60,60
|
|
||||||
Size=32,35
|
|
||||||
Collapsed=0
|
|
||||||
|
|
||||||
[Docking][Data]
|
|
||||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
|
||||||
DockNode ID=0x00000001 Parent=0x11111111 SizeRef=1121,701 CentralNode=1
|
|
||||||
DockNode ID=0x00000002 Parent=0x11111111 SizeRef=157,701 Selected=0x36DC96AB
|
|
||||||
|
|
32
src/src/Components/LightComponent.cpp
Normal file
32
src/src/Components/LightComponent.cpp
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#include "LightComponent.h"
|
||||||
|
|
||||||
|
LightComponent::LightComponent(Object* owner)
|
||||||
|
: Component(owner) {}
|
||||||
|
|
||||||
|
void LightComponent::Save(YAML::Emitter& out) const
|
||||||
|
{
|
||||||
|
out << YAML::BeginMap;
|
||||||
|
out << YAML::Key << "type" << YAML::Value << "LightComponent";
|
||||||
|
out << YAML::Key << "color" << YAML::Value << std::vector<float>{ m_Color.r, m_Color.g, m_Color.b };
|
||||||
|
out << YAML::Key << "intensity" << YAML::Value << m_Intensity;
|
||||||
|
out << YAML::Key << "radius" << YAML::Value << m_Radius;
|
||||||
|
out << YAML::Key << "falloff" << YAML::Value << m_Falloff;
|
||||||
|
out << YAML::Key << "type" << YAML::Value << m_type;
|
||||||
|
|
||||||
|
out << YAML::EndMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LightComponent::Load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
if (node["color"])
|
||||||
|
{
|
||||||
|
auto vec = node["color"].as<std::vector<float>>();
|
||||||
|
if (vec.size() == 3)
|
||||||
|
m_Color = glm::vec3(vec[0], vec[1], vec[2]);
|
||||||
|
}
|
||||||
|
if (node["intensity"]) m_Intensity = node["intensity"].as<float>();
|
||||||
|
if (node["radius"]) m_Radius = node["radius"].as<float>();
|
||||||
|
if (node["falloff"]) m_Falloff = node["falloff"].as<float>();
|
||||||
|
if (node["light_type"])m_type = node["light_type"].as<int>();
|
||||||
|
|
||||||
|
}
|
41
src/src/Components/LightComponent.h
Normal file
41
src/src/Components/LightComponent.h
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Component.h"
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <yaml-cpp/yaml.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class LightComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
LightComponent(Object* owner);
|
||||||
|
|
||||||
|
std::string GetName() const override { return "LightComponent"; }
|
||||||
|
|
||||||
|
void Save(YAML::Emitter& out) const override;
|
||||||
|
void Load(const YAML::Node& node) override;
|
||||||
|
|
||||||
|
void SetColor(const glm::vec3& color) { m_Color = color; }
|
||||||
|
void SetIntensity(float intensity) { m_Intensity = intensity; }
|
||||||
|
void SetRadius(float radius) { m_Radius = radius; }
|
||||||
|
void SetFalloff(float falloff) { m_Falloff = falloff; }
|
||||||
|
void SetType(int type) { m_type = type; }
|
||||||
|
|
||||||
|
|
||||||
|
glm::vec3 GetColor() const { return m_Color; }
|
||||||
|
float GetIntensity() const { return m_Intensity; }
|
||||||
|
float GetRadius() const { return m_Radius; }
|
||||||
|
float GetFalloff() const { return m_Falloff; }
|
||||||
|
int GetType() const { return m_type; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
glm::vec3 m_Color {1.0f, 1.0f, 1.0f};
|
||||||
|
float m_Intensity = 1.0f;
|
||||||
|
float m_Radius = 300.0f;
|
||||||
|
float m_Falloff = 1.0f;
|
||||||
|
int m_type = 0;
|
||||||
|
};
|
@ -3,15 +3,22 @@
|
|||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include "../utils/Logging.h"
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
|
|
||||||
SpriteComponent::SpriteComponent(Object* owner) : Component(owner) {}
|
SpriteComponent::SpriteComponent(Object* owner) : Component(owner) {}
|
||||||
|
|
||||||
unsigned int SpriteComponent::LoadTexture(const std::string& path) {
|
unsigned int SpriteComponent::LoadTexture(const std::string& path) {
|
||||||
int w, h, channels;
|
int w, h, channels;
|
||||||
stbi_set_flip_vertically_on_load(1);
|
std::string filename = GetFilenameFromPath(path);
|
||||||
|
stbi_set_flip_vertically_on_load(false);
|
||||||
|
|
||||||
unsigned char* data = stbi_load(path.c_str(), &w, &h, &channels, 4);
|
unsigned char* data = stbi_load(path.c_str(), &w, &h, &channels, 4);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
std::cerr << "Failed to load image: " << path << "\nReason: " << stbi_failure_reason() << std::endl;
|
Logger::LogError("Failed to load asset: '%s': %s", filename.c_str(), stbi_failure_reason());
|
||||||
|
|
||||||
|
texture_loaded = false;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,18 +37,29 @@ unsigned int SpriteComponent::LoadTexture(const std::string& path) {
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
|
texture_loaded = true;
|
||||||
|
Logger::LogDebug("Loaded Asset: %s, %d", filename.c_str(), id);
|
||||||
|
textureID = id;
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SpriteComponent::HasTexture()
|
||||||
|
{
|
||||||
|
return texture_loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpriteComponent::SetTexture(const std::string& path) {
|
void SpriteComponent::SetTexture(const std::string& path) {
|
||||||
|
if (path.empty()) return;
|
||||||
texturePath = path;
|
texturePath = path;
|
||||||
textureID = LoadTexture(path);
|
LoadTexture(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SpriteComponent::SetNormalMap(const std::string& path) {
|
void SpriteComponent::SetNormalMap(const std::string& path) {
|
||||||
|
if (path.empty()) return;
|
||||||
normalMapPath = path;
|
normalMapPath = path;
|
||||||
normalMapID = LoadTexture(path);
|
LoadTexture(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int SpriteComponent::GetTextureID() const {
|
unsigned int SpriteComponent::GetTextureID() const {
|
||||||
@ -69,6 +87,10 @@ void SpriteComponent::Save(YAML::Emitter& out) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SpriteComponent::Load(const YAML::Node& node) {
|
void SpriteComponent::Load(const YAML::Node& node) {
|
||||||
if (node["texture"]) SetTexture(node["texture"].as<std::string>());
|
if (node["texture"] && !node["texture"].as<std::string>().empty())
|
||||||
if (node["normalMap"]) SetNormalMap(node["normalMap"].as<std::string>());
|
SetTexture(node["texture"].as<std::string>());
|
||||||
|
|
||||||
|
if (node["normalMap"] && !node["normalMap"].as<std::string>().empty())
|
||||||
|
SetNormalMap(node["normalMap"].as<std::string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,10 @@ public:
|
|||||||
std::string GetTexturePath() const;
|
std::string GetTexturePath() const;
|
||||||
std::string GetNormalMapPath() const;
|
std::string GetNormalMapPath() const;
|
||||||
|
|
||||||
|
bool HasTexture();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
virtual glm::vec2 GetSize() const { return size; }
|
virtual glm::vec2 GetSize() const { return size; }
|
||||||
|
|
||||||
virtual std::string GetName() const override { return "SpriteComponent"; }
|
virtual std::string GetName() const override { return "SpriteComponent"; }
|
||||||
@ -33,6 +37,6 @@ private:
|
|||||||
std::string normalMapPath;
|
std::string normalMapPath;
|
||||||
unsigned int textureID = 0;
|
unsigned int textureID = 0;
|
||||||
unsigned int normalMapID = 0;
|
unsigned int normalMapID = 0;
|
||||||
|
bool texture_loaded = false;
|
||||||
unsigned int LoadTexture(const std::string& path);
|
unsigned int LoadTexture(const std::string& path);
|
||||||
};
|
};
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "components/SpriteComponent.h"
|
#include "components/SpriteComponent.h"
|
||||||
#include "components/CameraComponent.h"
|
#include "components/CameraComponent.h"
|
||||||
|
#include "components/LightComponent.h"
|
||||||
|
|
||||||
#include "utils/FileDialog.h"
|
#include "utils/FileDialog.h"
|
||||||
|
#include "utils/Logging.h"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
@ -21,7 +23,6 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#define NOMINMAX
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <commdlg.h>
|
#include <commdlg.h>
|
||||||
#include <openssl/sha.h>
|
#include <openssl/sha.h>
|
||||||
@ -32,7 +33,6 @@ static bool playing = false;
|
|||||||
|
|
||||||
static glm::vec2 cameraPos = {0, 0};
|
static glm::vec2 cameraPos = {0, 0};
|
||||||
static float cameraZoom = 1.0f;
|
static float cameraZoom = 1.0f;
|
||||||
static bool isDragging = false;
|
|
||||||
static ImVec2 lastMousePos = {};
|
static ImVec2 lastMousePos = {};
|
||||||
|
|
||||||
GLFWwindow *window = nullptr;
|
GLFWwindow *window = nullptr;
|
||||||
@ -47,6 +47,43 @@ Engine::~Engine()
|
|||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Engine::ShowDebugOverlay(float deltaTime)
|
||||||
|
{
|
||||||
|
static std::vector<float> fpsHistory;
|
||||||
|
static const int maxHistory = 100;
|
||||||
|
static float timer = 0;
|
||||||
|
float fps = 1.0f / deltaTime;
|
||||||
|
if (fpsHistory.size() >= maxHistory)
|
||||||
|
fpsHistory.erase(fpsHistory.begin());
|
||||||
|
if (timer >= 0.05)
|
||||||
|
{
|
||||||
|
timer = 0;
|
||||||
|
fpsHistory.push_back(fps);
|
||||||
|
}
|
||||||
|
timer += deltaTime;
|
||||||
|
|
||||||
|
ImGui::Begin("Performance Info", nullptr,
|
||||||
|
ImGuiWindowFlags_NoDecoration);
|
||||||
|
|
||||||
|
ImGui::TextColored(ImVec4(0.3f, 1.0f, 0.3f, 1.0f), "Performance");
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("FPS: %.1f", fps);
|
||||||
|
ImGui::Text("Delta Time: %.4f s", deltaTime);
|
||||||
|
ImGui::Text("Frame Time: %.2f ms", deltaTime * 1000.0f);
|
||||||
|
ImGui::PlotLines("##FPS", fpsHistory.data(), fpsHistory.size(), 0, "FPS History", 0.0f, 144.0f, ImVec2(-1, 50));
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "Renderer");
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::Text("Draw Calls: %d", Renderer::GetDrawCallCount());
|
||||||
|
ImGui::Text("Reserved Draws: %d", m_Reserved_draws);
|
||||||
|
|
||||||
|
ImGui::Text("Camera Zoom: %.2f", cameraZoom);
|
||||||
|
ImGui::Text("Camera Pos: (%.1f, %.1f)", cameraPos.x, cameraPos.y);
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
void Engine::Init()
|
void Engine::Init()
|
||||||
{
|
{
|
||||||
glfwInit();
|
glfwInit();
|
||||||
@ -54,9 +91,9 @@ void Engine::Init()
|
|||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
window = glfwCreateWindow(1280, 720, "2D Editor", nullptr, nullptr);
|
window = glfwCreateWindow(1280, 720, "Create Editor", nullptr, nullptr);
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(0); // No VSync
|
||||||
glewInit();
|
glewInit();
|
||||||
|
|
||||||
IMGUI_CHECKVERSION();
|
IMGUI_CHECKVERSION();
|
||||||
@ -66,13 +103,137 @@ void Engine::Init()
|
|||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||||
ImGui_ImplOpenGL3_Init("#version 330");
|
ImGui_ImplOpenGL3_Init("#version 330");
|
||||||
|
m_Reserved_draws = 0;
|
||||||
|
|
||||||
Renderer::Init();
|
Renderer::Init();
|
||||||
|
|
||||||
auto obj = std::make_shared<Object>("Sprite Object");
|
auto obj = std::make_shared<Object>("Hello, Create");
|
||||||
|
|
||||||
objects.push_back(obj);
|
objects.push_back(obj);
|
||||||
selected = obj;
|
selected = obj;
|
||||||
|
Logger::LogInfo("Initialized Engine");
|
||||||
}
|
}
|
||||||
|
void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||||
|
{
|
||||||
|
ImGui::Begin("Inspector");
|
||||||
|
|
||||||
|
if (!selected)
|
||||||
|
{
|
||||||
|
ImGui::Text("No object selected.");
|
||||||
|
ImGui::End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Static buffer and last-selected tracking
|
||||||
|
static char nameBuffer[128] = "";
|
||||||
|
static std::shared_ptr<Object> lastSelected = nullptr;
|
||||||
|
|
||||||
|
// If a new object is selected, refresh buffer
|
||||||
|
if (selected != lastSelected)
|
||||||
|
{
|
||||||
|
strncpy(nameBuffer, selected->GetName().c_str(), sizeof(nameBuffer));
|
||||||
|
nameBuffer[sizeof(nameBuffer) - 1] = '\0'; // null terminate
|
||||||
|
lastSelected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::InputText("Name", nameBuffer, sizeof(nameBuffer)))
|
||||||
|
selected->SetName(nameBuffer);
|
||||||
|
|
||||||
|
glm::vec2 pos = selected->GetLocalPosition();
|
||||||
|
if (ImGui::DragFloat2("Position", &pos.x))
|
||||||
|
selected->SetLocalPosition(pos);
|
||||||
|
|
||||||
|
ImGui::InputInt("Layer", &selected->layer);
|
||||||
|
|
||||||
|
ImGui::SeparatorText("Add Components");
|
||||||
|
|
||||||
|
if (ImGui::Button("Add SpriteComponent"))
|
||||||
|
{
|
||||||
|
if (!selected->GetComponent<SpriteComponent>())
|
||||||
|
selected->AddComponent<SpriteComponent>();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Add CameraComponent"))
|
||||||
|
{
|
||||||
|
if (!selected->GetComponent<CameraComponent>())
|
||||||
|
selected->AddComponent<CameraComponent>();
|
||||||
|
}
|
||||||
|
if (ImGui::Button("Add LightComponent"))
|
||||||
|
{
|
||||||
|
if (!selected->GetComponent<LightComponent>())
|
||||||
|
selected->AddComponent<LightComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sprite UI...
|
||||||
|
if (auto sprite = selected->GetComponent<SpriteComponent>())
|
||||||
|
{
|
||||||
|
ImGui::SeparatorText("Sprite Component");
|
||||||
|
std::string tex = sprite->GetTexturePath();
|
||||||
|
std::string norm = sprite->GetNormalMapPath();
|
||||||
|
|
||||||
|
ImGui::Text("Texture: %s", tex.c_str());
|
||||||
|
if (ImGui::Button("Load Texture"))
|
||||||
|
{
|
||||||
|
auto path = OpenFileDialog(FileDialogType::Images);
|
||||||
|
if (!path.empty())
|
||||||
|
sprite->SetTexture(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Normal Map: %s", norm.c_str());
|
||||||
|
if (ImGui::Button("Load Normal Map"))
|
||||||
|
{
|
||||||
|
auto path = OpenFileDialog(FileDialogType::Images);
|
||||||
|
if (!path.empty())
|
||||||
|
sprite->SetNormalMap(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Remove SpriteComponent"))
|
||||||
|
selected->RemoveComponent<SpriteComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Camera UI...
|
||||||
|
if (auto cam = selected->GetComponent<CameraComponent>())
|
||||||
|
{
|
||||||
|
ImGui::SeparatorText("Camera Component");
|
||||||
|
|
||||||
|
float fov = cam->GetFOV();
|
||||||
|
float aspect = cam->GetAspect();
|
||||||
|
float zoom = cam->GetZoom();
|
||||||
|
|
||||||
|
if (ImGui::DragFloat("FOV", &fov, 0.1f, 1.0f, 179.0f)) cam->SetFOV(fov);
|
||||||
|
if (ImGui::DragFloat("Aspect", &aspect, 0.01f, 0.1f, 5.0f)) cam->SetAspect(aspect);
|
||||||
|
if (ImGui::DragFloat("Zoom", &zoom, 0.1f, 0.1f, 10.0f)) cam->SetZoom(zoom);
|
||||||
|
|
||||||
|
if (ImGui::Button("Remove CameraComponent"))
|
||||||
|
selected->RemoveComponent<CameraComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Light UI...
|
||||||
|
if (auto light = selected->GetComponent<LightComponent>())
|
||||||
|
{
|
||||||
|
ImGui::SeparatorText("Light Component");
|
||||||
|
|
||||||
|
glm::vec3 color = light->GetColor();
|
||||||
|
float intensity = light->GetIntensity();
|
||||||
|
float radius = light->GetRadius();
|
||||||
|
float falloff = light->GetFalloff();
|
||||||
|
int type = light->GetType();
|
||||||
|
|
||||||
|
if (ImGui::ColorEdit3("Color", &color.x)) light->SetColor(color);
|
||||||
|
if (ImGui::DragFloat("Intensity", &intensity, 0.05f, 0.0f, 10.0f)) light->SetIntensity(intensity);
|
||||||
|
if (ImGui::DragFloat("Radius", &radius, 1.0f, 10.0f, 1000.0f)) light->SetRadius(radius);
|
||||||
|
if (ImGui::DragFloat("Falloff", &falloff, 0.05f, 0.1f, 5.0f)) light->SetFalloff(falloff);
|
||||||
|
|
||||||
|
//const char* types[] = { "Point", "Directional" };
|
||||||
|
//if (ImGui::Combo("Type", &type, types, IM_ARRAYSIZE(types)))
|
||||||
|
// light->SetType(type);
|
||||||
|
|
||||||
|
if (ImGui::Button("Remove LightComponent"))
|
||||||
|
selected->RemoveComponent<LightComponent>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Engine::Run()
|
void Engine::Run()
|
||||||
{
|
{
|
||||||
@ -85,6 +246,14 @@ void Engine::Run()
|
|||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()->ID);
|
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()->ID);
|
||||||
|
|
||||||
|
float currentTime = glfwGetTime();
|
||||||
|
static float lastTime = currentTime;
|
||||||
|
float deltaTime = currentTime - lastTime;
|
||||||
|
lastTime = currentTime;
|
||||||
|
|
||||||
|
ShowDebugOverlay(deltaTime);
|
||||||
|
Logger::Draw();
|
||||||
|
|
||||||
if (ImGui::BeginMainMenuBar())
|
if (ImGui::BeginMainMenuBar())
|
||||||
{
|
{
|
||||||
if (ImGui::Button(playing ? "Stop" : "Play"))
|
if (ImGui::Button(playing ? "Stop" : "Play"))
|
||||||
@ -141,93 +310,7 @@ void Engine::Run()
|
|||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
|
||||||
ImGui::Begin("Inspector");
|
DrawInspectorUI(selected);
|
||||||
if (selected)
|
|
||||||
{
|
|
||||||
char buffer[128];
|
|
||||||
strcpy(buffer, selected->GetName().c_str());
|
|
||||||
if (ImGui::InputText("Name", buffer, sizeof(buffer)))
|
|
||||||
selected->SetName(buffer);
|
|
||||||
|
|
||||||
glm::vec2 pos = selected->GetLocalPosition();
|
|
||||||
if (ImGui::DragFloat2("Position", &pos.x))
|
|
||||||
selected->SetLocalPosition(pos);
|
|
||||||
|
|
||||||
ImGui::InputInt("Layer", &selected->layer);
|
|
||||||
|
|
||||||
// Add SpriteComponent
|
|
||||||
if (ImGui::Button("Add SpriteComponent"))
|
|
||||||
{
|
|
||||||
if (!selected->GetComponent<SpriteComponent>())
|
|
||||||
selected->AddComponent<SpriteComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add CameraComponent
|
|
||||||
if (ImGui::Button("Add CameraComponent"))
|
|
||||||
{
|
|
||||||
if (!selected->GetComponent<CameraComponent>())
|
|
||||||
selected->AddComponent<CameraComponent>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show SpriteComponent UI
|
|
||||||
if (auto sprite = selected->GetComponent<SpriteComponent>())
|
|
||||||
{
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Sprite Component");
|
|
||||||
|
|
||||||
std::string tex = sprite->GetTexturePath();
|
|
||||||
std::string norm = sprite->GetNormalMapPath();
|
|
||||||
|
|
||||||
ImGui::Text("Texture: %s", tex.c_str());
|
|
||||||
if (ImGui::Button("Load Texture"))
|
|
||||||
{
|
|
||||||
auto path = OpenFileDialog(FileDialogType::Images);
|
|
||||||
if (!path.empty())
|
|
||||||
sprite->SetTexture(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::Text("Normal Map: %s", norm.c_str());
|
|
||||||
if (ImGui::Button("Load Normal Map"))
|
|
||||||
{
|
|
||||||
auto path = OpenFileDialog(FileDialogType::Images);
|
|
||||||
if (!path.empty())
|
|
||||||
sprite->SetNormalMap(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::Button("Remove SpriteComponent"))
|
|
||||||
{
|
|
||||||
selected->RemoveComponent<SpriteComponent>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show CameraComponent UI
|
|
||||||
if (auto cam = selected->GetComponent<CameraComponent>())
|
|
||||||
{
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::Text("Camera Component");
|
|
||||||
|
|
||||||
float fov = cam->GetFOV();
|
|
||||||
float aspect = cam->GetAspect();
|
|
||||||
float zoom = cam->GetZoom();
|
|
||||||
|
|
||||||
if (ImGui::DragFloat("FOV", &fov, 0.1f, 1.0f, 179.0f))
|
|
||||||
cam->SetFOV(fov);
|
|
||||||
if (ImGui::DragFloat("Aspect", &aspect, 0.01f, 0.1f, 5.0f))
|
|
||||||
cam->SetAspect(aspect);
|
|
||||||
if (ImGui::DragFloat("Zoom", &zoom, 0.1f, 0.1f, 10.0f))
|
|
||||||
cam->SetZoom(zoom);
|
|
||||||
|
|
||||||
if (ImGui::Button("Remove CameraComponent"))
|
|
||||||
{
|
|
||||||
selected->RemoveComponent<CameraComponent>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImGui::Text("No object selected.");
|
|
||||||
}
|
|
||||||
ImGui::End();
|
|
||||||
|
|
||||||
// Viewport
|
// Viewport
|
||||||
ImGui::Begin("Viewport", nullptr, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
ImGui::Begin("Viewport", nullptr, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse);
|
||||||
@ -270,16 +353,28 @@ void Engine::Run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Renderer::Resize((int)size.x, (int)size.y);
|
Renderer::Resize((int)size.x, (int)size.y);
|
||||||
Renderer::Begin(); // assumes orthographic matrix is set up here
|
Renderer::Begin();
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Object>> toDraw;
|
std::vector<std::shared_ptr<Object>> toDraw;
|
||||||
|
|
||||||
Renderer::DrawEditorGrid(cameraPos, cameraZoom);
|
toDraw.reserve(m_Reserved_draws);
|
||||||
|
m_Reserved_draws = 0; // Reset
|
||||||
|
|
||||||
|
Renderer::DrawEditorGrid(cameraPos, cameraZoom);
|
||||||
|
|
||||||
std::function<void(const std::shared_ptr<Object> &)> collect = [&](const std::shared_ptr<Object> &obj)
|
std::function<void(const std::shared_ptr<Object> &)> collect = [&](const std::shared_ptr<Object> &obj)
|
||||||
{
|
{
|
||||||
toDraw.push_back(obj);
|
toDraw.push_back(obj);
|
||||||
|
m_Reserved_draws += 1;
|
||||||
|
|
||||||
|
if (auto light = obj->GetComponent<LightComponent>())
|
||||||
|
{
|
||||||
|
glm::vec2 world = obj->GetWorldPosition();
|
||||||
|
glm::vec2 screen = (world - cameraPos) * cameraZoom + glm::vec2(Renderer::GetSize().x * 0.5f, Renderer::GetSize().y * 0.5f);
|
||||||
|
|
||||||
|
Renderer::AddLight(screen, light->GetColor(), light->GetIntensity(), light->GetRadius() * cameraZoom);
|
||||||
|
}
|
||||||
|
|
||||||
for (const auto &child : obj->GetChildren())
|
for (const auto &child : obj->GetChildren())
|
||||||
collect(child);
|
collect(child);
|
||||||
};
|
};
|
||||||
@ -289,7 +384,11 @@ void Engine::Run()
|
|||||||
collect(obj);
|
collect(obj);
|
||||||
|
|
||||||
std::sort(toDraw.begin(), toDraw.end(), [](const auto &a, const auto &b)
|
std::sort(toDraw.begin(), toDraw.end(), [](const auto &a, const auto &b)
|
||||||
{ return a->layer < b->layer; });
|
{
|
||||||
|
if (a->layer != b->layer)
|
||||||
|
return a->layer < b->layer;
|
||||||
|
|
||||||
|
return a->GetWorldPosition().y < b->GetWorldPosition().y; });
|
||||||
|
|
||||||
for (const auto &obj : toDraw)
|
for (const auto &obj : toDraw)
|
||||||
{
|
{
|
||||||
@ -477,19 +576,19 @@ void Engine::LoadScene(const std::string &path)
|
|||||||
|
|
||||||
if (!root["engine_version"] || !root["format_version"] || !root["scene_name"])
|
if (!root["engine_version"] || !root["format_version"] || !root["scene_name"])
|
||||||
{
|
{
|
||||||
std::cerr << "[LoadScene] Missing required metadata!\n";
|
Logger::LogError("[LoadScene] Missing required metadata!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (root["engine_version"].as<std::string>() != "0.1.0")
|
if (root["engine_version"].as<std::string>() != "0.1.0")
|
||||||
{
|
{
|
||||||
std::cerr << "[LoadScene] Version mismatch! Expected 0.1.0, got " << root["engine_version"].as<std::string>() << "\n";
|
Logger::LogError("[LoadScene] Version mismatch! Expected 0.1.0, got %s", root["engine_version"].as<std::string>().c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!VerifySceneHash(root))
|
if (!VerifySceneHash(root))
|
||||||
{
|
{
|
||||||
std::cerr << "[LoadScene] Scene hash does not match! File may be corrupted or tampered.\n";
|
Logger::LogWarning("[LoadScene] Scene hash does not match! File may be corrupted or tampered.");
|
||||||
}
|
}
|
||||||
|
|
||||||
objects.clear();
|
objects.clear();
|
||||||
@ -501,7 +600,7 @@ void Engine::LoadScene(const std::string &path)
|
|||||||
objects.push_back(obj);
|
objects.push_back(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "[LoadScene] Loaded scene: " << root["scene_name"].as<std::string>() << "\n";
|
Logger::LogInfo("[LoadScene] Loaded scene: %s", root["scene_name"].as<std::string>().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Engine::Shutdown()
|
void Engine::Shutdown()
|
||||||
|
@ -20,5 +20,8 @@ private:
|
|||||||
void DrawObjectNode(const std::shared_ptr<Object>& obj); // make sure this matches Engine.cpp
|
void DrawObjectNode(const std::shared_ptr<Object>& obj); // make sure this matches Engine.cpp
|
||||||
void SaveScene(const std::string& path);
|
void SaveScene(const std::string& path);
|
||||||
void LoadScene(const std::string& path);
|
void LoadScene(const std::string& path);
|
||||||
|
void ShowDebugOverlay(float deltaTime);
|
||||||
|
|
||||||
|
|
||||||
|
int m_Reserved_draws;
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
|
||||||
#include "../Components/Component.h"
|
#include "../Components/Component.h"
|
||||||
#include "../Components/SpriteComponent.h"
|
#include "../Components/SpriteComponent.h"
|
||||||
#include "../Components/CameraComponent.h"
|
#include "../Components/CameraComponent.h"
|
||||||
|
#include "../Components/LightComponent.h"
|
||||||
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
@ -84,6 +87,9 @@ void Object::Load(const YAML::Node& node) {
|
|||||||
} else if (type == "CameraComponent") {
|
} else if (type == "CameraComponent") {
|
||||||
auto comp = AddComponent<CameraComponent>();
|
auto comp = AddComponent<CameraComponent>();
|
||||||
comp->Load(compNode);
|
comp->Load(compNode);
|
||||||
|
} else if (type == "LightComponent") {
|
||||||
|
auto comp = AddComponent<LightComponent>();
|
||||||
|
comp->Load(compNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "Renderer.h"
|
#include "Renderer.h"
|
||||||
#include "Components/SpriteComponent.h"
|
#include "Components/SpriteComponent.h"
|
||||||
#include "utils/Shader.h"
|
#include "utils/Shader.h"
|
||||||
|
#include "utils/Logging.h"
|
||||||
|
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
@ -15,6 +17,12 @@ GLuint Renderer::quadVAO = 0;
|
|||||||
GLuint Renderer::quadVBO = 0;
|
GLuint Renderer::quadVBO = 0;
|
||||||
int Renderer::width = 1280;
|
int Renderer::width = 1280;
|
||||||
int Renderer::height = 720;
|
int Renderer::height = 720;
|
||||||
|
int Renderer::s_DrawCalls = 0;
|
||||||
|
std::vector<Light> Renderer::s_Lights;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Renderer::InitQuad() {
|
void Renderer::InitQuad() {
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
@ -64,6 +72,8 @@ void Renderer::Init() {
|
|||||||
InitQuad();
|
InitQuad();
|
||||||
|
|
||||||
spriteShader.LoadFromFile("src/assets/shaders/sprite.vert", "src/assets/shaders/sprite.frag");
|
spriteShader.LoadFromFile("src/assets/shaders/sprite.vert", "src/assets/shaders/sprite.frag");
|
||||||
|
|
||||||
|
s_DrawCalls = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::Resize(int w, int h) {
|
void Renderer::Resize(int w, int h) {
|
||||||
@ -86,6 +96,8 @@ void Renderer::Begin() {
|
|||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
s_DrawCalls = 0;
|
||||||
|
ClearLights();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::End() {
|
void Renderer::End() {
|
||||||
@ -108,25 +120,66 @@ void Renderer::End() {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
void Renderer::ClearLights() {
|
||||||
|
s_Lights.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Renderer::AddLight(const glm::vec2& screenPos, const glm::vec3& color, float intensity, float radius) {
|
||||||
|
if (s_Lights.size() >= 8) return;
|
||||||
|
s_Lights.push_back({screenPos, color, intensity, radius});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Renderer::DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float zoom, glm::vec2& CameraPos) {
|
void Renderer::DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float zoom, glm::vec2& CameraPos) {
|
||||||
if (!sprite || sprite->GetTextureID() == 0) return;
|
if (!sprite->HasTexture()) {
|
||||||
|
Logger::LogWarning("Tried to draw sprite with no texture");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
spriteShader.Use();
|
spriteShader.Use();
|
||||||
|
|
||||||
glm::vec2 size = sprite->GetSize();
|
glm::vec2 size = sprite->GetSize();
|
||||||
glm::vec2 screenPos = (pos - CameraPos) * zoom + glm::vec2(size.x / 2, size.y / 2);
|
glm::vec2 screenPos = (pos - CameraPos) * zoom + glm::vec2(width, height) * 0.5f - (size * zoom * 0.5f);
|
||||||
|
|
||||||
spriteShader.SetVec2("uPos", screenPos);
|
spriteShader.SetVec2("uPos", screenPos);
|
||||||
spriteShader.SetVec2("uSize", size*zoom);
|
spriteShader.SetVec2("uSize", size * zoom);
|
||||||
spriteShader.SetVec2("uScreen", glm::vec2(width, height));
|
spriteShader.SetVec2("uScreen", glm::vec2(width, height));
|
||||||
|
|
||||||
|
spriteShader.SetInt("uLightCount", static_cast<int>(s_Lights.size()));
|
||||||
|
for (size_t i = 0; i < s_Lights.size(); ++i) {
|
||||||
|
spriteShader.SetVec2(("uLightPos[" + std::to_string(i) + "]").c_str(), s_Lights[i].screenPos);
|
||||||
|
spriteShader.SetVec3(("uLightColor[" + std::to_string(i) + "]").c_str(), s_Lights[i].color);
|
||||||
|
spriteShader.SetFloat(("uLightIntensity[" + std::to_string(i) + "]").c_str(), s_Lights[i].intensity);
|
||||||
|
spriteShader.SetFloat(("uLightRadius[" + std::to_string(i) + "]").c_str(), s_Lights[i].radius);
|
||||||
|
}
|
||||||
|
|
||||||
spriteShader.SetInt("uTex", 0);
|
spriteShader.SetInt("uTex", 0);
|
||||||
|
spriteShader.SetInt("uNormalMap", 1);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, sprite->GetTextureID());
|
glBindTexture(GL_TEXTURE_2D, sprite->GetTextureID());
|
||||||
|
|
||||||
|
if (sprite->GetNormalMapID()) {
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, sprite->GetNormalMapID());
|
||||||
|
}
|
||||||
|
|
||||||
glBindVertexArray(quadVAO);
|
glBindVertexArray(quadVAO);
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
s_DrawCalls++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Renderer::GetDrawCallCount()
|
||||||
|
{
|
||||||
|
return s_DrawCalls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
class SpriteComponent;
|
class SpriteComponent;
|
||||||
|
|
||||||
|
struct Light {
|
||||||
|
glm::vec2 screenPos;
|
||||||
|
glm::vec3 color;
|
||||||
|
float intensity;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
class Renderer {
|
class Renderer {
|
||||||
public:
|
public:
|
||||||
static void Init();
|
static void Init();
|
||||||
@ -11,14 +20,18 @@ public:
|
|||||||
static void Begin();
|
static void Begin();
|
||||||
static void End();
|
static void End();
|
||||||
static void DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float zoom, glm::vec2& CameraPos);
|
static void DrawSprite(SpriteComponent* sprite, const glm::vec2& pos, float zoom, glm::vec2& CameraPos);
|
||||||
|
static void AddLight(const glm::vec2& screenPos, const glm::vec3& color, float intensity, float radius);
|
||||||
|
static void ClearLights();
|
||||||
static void DrawEditorGrid(const glm::vec2& cameraPos, float zoom);
|
static void DrawEditorGrid(const glm::vec2& cameraPos, float zoom);
|
||||||
static GLuint GetRenderTexture();
|
static GLuint GetRenderTexture();
|
||||||
static glm::ivec2 GetSize();
|
static glm::ivec2 GetSize();
|
||||||
|
static int GetDrawCallCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static std::vector<Light> s_Lights;
|
||||||
static GLuint fbo, textureColorBuffer, rbo;
|
static GLuint fbo, textureColorBuffer, rbo;
|
||||||
static int width, height;
|
static int width, height;
|
||||||
|
static int s_DrawCalls;
|
||||||
static GLuint shader, quadVAO, quadVBO;
|
static GLuint shader, quadVAO, quadVBO;
|
||||||
static void InitQuad();
|
static void InitQuad();
|
||||||
static GLuint LoadShader(const char* vertexSrc, const char* fragmentSrc);
|
static GLuint LoadShader(const char* vertexSrc, const char* fragmentSrc);
|
||||||
|
141
src/src/utils/Logging.cpp
Normal file
141
src/src/utils/Logging.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include "Logging.h"
|
||||||
|
#include <imgui.h>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
std::vector<Logger::LogMessage> Logger::s_Messages;
|
||||||
|
bool Logger::s_AutoScroll = true;
|
||||||
|
bool Logger::s_ShowInfo = true;
|
||||||
|
bool Logger::s_ShowWarning = true;
|
||||||
|
bool Logger::s_ShowError = true;
|
||||||
|
bool Logger::s_ShowDebug = true;
|
||||||
|
|
||||||
|
const char* Logger::ToString(Level level)
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case Info: return "Info";
|
||||||
|
case Warning: return "Warning";
|
||||||
|
case Error: return "Error";
|
||||||
|
case Debug: return "Debug";
|
||||||
|
default: return "Unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Logger::GetAnsiColor(Level level)
|
||||||
|
{
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case Info: return "\033[0;37m"; // Gray
|
||||||
|
case Warning: return "\033[1;33m"; // Yellow
|
||||||
|
case Error: return "\033[1;31m"; // Red
|
||||||
|
case Debug: return "\033[1;36m"; // Cyan
|
||||||
|
default: return "\033[0m";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::Log(Level level, const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
LogVA(level, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogVA(Level level, const char* fmt, va_list args)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
|
s_Messages.push_back({ buffer, level });
|
||||||
|
|
||||||
|
std::cout << GetAnsiColor(level)
|
||||||
|
<< "[Logger][" << ToString(level) << "] "
|
||||||
|
<< buffer << "\033[0m" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Logger::LogInfo(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
LogVA(Info, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogWarning(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
LogVA(Warning, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogError(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
LogVA(Error, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::LogDebug(const char* fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args;
|
||||||
|
va_start(args, fmt);
|
||||||
|
LogVA(Debug, fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::Clear()
|
||||||
|
{
|
||||||
|
s_Messages.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Logger::Draw(const char* title)
|
||||||
|
{
|
||||||
|
ImGui::Begin(title);
|
||||||
|
|
||||||
|
if (ImGui::Button("Clear")) Clear();
|
||||||
|
ImGui::SameLine(); ImGui::Checkbox("Auto-scroll", &s_AutoScroll);
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImGui::Checkbox("Info", &s_ShowInfo); ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("Warning", &s_ShowWarning); ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("Error", &s_ShowError); ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("Debug", &s_ShowDebug);
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
ImGui::BeginChild("LogMessages");
|
||||||
|
|
||||||
|
for (const auto& msg : s_Messages)
|
||||||
|
{
|
||||||
|
if ((msg.level == Info && !s_ShowInfo) ||
|
||||||
|
(msg.level == Warning && !s_ShowWarning) ||
|
||||||
|
(msg.level == Error && !s_ShowError) ||
|
||||||
|
(msg.level == Debug && !s_ShowDebug))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec4 color;
|
||||||
|
switch (msg.level)
|
||||||
|
{
|
||||||
|
case Info: color = ImVec4(0.8f, 0.8f, 0.8f, 1.0f); break;
|
||||||
|
case Warning: color = ImVec4(1.0f, 0.85f, 0.3f, 1.0f); break;
|
||||||
|
case Error: color = ImVec4(1.0f, 0.3f, 0.3f, 1.0f); break;
|
||||||
|
case Debug: color = ImVec4(0.3f, 0.9f, 1.0f, 1.0f); break;
|
||||||
|
default: color = ImVec4(1, 1, 1, 1); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_Text, color);
|
||||||
|
ImGui::Text("[%s] %s", ToString(msg.level), msg.text.c_str());
|
||||||
|
ImGui::PopStyleColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s_AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY())
|
||||||
|
ImGui::SetScrollHereY(1.0f);
|
||||||
|
|
||||||
|
ImGui::EndChild();
|
||||||
|
ImGui::End();
|
||||||
|
}
|
43
src/src/utils/Logging.h
Normal file
43
src/src/utils/Logging.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
class Logger
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Level
|
||||||
|
{
|
||||||
|
Info,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
Debug
|
||||||
|
};
|
||||||
|
static void Log(Level level, const char* fmt, ...);
|
||||||
|
static void LogVA(Level level, const char* fmt, va_list args);
|
||||||
|
|
||||||
|
static void LogInfo(const char* fmt, ...);
|
||||||
|
static void LogWarning(const char* fmt, ...);
|
||||||
|
static void LogError(const char* fmt, ...);
|
||||||
|
static void LogDebug(const char* fmt, ...);
|
||||||
|
|
||||||
|
static void Clear();
|
||||||
|
static void Draw(const char* title = "Console");
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct LogMessage
|
||||||
|
{
|
||||||
|
std::string text;
|
||||||
|
Level level;
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::vector<LogMessage> s_Messages;
|
||||||
|
static bool s_AutoScroll;
|
||||||
|
static bool s_ShowInfo;
|
||||||
|
static bool s_ShowWarning;
|
||||||
|
static bool s_ShowError;
|
||||||
|
static bool s_ShowDebug;
|
||||||
|
|
||||||
|
static const char* ToString(Level level);
|
||||||
|
static const char* GetAnsiColor(Level level);
|
||||||
|
};
|
14
src/src/utils/utils.cpp
Normal file
14
src/src/utils/utils.cpp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
std::string GetFilenameFromPath(const std::string& path)
|
||||||
|
{
|
||||||
|
// Find the last slash or backslash
|
||||||
|
size_t lastSlash = path.find_last_of("/\\");
|
||||||
|
std::string filename = (lastSlash == std::string::npos) ? path : path.substr(lastSlash + 1);
|
||||||
|
|
||||||
|
// Strip trailing slashes (if any)
|
||||||
|
while (!filename.empty() && (filename.back() == '/' || filename.back() == '\\'))
|
||||||
|
filename.pop_back();
|
||||||
|
|
||||||
|
return filename;
|
||||||
|
}
|
4
src/src/utils/utils.h
Normal file
4
src/src/utils/utils.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
std::string GetFilenameFromPath(const std::string& path);
|
Loading…
Reference in New Issue
Block a user