mirror of
https://github.com/antopilo/Nuake.git
synced 2026-09-21 20:08:40 +03:00
Added Screen space reflections and Editor UI refactoring
This commit is contained in:
@@ -1,16 +1,21 @@
|
||||
#include <Engine.h>
|
||||
#include "src/Core/Maths.h"
|
||||
#include <src/Scene/Entities/Entity.h>
|
||||
#include <src/Core/Maths.h>
|
||||
#include "src/Core/Input.h"
|
||||
|
||||
#include <src/Scene/Scene.h>
|
||||
#include <src/Scene/Entities/Entity.h>
|
||||
#include <src/Scene/Components/Components.h>
|
||||
|
||||
#include "src/Windows/EditorInterface.h"
|
||||
|
||||
|
||||
|
||||
#include <src/Scene/Components/QuakeMap.h>
|
||||
#include <src/Vendors/imgui/imgui.h>
|
||||
#include <src/Vendors/imgui/ImGuizmo.h>
|
||||
#include <src/Scene/Components/Components.h>
|
||||
#include <src/Core/Physics/PhysicsManager.h>
|
||||
#include "src/Scene/Components/BoxCollider.h"
|
||||
#include "src/EditorInterface.h"
|
||||
#include "src/Core/Input.h"
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <src/Vendors/glm/trigonometric.hpp>
|
||||
#include <src/Scripting/ScriptingEngine.h>
|
||||
@@ -20,6 +25,7 @@
|
||||
#include "src/UI/UserInterface.h"
|
||||
#include "src/NewEditor.h"
|
||||
#include <src/Scene/Components/BSPBrushComponent.h>
|
||||
#include "src/Actions/EditorSelection.h"
|
||||
|
||||
std::string WindowTitle = "Nuake Engine";
|
||||
|
||||
@@ -38,13 +44,6 @@ void OpenProject()
|
||||
|
||||
project->FullPath = projectPath;
|
||||
Nuake::Engine::LoadProject(project);
|
||||
|
||||
// Create new interface named test.
|
||||
//userInterface = UI::UserInterface::New("test");
|
||||
|
||||
|
||||
// Set current interface running.
|
||||
//Engine::GetCurrentScene()->AddInterface(userInterface);
|
||||
}
|
||||
|
||||
std::vector<Nuake::LineVertex> vertices
|
||||
@@ -168,10 +167,10 @@ int main()
|
||||
ditherShader->SetUniform1f("u_Time", Nuake::Engine::GetTime());
|
||||
ditherShader->SetUniform4f("u_Color", 252.0 / 255.0, 3.0 / 255.0, 65.0 / 255.0, 1.0);
|
||||
|
||||
if (editor.m_IsEntitySelected && editor.m_SelectedEntity.HasComponent<Nuake::BSPBrushComponent>())
|
||||
if (editor.Selection.Type == EditorSelectionType::Entity && editor.Selection.Entity.HasComponent<Nuake::BSPBrushComponent>())
|
||||
{
|
||||
for (auto& m : editor.m_SelectedEntity.GetComponent<Nuake::BSPBrushComponent>().Meshes)
|
||||
Nuake::Renderer::SubmitMesh(m, editor.m_SelectedEntity.GetComponent<Nuake::TransformComponent>().GetGlobalTransform());
|
||||
for (auto& m : editor.Selection.Entity.GetComponent<Nuake::BSPBrushComponent>().Meshes)
|
||||
Nuake::Renderer::SubmitMesh(m, editor.Selection.Entity.GetComponent<Nuake::TransformComponent>().GetGlobalTransform());
|
||||
|
||||
Nuake::Renderer::Flush(ditherShader, true);
|
||||
}
|
||||
@@ -179,10 +178,10 @@ int main()
|
||||
ditherShader->SetUniform1f("u_Time", Nuake::Engine::GetTime() / 10.0f);
|
||||
ditherShader->SetUniform4f("u_Color", 52.f / 255.f, 235.f / 255.f, 88.f / 255.f, 1);
|
||||
auto cubeCollidersView = currentScene->m_Registry.view<Nuake::TransformComponent, Nuake::BoxColliderComponent>();
|
||||
if (editor.m_IsEntitySelected && editor.m_SelectedEntity.HasComponent<Nuake::BoxColliderComponent>())
|
||||
if (editor.Selection.Type == EditorSelectionType::Entity && editor.Selection.Entity.HasComponent<Nuake::BoxColliderComponent>())
|
||||
{
|
||||
auto transformComponent = editor.m_SelectedEntity.GetComponent<Nuake::TransformComponent>();
|
||||
auto colliderComponent = editor.m_SelectedEntity.GetComponent<Nuake::BoxColliderComponent>();
|
||||
auto transformComponent = editor.Selection.Entity.GetComponent<Nuake::TransformComponent>();
|
||||
auto colliderComponent = editor.Selection.Entity.GetComponent<Nuake::BoxColliderComponent>();
|
||||
Nuake::Matrix4 transform = transformComponent.GetGlobalTransform();
|
||||
transform = glm::scale(transform, colliderComponent.Size);
|
||||
Nuake::Renderer::SubmitCube(transform);
|
||||
@@ -194,9 +193,9 @@ int main()
|
||||
sceneFramebuffer->Unbind();
|
||||
|
||||
editor.Draw();
|
||||
|
||||
Nuake::Engine::EndDraw();
|
||||
}
|
||||
|
||||
Nuake::Engine::Close();
|
||||
}
|
||||
|
||||
}
|
||||
16
Editor/resource.h
Normal file
16
Editor/resource.h
Normal file
@@ -0,0 +1,16 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by Editor.rc
|
||||
//
|
||||
#define IDI_ICON1 101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
31
Editor/resources/Shaders/combine.shader
Normal file
31
Editor/resources/Shaders/combine.shader
Normal file
@@ -0,0 +1,31 @@
|
||||
#shader vertex
|
||||
#version 460 core
|
||||
|
||||
layout(location = 0) in vec3 VertexPosition;
|
||||
layout(location = 1) in vec2 UVPosition;
|
||||
|
||||
out flat vec2 UV;
|
||||
|
||||
void main()
|
||||
{
|
||||
UV = UVPosition;
|
||||
gl_Position = vec4(VertexPosition, 1.0f);
|
||||
}
|
||||
|
||||
#shader fragment
|
||||
#version 460 core
|
||||
|
||||
uniform sampler2D u_Source;
|
||||
uniform sampler2D u_Source2;
|
||||
|
||||
in vec2 UV;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 a = texture(u_Source, UV);
|
||||
vec4 b = texture(u_Source2, UV);
|
||||
|
||||
FragColor = vec4(vec3(a.rgb + b.rgb / 2.0), a.a * b.a);
|
||||
}
|
||||
@@ -117,25 +117,51 @@ vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
|
||||
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
|
||||
}
|
||||
|
||||
|
||||
float ShadowCalculation(Light light, vec3 FragPos, vec3 normal)
|
||||
int GetCSMDepth(float depth, Light light)
|
||||
{
|
||||
// Get Depth
|
||||
float depth = length(FragPos - u_EyePosition);
|
||||
int shadowmap = 0;
|
||||
|
||||
int shadowmap = -1;
|
||||
// Get CSM depth
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
float CSMDepth = light.CascadeDepth[i];
|
||||
|
||||
if (depth < CSMDepth + 0.0001)
|
||||
|
||||
if (depth < CSMDepth + 0.0001f)
|
||||
{
|
||||
shadowmap = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return shadowmap;
|
||||
}
|
||||
|
||||
float SampleShadowMap(sampler2D shadowMap, vec2 coords, float compare)
|
||||
{
|
||||
return step(compare, texture(shadowMap, coords.xy).r);
|
||||
}
|
||||
|
||||
float SampleShadowMapLinear(sampler2D shadowMap, vec2 coords, float compare, vec2 texelSize)
|
||||
{
|
||||
vec2 pixelPos = coords / texelSize + vec2(0.5);
|
||||
vec2 fracPart = fract(pixelPos);
|
||||
vec2 startTexel = (pixelPos - fracPart) * texelSize;
|
||||
|
||||
float blTexel = SampleShadowMap(shadowMap, startTexel, compare);
|
||||
float brTexel = SampleShadowMap(shadowMap, startTexel + vec2(texelSize.x, 0.0), compare);
|
||||
float tlTexel = SampleShadowMap(shadowMap, startTexel + vec2(0.0, texelSize.y), compare);
|
||||
float trTexel = SampleShadowMap(shadowMap, startTexel + texelSize, compare);
|
||||
|
||||
float mixA = mix(blTexel, tlTexel, fracPart.y);
|
||||
float mixB = mix(brTexel, trTexel, fracPart.y);
|
||||
|
||||
return mix(mixA, mixB, fracPart.x);
|
||||
}
|
||||
|
||||
float ShadowCalculation(Light light, vec3 FragPos, vec3 normal)
|
||||
{
|
||||
// Get Depth
|
||||
float depth = length(FragPos - u_EyePosition);
|
||||
int shadowmap = GetCSMDepth(depth, light);
|
||||
if (shadowmap == -1)
|
||||
return 1.0;
|
||||
|
||||
@@ -149,18 +175,40 @@ float ShadowCalculation(Light light, vec3 FragPos, vec3 normal)
|
||||
// get depth of current fragment from light's perspective
|
||||
float currentDepth = projCoords.z;
|
||||
// check whether current frag pos is in shadow
|
||||
float bias = max(0.005 * (1.0 - dot(normal, light.Direction)), 0.0005);
|
||||
|
||||
float shadow = 0.0;
|
||||
float bias = max(0.005 * (1.0 - dot(normal, light.Direction)), 0.0005);
|
||||
//float pcfDepth = texture(ShadowMaps[shadowmap], vec3(projCoords.xy, currentDepth), bias);
|
||||
|
||||
float pcfDepth = texture(ShadowMaps[shadowmap], projCoords.xy).r;
|
||||
return currentDepth - bias > pcfDepth ? 1.0 : 0.0;
|
||||
if (shadowmap <= 3)
|
||||
{
|
||||
const float NUM_SAMPLES = 4.f;
|
||||
const float SAMPLES_START = (NUM_SAMPLES - 1.0f) / 2.0f;
|
||||
const float NUM_SAMPLES_SQUARED = NUM_SAMPLES * NUM_SAMPLES;
|
||||
vec2 texelSize = 1.0 / vec2(2048, 2048);
|
||||
|
||||
float result = 0.0f;
|
||||
for (float y = -SAMPLES_START; y <= SAMPLES_START; y += 1.0f)
|
||||
{
|
||||
for (float x = -SAMPLES_START; x <= SAMPLES_START; x += 1.0f)
|
||||
{
|
||||
vec2 coordsOffset = vec2(x, y) * texelSize;
|
||||
result += SampleShadowMapLinear(ShadowMaps[shadowmap], projCoords.xy + coordsOffset, currentDepth - bias, texelSize);
|
||||
}
|
||||
}
|
||||
|
||||
return result / NUM_SAMPLES_SQUARED;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return SampleShadowMap(ShadowMaps[shadowmap], projCoords.xy, currentDepth - bias);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 worldPos = WorldPosFromDepth(texture(m_Depth, UV).r);
|
||||
|
||||
if (texture(m_Depth, UV).r == 1)
|
||||
{
|
||||
FragColor = vec4(0, 0, 0, 0);
|
||||
@@ -202,7 +250,7 @@ void main()
|
||||
vec3 radiance = Lights[i].Color * attenuation ;
|
||||
|
||||
if (Lights[i].Type == 0) {
|
||||
radiance *= 1.0f - shadow;
|
||||
radiance *= shadow;
|
||||
}
|
||||
|
||||
// Cook-Torrance BRDF
|
||||
@@ -235,5 +283,18 @@ void main()
|
||||
vec3 ambient = (kD * albedo) * ao;
|
||||
vec3 color = ambient + Lo;
|
||||
|
||||
// Display CSM splits..
|
||||
/*float depth = length(worldPos - u_EyePosition);
|
||||
int cascade = GetCSMDepth(depth, Lights[0]);
|
||||
if (cascade == 0)
|
||||
color *= vec3(1.0, 0.0, 0.0);
|
||||
if (cascade == 1)
|
||||
color *= vec3(0.0, 1.0, 0.0);
|
||||
if (cascade == 2)
|
||||
color *= vec3(0.0, 0.0, 1.0);
|
||||
if (cascade == 3)
|
||||
color *= vec3(0.0, 1.0, 1.0);
|
||||
*/
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -25,7 +25,6 @@ void main()
|
||||
discard;
|
||||
|
||||
vec4 finalColor = u_Color;
|
||||
finalColor.a = (sin(u_Time * 4.0) + 1.0) / 4.0 + 0.1;
|
||||
FragColor = finalColor;
|
||||
|
||||
}
|
||||
@@ -17,8 +17,15 @@ out vec2 UV;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 N = normalize((u_Model * vec4(Normal, 0.0f)).xyz);
|
||||
//mat3 normalMatrix = transpose(inverse(mat3(u_Model)));
|
||||
//vec3 T = normalize(normalMatrix * Tangent);
|
||||
//vec3 N = normalize(normalMatrix * Normal);
|
||||
//T = normalize(T - dot(T, N) * N);
|
||||
//vec3 B = cross(N, T);
|
||||
|
||||
|
||||
vec3 T = normalize((u_Model * vec4(Tangent, 0.0f)).xyz);
|
||||
vec3 N = normalize((u_Model * vec4(Normal, 0.0f)).xyz);
|
||||
vec3 B = normalize((u_Model * vec4(Bitangent, 0.0f)).xyz);
|
||||
TBN = mat3(T, B, N);
|
||||
|
||||
@@ -68,10 +75,8 @@ void main()
|
||||
if (u_HasNormal == 1)
|
||||
normal = texture(m_Normal, UV).rgb;
|
||||
normal = normal * 2.0 - 1.0;
|
||||
|
||||
normal = TBN * normalize(normal);
|
||||
|
||||
gNormal = vec4(normal, 1.0) / 2.0 + 0.5;
|
||||
gNormal = vec4(normal / 2.0 + 0.5, 1.0);
|
||||
|
||||
// Albedo
|
||||
gAlbedo = vec4(m_AlbedoColor, 1.0);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#shader vertex
|
||||
#version 460 core
|
||||
|
||||
layout(location = 0) in vec3 VertexPosition;
|
||||
layout(location = 1) in vec2 UVPosition;
|
||||
layout(location = 2) in vec3 Normal;
|
||||
|
||||
189
Editor/resources/Shaders/ssr.shader
Normal file
189
Editor/resources/Shaders/ssr.shader
Normal file
@@ -0,0 +1,189 @@
|
||||
#shader vertex
|
||||
#version 460 core
|
||||
|
||||
layout(location = 0) in vec3 VertexPosition;
|
||||
layout(location = 1) in vec2 UVPosition;
|
||||
|
||||
out flat vec2 UV;
|
||||
|
||||
void main()
|
||||
{
|
||||
UV = UVPosition;
|
||||
gl_Position = vec4(VertexPosition, 1.0f);
|
||||
}
|
||||
|
||||
#shader fragment
|
||||
#version 420 core
|
||||
|
||||
in vec2 UV;
|
||||
out vec4 outColor;
|
||||
|
||||
uniform sampler2D textureFrame;
|
||||
uniform sampler2D textureDepth;
|
||||
uniform sampler2D textureNorm;
|
||||
uniform sampler2D textureMetallic;
|
||||
uniform sampler2D textureAlbedo;
|
||||
|
||||
uniform mat4 proj;
|
||||
uniform mat4 invProj;
|
||||
uniform mat4 view;
|
||||
uniform mat4 invView;
|
||||
|
||||
uniform float rayStep = 0.2f;
|
||||
uniform int iterationCount = 100;
|
||||
uniform float distanceBias = 0.05f;
|
||||
uniform bool enableSSR = true;
|
||||
uniform int sampleCount = 4;
|
||||
uniform bool isSamplingEnabled = true;
|
||||
uniform bool isExponentialStepEnabled = false;
|
||||
uniform bool isAdaptiveStepEnabled = true;
|
||||
uniform bool isBinarySearchEnabled = true;
|
||||
uniform bool debugDraw = false;
|
||||
uniform float samplingCoefficient = 0.001f;
|
||||
|
||||
vec3 ReflectedVector;
|
||||
float Metallic;
|
||||
const float reflectionSpecularFalloffExponent = 3.0;
|
||||
float random(vec2 uv) {
|
||||
return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453123); //simple random function
|
||||
}
|
||||
|
||||
vec3 generatePositionFromDepth(vec2 texturePos, float depth) {
|
||||
vec4 ndc = vec4((texturePos - 0.5) * 2, depth, 1.f);
|
||||
vec4 inversed = invProj * ndc;// going back from projected
|
||||
inversed /= inversed.w;
|
||||
return inversed.xyz;
|
||||
}
|
||||
|
||||
vec2 generateProjectedPosition(vec3 pos) {
|
||||
vec4 samplePosition = proj * vec4(pos, 1.f);
|
||||
samplePosition.xy = (samplePosition.xy / samplePosition.w) * 0.5 + 0.5;
|
||||
return samplePosition.xy;
|
||||
}
|
||||
|
||||
vec3 SSR(vec3 position, vec3 reflection) {
|
||||
vec3 step = rayStep * reflection;
|
||||
vec3 marchingPosition = position + step;
|
||||
float delta;
|
||||
float depthFromScreen;
|
||||
vec2 screenPosition;
|
||||
|
||||
int i = 0;
|
||||
for (; i < iterationCount; i++) {
|
||||
screenPosition = generateProjectedPosition(marchingPosition);
|
||||
depthFromScreen = abs(generatePositionFromDepth(screenPosition, textureLod(textureDepth, screenPosition, 2).x).z);
|
||||
delta = abs(marchingPosition.z) - depthFromScreen;
|
||||
|
||||
float depth = textureLod(textureDepth, screenPosition, 2).r;
|
||||
|
||||
if (abs(delta) < distanceBias || depthFromScreen > 1000.0f) {
|
||||
vec3 color = vec3(1);
|
||||
if (debugDraw)
|
||||
color = vec3(0.5 + sign(delta) / 2, 0.3, 0.5 - sign(delta) / 2);
|
||||
vec2 dCoords = smoothstep(0.2, 0.6, abs(vec2(0.5, 0.5) - screenPosition.xy));
|
||||
float screenEdgefactor = clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0);
|
||||
float ReflectionMultiplier = pow(Metallic, 3.0) *
|
||||
screenEdgefactor *
|
||||
-ReflectedVector.z;
|
||||
|
||||
return texture(textureFrame, screenPosition).xyz * color * clamp(ReflectionMultiplier, 0.0, 0.9);
|
||||
}
|
||||
if (isBinarySearchEnabled && delta > 0) {
|
||||
break;
|
||||
}
|
||||
if (isAdaptiveStepEnabled) {
|
||||
float directionSign = sign(abs(marchingPosition.z) - depthFromScreen);
|
||||
//this is sort of adapting step, should prevent lining reflection by doing sort of iterative converging
|
||||
//some implementation doing it by binary search, but I found this idea more cheaty and way easier to implement
|
||||
step = step * (1.0 - rayStep * max(directionSign, 0.0));
|
||||
marchingPosition += step * (-directionSign);
|
||||
}
|
||||
else {
|
||||
marchingPosition += step;
|
||||
}
|
||||
if (isExponentialStepEnabled) {
|
||||
step *= 1.05;
|
||||
}
|
||||
}
|
||||
if (isBinarySearchEnabled) {
|
||||
for (; i < iterationCount; i++) {
|
||||
|
||||
step *= 0.5;
|
||||
marchingPosition = marchingPosition - step * sign(delta);
|
||||
|
||||
screenPosition = generateProjectedPosition(marchingPosition);
|
||||
depthFromScreen = abs(generatePositionFromDepth(screenPosition, textureLod(textureDepth, screenPosition, 2).x).z);
|
||||
delta = abs(marchingPosition.z) - depthFromScreen;
|
||||
|
||||
vec2 dCoords = smoothstep(0.2, 0.6, abs(vec2(0.5, 0.5) - screenPosition.xy));
|
||||
float screenEdgefactor = clamp(1.0 - (dCoords.x + dCoords.y), 0.0, 1.0);
|
||||
float ReflectionMultiplier = pow(Metallic, 3.0) * screenEdgefactor *
|
||||
-ReflectedVector.z;
|
||||
|
||||
if (abs(delta) < distanceBias) {
|
||||
return texture(textureFrame, screenPosition).xyz * clamp(ReflectionMultiplier, 0.0, 0.9);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vec3(0.0);
|
||||
}
|
||||
|
||||
vec3 fresnelSchlick(float cosTheta, vec3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 position = generatePositionFromDepth(UV, textureLod(textureDepth, UV, 2).x);
|
||||
vec4 normal = view * vec4(texture(textureNorm, UV).xyz * 2.0 - 1.0, 0.0);
|
||||
|
||||
float metallic = texture(textureMetallic, UV).r;
|
||||
Metallic = metallic;
|
||||
vec3 albedo = texture(textureAlbedo, UV).rgb;
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
vec3 Fresnel = fresnelSchlick(max(dot(normalize(normal.rgb), normalize(position)), 0.0), F0);
|
||||
|
||||
if (!enableSSR || metallic < 0.01) {
|
||||
discard;// outColor = mix(texture(textureFrame, UV), normal, 0.9);
|
||||
}
|
||||
else {
|
||||
vec3 reflectionDirection = normalize(reflect(position, normalize(normal.xyz)));
|
||||
|
||||
ReflectedVector = reflectionDirection;
|
||||
if (isSamplingEnabled) {
|
||||
vec3 firstBasis = normalize(cross(vec3(0.f, 0.f, 1.f), reflectionDirection));
|
||||
vec3 secondBasis = normalize(cross(reflectionDirection, firstBasis));
|
||||
vec4 resultingColor = vec4(0.f);
|
||||
for (int i = 0; i < sampleCount; i++) {
|
||||
vec2 coeffs = vec2(random(UV + vec2(0, i)) + random(UV + vec2(i, 0))) * samplingCoefficient;
|
||||
vec3 reflectionDirectionRandomized = reflectionDirection + firstBasis * coeffs.x + secondBasis * coeffs.y;
|
||||
vec3 tempColor = SSR(position, normalize(reflectionDirectionRandomized));
|
||||
|
||||
if(tempColor != vec3(0))
|
||||
resultingColor += vec4(tempColor, 1.0f);
|
||||
}
|
||||
|
||||
if(resultingColor.w != 0)
|
||||
resultingColor /= resultingColor.w;
|
||||
|
||||
if (resultingColor.xyz == vec3(0.0f))
|
||||
{
|
||||
outColor = vec4(1, 0, 0, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
outColor = vec4(resultingColor.xyz * Fresnel, metallic) ;
|
||||
|
||||
}
|
||||
else {
|
||||
outColor = vec4(SSR(position, normalize(reflectionDirection)) * Fresnel, metallic);
|
||||
if (outColor.xyz == vec3(0.f)) {
|
||||
outColor = texture(textureFrame, UV);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,11 +37,12 @@ struct Light {
|
||||
mat4 transform;
|
||||
vec3 color;
|
||||
vec3 direction;
|
||||
sampler2D shadowmap;
|
||||
int shadowmap;
|
||||
};
|
||||
|
||||
uniform Light u_Lights[MAX_LIGHT];
|
||||
|
||||
uniform sampler2D lightShadowmap;
|
||||
in vec2 UV;
|
||||
|
||||
out vec4 FragColor;
|
||||
@@ -57,7 +58,8 @@ float ComputeScattering(float lightDotView)
|
||||
|
||||
vec3 ComputeVolumetric(vec3 FragPos, Light light)
|
||||
{
|
||||
vec3 rayVector = FragPos - u_CamPosition; // Ray Direction
|
||||
vec3 startPosition = u_CamPosition; // Camera Position
|
||||
vec3 rayVector = FragPos - startPosition; // Ray Direction
|
||||
|
||||
float rayLength = length(rayVector); // Length of the raymarched
|
||||
|
||||
@@ -68,7 +70,7 @@ vec3 ComputeVolumetric(vec3 FragPos, Light light)
|
||||
vec3 accumFog = vec3(0.0f, 0.0f, 0.0f); // accumulative color
|
||||
|
||||
// Raymarching
|
||||
vec3 currentPosition = u_CamPosition;
|
||||
vec3 currentPosition = startPosition;
|
||||
for (int i = 0; i < u_StepCount; i++)
|
||||
{
|
||||
vec4 fragPosLightSpace = light.transform * vec4(currentPosition, 1.0f);
|
||||
@@ -78,7 +80,7 @@ vec3 ComputeVolumetric(vec3 FragPos, Light light)
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
float currentDepth = projCoords.z;
|
||||
float closestDepth = texture(light.shadowmap, projCoords.xy).r;
|
||||
float closestDepth = texture(lightShadowmap, projCoords.xy).r;
|
||||
if (closestDepth > currentDepth)
|
||||
accumFog += (ComputeScattering(dot(rayDirection, normalize(light.direction))).xxx * light.color);
|
||||
|
||||
@@ -110,11 +112,10 @@ void main()
|
||||
vec3 globalFragmentPosition = WorldPosFromDepth(depth);
|
||||
|
||||
vec3 fog = vec3(0, 0, 0);
|
||||
|
||||
for (int i = 0; i < u_LightCount; i++)
|
||||
{
|
||||
fog += ComputeVolumetric(globalFragmentPosition, u_Lights[i]);
|
||||
}
|
||||
|
||||
FragColor = vec4(mix(fog, vec3(depth), 0.01), 1.0);
|
||||
|
||||
FragColor = vec4(mix(fog, ComputeVolumetric(globalFragmentPosition, u_Lights[0]), 0.9f), 1.0);
|
||||
}
|
||||
49
Editor/src/Actions/EditorSelection.h
Normal file
49
Editor/src/Actions/EditorSelection.h
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
#include "src/Core/Core.h"
|
||||
#include "src/Scene/Entities/Entity.h"
|
||||
#include "src/Resource/Resource.h"
|
||||
|
||||
enum EditorSelectionType {
|
||||
None,
|
||||
Entity,
|
||||
File,
|
||||
Resource,
|
||||
};
|
||||
|
||||
class EditorSelection {
|
||||
public:
|
||||
|
||||
EditorSelectionType Type = EditorSelectionType::None;
|
||||
|
||||
Nuake::Entity Entity;
|
||||
Ref<Nuake::File> File;
|
||||
Nuake::Resource Resource;
|
||||
|
||||
EditorSelection()
|
||||
{
|
||||
Type = None;
|
||||
}
|
||||
|
||||
EditorSelection(const Nuake::Entity& entity)
|
||||
{
|
||||
Type = EditorSelectionType::Entity;
|
||||
Entity = entity;
|
||||
}
|
||||
|
||||
EditorSelection(const Ref<Nuake::File>& file)
|
||||
{
|
||||
Type = EditorSelectionType::File;
|
||||
File = file;
|
||||
}
|
||||
|
||||
EditorSelection(const Nuake::Resource& resource)
|
||||
{
|
||||
Type = EditorSelectionType::Resource;
|
||||
Resource = resource;
|
||||
}
|
||||
|
||||
operator bool()
|
||||
{
|
||||
return Type != None;
|
||||
}
|
||||
};
|
||||
89
Editor/src/ComponentsPanel/ComponentPanel.h
Normal file
89
Editor/src/ComponentsPanel/ComponentPanel.h
Normal file
@@ -0,0 +1,89 @@
|
||||
#pragma once
|
||||
#include "src/Scene/Entities/Entity.h"
|
||||
|
||||
#include "../Misc/InterfaceFonts.h"
|
||||
|
||||
#include <src/Vendors/imgui/imgui.h>
|
||||
#include <src/Resource/FontAwesome5.h>
|
||||
|
||||
|
||||
#define MenuItemComponent(label, Component) \
|
||||
if(entity.HasComponent<Component>()) \
|
||||
ImGui::Text(label); \
|
||||
else if (ImGui::MenuItem(label)) \
|
||||
entity.AddComponent<Component>();
|
||||
|
||||
|
||||
#define BeginComponentTable(name, component) \
|
||||
UIFont* boldFont = new UIFont(Fonts::Bold); \
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.f, 0.f)); \
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.f, 8.f)); \
|
||||
bool removed = false; \
|
||||
bool headerOpened = ImGui::CollapsingHeader(#name, ImGuiTreeNodeFlags_DefaultOpen); \
|
||||
if (#name != "TRANSFORM" && ImGui::BeginPopupContextItem()) \
|
||||
{ \
|
||||
if (ImGui::Selectable("Remove")) { removed = true; } \
|
||||
ImGui::EndPopup(); \
|
||||
} \
|
||||
\
|
||||
if(removed) \
|
||||
{ \
|
||||
entity.RemoveComponent<component>(); \
|
||||
ImGui::PopStyleVar(); \
|
||||
delete boldFont; \
|
||||
} \
|
||||
else if (headerOpened) \
|
||||
{ \
|
||||
delete boldFont; \
|
||||
ImGui::PopStyleVar(); \
|
||||
if (ImGui::BeginTable(#name, 3, ImGuiTableFlags_BordersInner)) \
|
||||
{ \
|
||||
ImGui::TableSetupColumn("name", 0, 0.3f); \
|
||||
ImGui::TableSetupColumn("set", 0, 0.6f); \
|
||||
ImGui::TableSetupColumn("reset", 0, 0.1f); \
|
||||
\
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
|
||||
#define EndComponentTable() \
|
||||
ImGui::EndTable(); \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
ImGui::PopStyleVar(); \
|
||||
delete boldFont; \
|
||||
} \
|
||||
ImGui::PopStyleVar();
|
||||
|
||||
|
||||
#define ComponentTableReset(setting, value) \
|
||||
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0)); \
|
||||
std::string resetLabel = std::string(ICON_FA_UNDO) + "##Reset" + #setting; \
|
||||
if (ImGui::Button(resetLabel.c_str())) setting = value; \
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
|
||||
#define ComponentDropDown(arrayData, enumData, value) \
|
||||
const char* current_item = arrayData[(int)value]; \
|
||||
if (ImGui::BeginCombo("Type", current_item)) \
|
||||
{ \
|
||||
for (int n = 0; n < IM_ARRAYSIZE(arrayData); n++) \
|
||||
{ \
|
||||
bool is_selected = (current_item == arrayData[n]); \
|
||||
if (ImGui::Selectable(arrayData[n], is_selected)) \
|
||||
{ \
|
||||
current_item = arrayData[n]; \
|
||||
value = (enumData)n; \
|
||||
} \
|
||||
if (is_selected) \
|
||||
ImGui::SetItemDefaultFocus(); \
|
||||
} \
|
||||
ImGui::EndCombo(); \
|
||||
}
|
||||
|
||||
|
||||
class ComponentPanel {
|
||||
public:
|
||||
virtual void Draw(Nuake::Entity entity) = 0;
|
||||
};
|
||||
106
Editor/src/ComponentsPanel/LightPanel.h
Normal file
106
Editor/src/ComponentsPanel/LightPanel.h
Normal file
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
#include "ComponentPanel.h"
|
||||
#include "src/Scene/Components/LightComponent.h"
|
||||
|
||||
class LightPanel :ComponentPanel {
|
||||
|
||||
public:
|
||||
LightPanel() { }
|
||||
|
||||
void Draw(Nuake::Entity entity) override
|
||||
{
|
||||
if (!entity.HasComponent<Nuake::LightComponent>())
|
||||
return;
|
||||
|
||||
Nuake::LightComponent& component = entity.GetComponent<Nuake::LightComponent>();
|
||||
|
||||
BeginComponentTable(LIGHT, Nuake::LightComponent);
|
||||
{
|
||||
{
|
||||
ImGui::Text("Color");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth());
|
||||
ImGui::ColorEdit3("##lightcolor", &component.Color.r, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel);
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.Color, Nuake::Vector3(1, 1, 1));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Strength");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SliderFloat("Strength", &component.Strength, 0.0f, 100.0f);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.Strength, 10.f);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Cast Shadows");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Using the SetCastShadows allows to create Framebuffers.
|
||||
bool castShadows = component.CastShadows;
|
||||
ImGui::Checkbox("##CastShadows", &castShadows);
|
||||
if (castShadows != component.CastShadows)
|
||||
component.SetCastShadows(castShadows);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.CastShadows, false);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Type");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
const char* lightTypes[] = { "Directional", "Point", "Spot" };
|
||||
ComponentDropDown(lightTypes, Nuake::LightType, component.Type)
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.Type, Nuake::LightType::Point);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
if (component.Type == Nuake::LightType::Directional)
|
||||
{
|
||||
{
|
||||
ImGui::Text("Is Volumetric");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("##Volumetric", &component.IsVolumetric);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.IsVolumetric, false);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Sync Direction with sky");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("##SyncSky", &component.SyncDirectionWithSky);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.SyncDirectionWithSky, false);
|
||||
|
||||
// Light direction is only useful if it is not overriden by the procedural sky direction
|
||||
if (!component.SyncDirectionWithSky)
|
||||
{
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Direction");
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiHelper::DrawVec3("Direction", &component.Direction);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.Direction, Nuake::Vector3(0, -1, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EndComponentTable();
|
||||
}
|
||||
};
|
||||
43
Editor/src/ComponentsPanel/MeshPanel.h
Normal file
43
Editor/src/ComponentsPanel/MeshPanel.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "ComponentPanel.h"
|
||||
#include <src/Scene/Entities/ImGuiHelper.h>
|
||||
#include <src/Scene/Components/MeshComponent.h>
|
||||
|
||||
class MeshPanel : ComponentPanel {
|
||||
|
||||
public:
|
||||
MeshPanel() {}
|
||||
|
||||
void Draw(Nuake::Entity entity) override
|
||||
{
|
||||
if (!entity.HasComponent<Nuake::MeshComponent>())
|
||||
return;
|
||||
|
||||
Nuake::MeshComponent& component = entity.GetComponent<Nuake::MeshComponent>();
|
||||
BeginComponentTable(MESH, Nuake::MeshComponent);
|
||||
{
|
||||
ImGui::Text("Mesh");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
std::string path = component.ModelPath;
|
||||
ImGui::Button(component.ModelPath.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Model"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
path = Nuake::FileSystem::AbsoluteToRelative(fullPath);
|
||||
|
||||
component.ModelPath = path;
|
||||
component.LoadModel();
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.ModelPath, "");
|
||||
}
|
||||
EndComponentTable();
|
||||
}
|
||||
};
|
||||
70
Editor/src/ComponentsPanel/QuakeMapPanel.h
Normal file
70
Editor/src/ComponentsPanel/QuakeMapPanel.h
Normal file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#include "ComponentPanel.h"
|
||||
#include <src/Scene/Components/QuakeMap.h>
|
||||
#include "src/Scene/Systems/QuakeMapBuilder.h"
|
||||
#include <src/Core/FileSystem.h>
|
||||
|
||||
class QuakeMapPanel : ComponentPanel {
|
||||
|
||||
public:
|
||||
QuakeMapPanel() {}
|
||||
|
||||
void Draw(Nuake::Entity entity) override
|
||||
{
|
||||
if (!entity.HasComponent<Nuake::QuakeMapComponent>())
|
||||
return;
|
||||
|
||||
Nuake::QuakeMapComponent& component = entity.GetComponent<Nuake::QuakeMapComponent>();
|
||||
BeginComponentTable(QUAKEMAP, Nuake::QuakeMapComponent);
|
||||
{
|
||||
{
|
||||
ImGui::Text("Map");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
std::string path = component.Path;
|
||||
ImGui::Button(component.Path.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Map"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
path = Nuake::FileSystem::AbsoluteToRelative(fullPath);
|
||||
|
||||
component.Path = path;
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ComponentTableReset(component.Path, "");
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Collision");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Checkbox("#Collison", &component.HasCollisions);
|
||||
ImGui::TableNextColumn();
|
||||
ComponentTableReset(component.HasCollisions, true);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Build");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (ImGui::Button("Build"))
|
||||
{
|
||||
Nuake::QuakeMapBuilder builder;
|
||||
builder.BuildQuakeMap(entity, component.HasCollisions);
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
//ComponentTableReset(component.Class, "");
|
||||
}
|
||||
}
|
||||
EndComponentTable();
|
||||
}
|
||||
};
|
||||
65
Editor/src/ComponentsPanel/ScriptPanel.h
Normal file
65
Editor/src/ComponentsPanel/ScriptPanel.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
#include "ComponentPanel.h"
|
||||
#include <src/Scene/Components/WrenScriptComponent.h>
|
||||
#include <src/Core/FileSystem.h>
|
||||
|
||||
class ScriptPanel : ComponentPanel {
|
||||
|
||||
public:
|
||||
ScriptPanel() {}
|
||||
|
||||
void Draw(Nuake::Entity entity) override
|
||||
{
|
||||
if (!entity.HasComponent<Nuake::WrenScriptComponent>())
|
||||
return;
|
||||
|
||||
Nuake::WrenScriptComponent& component = entity.GetComponent<Nuake::WrenScriptComponent>();
|
||||
BeginComponentTable(SCRIPT, Nuake::WrenScriptComponent);
|
||||
{
|
||||
{
|
||||
ImGui::Text("Script");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
std::string path = component.Script;
|
||||
ImGui::Button(component.Script.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
path = Nuake::FileSystem::AbsoluteToRelative(fullPath);
|
||||
|
||||
Ref<Nuake::File> nuakeFile = Nuake::FileSystem::GetFile(path);
|
||||
component.mWrenScript = CreateRef<Nuake::WrenScript>(nuakeFile, true);
|
||||
auto& modules = component.mWrenScript->GetModules();
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
component.Script = path;
|
||||
|
||||
|
||||
//
|
||||
//ImGuiHelper::DrawVec3("Translation", &component.Translation);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ComponentTableReset(component.Script, "");
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Module");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
// Todo: Automatically parse available modules. and offer a dropdown
|
||||
//ImGuiHelper::DrawVec3("Rotation", &component.Rotation);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
|
||||
|
||||
//ComponentTableReset(component.Class, "");
|
||||
}
|
||||
}
|
||||
EndComponentTable();
|
||||
}
|
||||
};
|
||||
48
Editor/src/ComponentsPanel/TransformPanel.h
Normal file
48
Editor/src/ComponentsPanel/TransformPanel.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
#include "ComponentPanel.h"
|
||||
#include <src/Scene/Entities/ImGuiHelper.h>
|
||||
#include <src/Scene/Components/TransformComponent.h>
|
||||
|
||||
class TransformPanel : ComponentPanel {
|
||||
|
||||
public:
|
||||
TransformPanel() {}
|
||||
|
||||
void Draw(Nuake::Entity entity) override
|
||||
{
|
||||
Nuake::TransformComponent& component = entity.GetComponent<Nuake::TransformComponent>();
|
||||
BeginComponentTable(TRANSFORM, Nuake::TransformComponent);
|
||||
{
|
||||
{
|
||||
ImGui::Text("Translation");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiHelper::DrawVec3("Translation", &component.Translation);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ComponentTableReset(component.Translation, Nuake::Vector3(0, 0, 0));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Rotation");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiHelper::DrawVec3("Rotation", &component.Rotation);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ComponentTableReset(component.Rotation, Nuake::Vector3(0, 0, 0));
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
{
|
||||
ImGui::Text("Scale");
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiHelper::DrawVec3("Scale", &component.Scale);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ComponentTableReset(component.Scale, Nuake::Vector3(1, 1, 1));
|
||||
}
|
||||
}
|
||||
EndComponentTable();
|
||||
}
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
class GizmoDrawer
|
||||
{
|
||||
void Draw();
|
||||
|
||||
|
||||
};
|
||||
@@ -1,9 +1,7 @@
|
||||
#pragma once
|
||||
#include <vcruntime_string.h>
|
||||
#include <string>
|
||||
#include <src/Vendors/imgui/imgui.h>
|
||||
|
||||
|
||||
void ImGuiTextSTD(const std::string& label, std::string& value)
|
||||
{
|
||||
char buffer[256];
|
||||
38
Editor/src/Misc/InterfaceFonts.cpp
Normal file
38
Editor/src/Misc/InterfaceFonts.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include "InterfaceFonts.h"
|
||||
#include <src/Vendors/imgui/imgui.h>
|
||||
#include <src/Resource/FontAwesome5.h>
|
||||
|
||||
std::map<Fonts, ImFont*> FontManager::mFonts = std::map<Fonts, ImFont*>();
|
||||
|
||||
void FontManager::LoadFonts()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
static const ImWchar icons_ranges[] = { ICON_MIN_FA, ICON_MAX_FA, 0 };
|
||||
ImFontConfig icons_config; icons_config.MergeMode = true; icons_config.PixelSnapH = true;
|
||||
|
||||
mFonts[Normal] = io.Fonts->AddFontFromFileTTF("resources/Fonts/fa-solid-900.ttf", 11.0f, &icons_config, icons_ranges);
|
||||
mFonts[Bold] = io.Fonts->AddFontFromFileTTF("resources/Fonts/OpenSans-Bold.ttf", 16.0);
|
||||
mFonts[LargeBold] = io.Fonts->AddFontFromFileTTF("resources/Fonts/OpenSans-Regular.ttf", 32);
|
||||
mFonts[Title] = io.Fonts->AddFontFromFileTTF("resources/Fonts/OpenSans-Bold.ttf", 50.0);
|
||||
mFonts[SubTitle] = io.Fonts->AddFontFromFileTTF("resources/Fonts/OpenSans-Regular.ttf", 24.0);
|
||||
ImGui::GetIO().Fonts->AddFontDefault();
|
||||
icons_config.MergeMode = true;
|
||||
mFonts[BigIcon] = io.Fonts->AddFontFromFileTTF("resources/Fonts/fa-solid-900.ttf", 42.0f, &icons_config, icons_ranges);
|
||||
}
|
||||
|
||||
ImFont* FontManager::GetFont(Fonts font)
|
||||
{
|
||||
return mFonts[font];
|
||||
}
|
||||
|
||||
UIFont::UIFont(Fonts font)
|
||||
{
|
||||
ImGuiFont = FontManager::GetFont(font);
|
||||
ImGui::PushFont(ImGuiFont);
|
||||
}
|
||||
|
||||
UIFont::~UIFont()
|
||||
{
|
||||
ImGui::PopFont();
|
||||
}
|
||||
28
Editor/src/Misc/InterfaceFonts.h
Normal file
28
Editor/src/Misc/InterfaceFonts.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
enum Fonts {
|
||||
Normal, Bold, LargeBold, Icons, BigIcon, Title, SubTitle
|
||||
};
|
||||
|
||||
class ImFont;
|
||||
|
||||
// Help class that automatically push and pops itself when
|
||||
// Reaching end of scope
|
||||
class UIFont {
|
||||
private:
|
||||
ImFont* ImGuiFont;
|
||||
public:
|
||||
UIFont(Fonts font);
|
||||
~UIFont();
|
||||
};
|
||||
|
||||
class FontManager {
|
||||
private:
|
||||
static std::map < Fonts, ImFont*> mFonts;
|
||||
|
||||
public:
|
||||
static void LoadFonts();
|
||||
static ImFont* GetFont(Fonts font);
|
||||
};
|
||||
@@ -1 +0,0 @@
|
||||
#pragma once
|
||||
@@ -1 +0,0 @@
|
||||
#pragma once
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,18 +3,20 @@
|
||||
#include "src/Vendors/imgui/imgui.h"
|
||||
#include <src/Vendors/imgui/ImGuizmo.h>
|
||||
#include "src/Core/FileSystem.h"
|
||||
#include "FileSystemUI.h"
|
||||
|
||||
|
||||
#include "../Actions/EditorSelection.h"
|
||||
#include "EditorSelectionPanel.h"
|
||||
|
||||
namespace Nuake {
|
||||
class Material;
|
||||
class FileSystemUI;
|
||||
class EditorInterface
|
||||
{
|
||||
private:
|
||||
FileSystemUI filesystem = FileSystemUI();
|
||||
FileSystemUI* filesystem;
|
||||
|
||||
|
||||
|
||||
bool m_DrawGrid = false;
|
||||
bool m_ShowImGuiDemo = false;
|
||||
bool m_DebugCollisions = false;
|
||||
@@ -27,8 +29,11 @@ namespace Nuake {
|
||||
bool m_IsMaterialSelected = false;
|
||||
|
||||
public:
|
||||
bool m_IsEntitySelected = false;
|
||||
Entity m_SelectedEntity;
|
||||
EditorSelection Selection;
|
||||
EditorSelectionPanel SelectionPanel;
|
||||
|
||||
EditorInterface();
|
||||
|
||||
static ImFont* bigIconFont;
|
||||
void BuildFonts();
|
||||
void Init();
|
||||
357
Editor/src/Windows/EditorSelectionPanel.cpp
Normal file
357
Editor/src/Windows/EditorSelectionPanel.cpp
Normal file
@@ -0,0 +1,357 @@
|
||||
#include "EditorSelectionPanel.h"
|
||||
#include "src/Scene/Components/ImportComponents.h"
|
||||
#include "../Misc/ImGuiTextHelper.h"
|
||||
|
||||
EditorSelectionPanel::EditorSelectionPanel()
|
||||
{
|
||||
mTransformPanel = TransformPanel();
|
||||
mLightPanel = LightPanel();
|
||||
mScriptPanel = ScriptPanel();
|
||||
mQuakeMapPanel = QuakeMapPanel();
|
||||
}
|
||||
|
||||
void EditorSelectionPanel::Draw(EditorSelection selection)
|
||||
{
|
||||
if (ImGui::Begin("Propreties"))
|
||||
{
|
||||
switch (selection.Type)
|
||||
{
|
||||
case EditorSelectionType::None:
|
||||
{
|
||||
DrawNone();
|
||||
break;
|
||||
}
|
||||
|
||||
case EditorSelectionType::Entity:
|
||||
{
|
||||
DrawEntity(selection.Entity);
|
||||
break;
|
||||
}
|
||||
case EditorSelectionType::File:
|
||||
{
|
||||
DrawFile(selection.File.get());
|
||||
break;
|
||||
}
|
||||
case EditorSelectionType::Resource:
|
||||
{
|
||||
DrawResource(selection.Resource);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void EditorSelectionPanel::DrawNone()
|
||||
{
|
||||
std::string text = "No selection";
|
||||
auto windowWidth = ImGui::GetWindowSize().x;
|
||||
auto windowHeight = ImGui::GetWindowSize().y;
|
||||
|
||||
auto textWidth = ImGui::CalcTextSize(text.c_str()).x;
|
||||
auto textHeight = ImGui::CalcTextSize(text.c_str()).y;
|
||||
ImGui::SetCursorPosX((windowWidth - textWidth) * 0.5f);
|
||||
ImGui::SetCursorPosY((windowHeight - textHeight) * 0.5f);
|
||||
|
||||
ImGui::Text(text.c_str());
|
||||
}
|
||||
|
||||
void EditorSelectionPanel::DrawEntity(Nuake::Entity entity)
|
||||
{
|
||||
DrawAddComponentMenu(entity);
|
||||
|
||||
// Draw each component properties panels.
|
||||
mTransformPanel.Draw(entity);
|
||||
mLightPanel.Draw(entity);
|
||||
mScriptPanel.Draw(entity);
|
||||
mMeshPanel.Draw(entity);
|
||||
mQuakeMapPanel.Draw(entity);
|
||||
/*
|
||||
if (Selection.Entity.HasComponent<MeshComponent>())
|
||||
{
|
||||
std::string icon = ICON_FA_MALE;
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Mesh").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Mesh properties");
|
||||
auto& component = Selection.Entity.GetComponent<MeshComponent>();
|
||||
// Path
|
||||
std::string path = component.ModelPath;
|
||||
char pathBuffer[256];
|
||||
|
||||
memset(pathBuffer, 0, sizeof(pathBuffer));
|
||||
std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer));
|
||||
|
||||
std::string oldPath = component.ModelPath;
|
||||
ImGui::Text("Model: ");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::InputText("##ModelPath", pathBuffer, sizeof(pathBuffer)))
|
||||
path = FileSystem::AbsoluteToRelative(std::string(pathBuffer));
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Model"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
path = FileSystem::AbsoluteToRelative(fullPath);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
if (component.ModelPath != path)
|
||||
{
|
||||
component.ModelPath = path;
|
||||
component.LoadModel();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Reimport"))
|
||||
{
|
||||
component.LoadModel();
|
||||
}
|
||||
|
||||
ImGui::Indent(16.0f);
|
||||
if (ImGui::CollapsingHeader("Meshes"))
|
||||
{
|
||||
ImGui::Indent(16.0f);
|
||||
uint16_t index = 0;
|
||||
for (auto& m : component.meshes)
|
||||
{
|
||||
if (ImGui::CollapsingHeader(std::to_string(index).c_str()))
|
||||
{
|
||||
std::string materialName = "No material";
|
||||
if (m->m_Material)
|
||||
materialName = m->m_Material->GetName();
|
||||
|
||||
ImGui::Indent(16.0f);
|
||||
if (ImGui::CollapsingHeader(materialName.c_str()))
|
||||
{
|
||||
//if (ImGui::BeginChild("Material child", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysAutoResize))
|
||||
//{
|
||||
ImGui::Indent(16.0f);
|
||||
DrawMaterialEditor(m->m_Material);
|
||||
//}
|
||||
//ImGui::EndChild();
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Material"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
path = FileSystem::AbsoluteToRelative(fullPath);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (Selection.Entity.HasComponent<WrenScriptComponent>()) {
|
||||
std::string icon = ICON_FA_FILE;
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Wren Script").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Script properties");
|
||||
auto& component = Selection.Entity.GetComponent<WrenScriptComponent>();
|
||||
|
||||
// Path
|
||||
std::string path = component.Script;
|
||||
char pathBuffer[256];
|
||||
|
||||
memset(pathBuffer, 0, sizeof(pathBuffer));
|
||||
std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer));
|
||||
|
||||
ImGui::Text("Script: ");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::InputText("##ScriptPath", pathBuffer, sizeof(pathBuffer)))
|
||||
path = FileSystem::AbsoluteToRelative(std::string(pathBuffer));
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
path = FileSystem::AbsoluteToRelative(fullPath);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
|
||||
component.Script = path;
|
||||
|
||||
// Class
|
||||
std::string module = component.Class;
|
||||
|
||||
char classBuffer[256];
|
||||
|
||||
memset(classBuffer, 0, sizeof(classBuffer));
|
||||
std::strncpy(classBuffer, module.c_str(), sizeof(classBuffer));
|
||||
|
||||
ImGui::Text("Class: ");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::InputText("##ScriptModule", classBuffer, sizeof(classBuffer)))
|
||||
module = std::string(classBuffer);
|
||||
|
||||
component.Class = module;
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
|
||||
if (Selection.Entity.HasComponent<CameraComponent>()) {
|
||||
|
||||
std::string icon = ICON_FA_LIGHTBULB;
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Camera").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Camera properties");
|
||||
Selection.Entity.GetComponent<CameraComponent>().DrawEditor();
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Selection.Entity.HasComponent<CharacterControllerComponent>())
|
||||
{
|
||||
if (ImGui::CollapsingHeader("Character controller", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Character controller properties");
|
||||
auto& c = Selection.Entity.GetComponent<CharacterControllerComponent>();
|
||||
ImGui::InputFloat("Height", &c.Height);
|
||||
ImGui::InputFloat("Radius", &c.Radius);
|
||||
ImGui::InputFloat("Mass", &c.Mass);
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
if (Selection.Entity.HasComponent<RigidBodyComponent>())
|
||||
{
|
||||
std::string icon = ICON_FA_BOWLING_BALL;
|
||||
if (ImGui::CollapsingHeader((icon + " Rigidbody").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Rigidbody properties");
|
||||
RigidBodyComponent& rbComponent = Selection.Entity.GetComponent<RigidBodyComponent>();
|
||||
ImGui::DragFloat("Mass", &rbComponent.mass, 0.1, 0.0);
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
if (Selection.Entity.HasComponent<BoxColliderComponent>())
|
||||
{
|
||||
std::string icon = ICON_FA_BOX;
|
||||
if (ImGui::CollapsingHeader((icon + " Box collider").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Box collider properties");
|
||||
BoxColliderComponent& component = Selection.Entity.GetComponent<BoxColliderComponent>();
|
||||
ImGuiHelper::DrawVec3("Size", &component.Size);
|
||||
ImGui::Checkbox("Is trigger", &component.IsTrigger);
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
if (Selection.Entity.HasComponent<SphereColliderComponent>())
|
||||
{
|
||||
std::string icon = ICON_FA_CIRCLE;
|
||||
if (ImGui::CollapsingHeader((icon + " Sphere collider").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Sphere properties");
|
||||
SphereColliderComponent& component = Selection.Entity.GetComponent<SphereColliderComponent>();
|
||||
ImGui::DragFloat("Radius", &component.Radius, 0.1f, 0.0f, 100.0f);
|
||||
ImGui::Checkbox("Is trigger", &component.IsTrigger);
|
||||
|
||||
ImGui::Separator();
|
||||
}
|
||||
}
|
||||
if (Selection.Entity.HasComponent<QuakeMapComponent>())
|
||||
{
|
||||
|
||||
std::string icon = ICON_FA_BROOM;
|
||||
if (ImGui::CollapsingHeader((icon + " " + "Quake map").c_str(), ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
ImGui::TextColored(ImGui::GetStyleColorVec4(1), "Quake map properties");
|
||||
auto& component = Selection.Entity.GetComponent<QuakeMapComponent>();
|
||||
std::string path = component.Path;
|
||||
|
||||
|
||||
char pathBuffer[256];
|
||||
memset(pathBuffer, 0, sizeof(pathBuffer));
|
||||
std::strncpy(pathBuffer, path.c_str(), sizeof(pathBuffer));
|
||||
ImGui::Text("Map file: ");
|
||||
ImGui::SameLine();
|
||||
if (ImGui::InputText("##MapPath", pathBuffer, sizeof(pathBuffer)))
|
||||
{
|
||||
path = std::string(pathBuffer);
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Map"))
|
||||
{
|
||||
char* file = (char*)payload->Data;
|
||||
std::string fullPath = std::string(file, 256);
|
||||
path = FileSystem::AbsoluteToRelative(fullPath);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
component.Path = path;
|
||||
|
||||
ImGui::InputFloat("Scale factor", &component.ScaleFactor, 0.01f, 0.1f);
|
||||
|
||||
ImGui::Checkbox("Build collisions", &component.HasCollisions);
|
||||
if (ImGui::Button("Build Geometry"))
|
||||
{
|
||||
QuakeMapBuilder mapBuilder;
|
||||
mapBuilder.BuildQuakeMap(Selection.Entity);
|
||||
}
|
||||
ImGui::Separator();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void EditorSelectionPanel::DrawAddComponentMenu(Nuake::Entity entity)
|
||||
{
|
||||
if (entity.HasComponent<Nuake::NameComponent>())
|
||||
{
|
||||
auto& entityName = entity.GetComponent<Nuake::NameComponent>().Name;
|
||||
ImGuiTextSTD("##Name", entityName);
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::Button("Add Component"))
|
||||
ImGui::OpenPopup("ComponentPopup");
|
||||
|
||||
if (ImGui::BeginPopup("ComponentPopup"))
|
||||
{
|
||||
MenuItemComponent("Wren Script", Nuake::WrenScriptComponent);
|
||||
MenuItemComponent("Camera", Nuake::CameraComponent);
|
||||
MenuItemComponent("Light", Nuake::LightComponent);
|
||||
MenuItemComponent("Mesh", Nuake::MeshComponent);
|
||||
MenuItemComponent("Rigid body", Nuake::RigidBodyComponent);
|
||||
MenuItemComponent("Box collider", Nuake::BoxColliderComponent);
|
||||
MenuItemComponent("Sphere collider", Nuake::SphereColliderComponent);
|
||||
MenuItemComponent("Mesh collider", Nuake::MeshColliderComponent);
|
||||
MenuItemComponent("Quake map", Nuake::QuakeMapComponent);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EditorSelectionPanel::DrawFile(Nuake::File* file)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EditorSelectionPanel::DrawResource(Nuake::Resource resource)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
30
Editor/src/Windows/EditorSelectionPanel.h
Normal file
30
Editor/src/Windows/EditorSelectionPanel.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include "../Actions/EditorSelection.h"
|
||||
#include "src/Scene/Entities/Entity.h"
|
||||
#include "src/Core/FileSystem.h"
|
||||
|
||||
#include "../ComponentsPanel/TransformPanel.h"
|
||||
#include "../ComponentsPanel/LightPanel.h"
|
||||
#include "../ComponentsPanel/ScriptPanel.h"
|
||||
#include "../ComponentsPanel/MeshPanel.h"
|
||||
#include "../ComponentsPanel/QuakeMapPanel.h"
|
||||
|
||||
class EditorSelectionPanel {
|
||||
private:
|
||||
TransformPanel mTransformPanel;
|
||||
LightPanel mLightPanel;
|
||||
ScriptPanel mScriptPanel;
|
||||
MeshPanel mMeshPanel;
|
||||
QuakeMapPanel mQuakeMapPanel;
|
||||
public:
|
||||
EditorSelectionPanel();
|
||||
|
||||
void Draw(EditorSelection selection);
|
||||
|
||||
void DrawNone();
|
||||
void DrawEntity(Nuake::Entity entity);
|
||||
void DrawAddComponentMenu(Nuake::Entity entity);
|
||||
|
||||
void DrawFile(Nuake::File* file);
|
||||
void DrawResource(Nuake::Resource resource);
|
||||
};
|
||||
@@ -114,54 +114,53 @@ namespace Nuake {
|
||||
void FileSystemUI::DrawFile(Ref<File> file)
|
||||
{
|
||||
ImGui::PushFont(EditorInterface::bigIconFont);
|
||||
if (file->Type == ".png" || file->Type == ".jpg")
|
||||
std::string fileExtension = file->GetExtension();
|
||||
if (fileExtension == ".png" || fileExtension == ".jpg")
|
||||
{
|
||||
Ref<Texture> texture = TextureManager::Get()->GetTexture(file->fullPath);
|
||||
Ref<Texture> texture = TextureManager::Get()->GetTexture(file->GetAbsolutePath());
|
||||
ImGui::ImageButton((void*)texture->GetID(), ImVec2(100, 100), ImVec2(0, 1), ImVec2(1, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* icon = ICON_FA_FILE;
|
||||
if (file->Type == ".shader")
|
||||
if (fileExtension == ".shader" || fileExtension == ".wren")
|
||||
icon = ICON_FA_FILE_CODE;
|
||||
if (file->Type == ".map")
|
||||
if (fileExtension == ".map")
|
||||
icon = ICON_FA_BROOM;
|
||||
if (file->Type == ".ogg" || file->Type == ".mp3" || file->Type == ".wav" || file->Type == ".flac")
|
||||
if (fileExtension == ".ogg" || fileExtension == ".mp3" || fileExtension == ".wav")
|
||||
icon = ICON_FA_FILE_AUDIO;
|
||||
if (file->Type == ".wren")
|
||||
icon = ICON_FA_FILE_CODE;
|
||||
if (file->Type == ".md3" || file->Type == ".obj")
|
||||
if (fileExtension == ".md3" || fileExtension == ".obj")
|
||||
icon = ICON_FA_FILE_IMAGE;
|
||||
|
||||
std::string fullName = icon + std::string("##") + file->fullPath;
|
||||
std::string fullName = icon + std::string("##") + file->GetAbsolutePath();
|
||||
if (ImGui::Button(fullName.c_str(), ImVec2(100, 100)))
|
||||
{
|
||||
|
||||
Editor->Selection = EditorSelection(file);
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropSource())
|
||||
{
|
||||
char pathBuffer[256];
|
||||
std::strncpy(pathBuffer, file->fullPath.c_str(), sizeof(pathBuffer));
|
||||
std::strncpy(pathBuffer, file->GetAbsolutePath().c_str(), sizeof(pathBuffer));
|
||||
std::string dragType;
|
||||
if (file->Type == ".wren")
|
||||
if (fileExtension == ".wren")
|
||||
dragType = "_Script";
|
||||
else if (file->Type == ".map")
|
||||
else if (fileExtension == ".map")
|
||||
dragType = "_Map";
|
||||
else if (file->Type == ".obj" || file->Type == ".mdl" || file->Type == ".gltf" || file->Type == ".md3" || file->Type == ".fbx")
|
||||
else if (fileExtension == ".obj" || fileExtension == ".mdl" || fileExtension == ".gltf" || fileExtension == ".md3" || fileExtension == ".fbx")
|
||||
dragType = "_Model";
|
||||
else if (file->Type == ".interface")
|
||||
else if (fileExtension == ".interface")
|
||||
dragType = "_Interface";
|
||||
else if (file->Type == ".prefab")
|
||||
else if (fileExtension == ".prefab")
|
||||
dragType = "_Prefab";
|
||||
|
||||
ImGui::SetDragDropPayload(dragType.c_str(), (void*)(pathBuffer), sizeof(pathBuffer));
|
||||
ImGui::Text(file->name.c_str());
|
||||
ImGui::Text(file->GetName().c_str());
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Text(file->name.c_str());
|
||||
ImGui::Text(file->GetName().c_str());
|
||||
ImGui::PopFont();
|
||||
}
|
||||
|
||||
@@ -266,7 +265,7 @@ namespace Nuake {
|
||||
{
|
||||
int width = avail.x;
|
||||
ImVec2 buttonSize = ImVec2(80, 80);
|
||||
int amount = (int)(width / 200);
|
||||
int amount = (int)(width / 100);
|
||||
if (amount <= 0) amount = 1;
|
||||
|
||||
int i = 1; // current amount of item per row.
|
||||
@@ -1,18 +1,22 @@
|
||||
#pragma once
|
||||
#include <src/Core/FileSystem.h>
|
||||
#include <src/Scene/Entities/Entity.h>
|
||||
#include "EditorInterface.h"
|
||||
|
||||
namespace Nuake {
|
||||
class FileSystemUI
|
||||
{
|
||||
private:
|
||||
|
||||
EditorInterface* Editor;
|
||||
|
||||
public:
|
||||
Ref<Directory> m_CurrentDirectory;
|
||||
FileSystemUI() {
|
||||
|
||||
FileSystemUI(EditorInterface* editor) {
|
||||
m_CurrentDirectory = FileSystem::RootDirectory;
|
||||
Editor = editor;
|
||||
}
|
||||
|
||||
void Draw();
|
||||
void DrawDirectoryContent();
|
||||
void DrawFiletree();
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "ProjectInterface.h"
|
||||
#include <src/Vendors/imgui/imgui.h>
|
||||
#include "Engine.h"
|
||||
#include "ImGuiTextHelper.h"
|
||||
//#include "ImGuiTextHelper.h"
|
||||
|
||||
namespace Nuake {
|
||||
void ProjectInterface::DrawProjectSettings()
|
||||
@@ -45,7 +45,7 @@ namespace Nuake {
|
||||
|
||||
ImGui::Text("Trenchbroom path:");
|
||||
ImGui::SameLine();
|
||||
ImGuiTextSTD("", m_CurrentProject->TrenchbroomPath);
|
||||
//ImGuiTextSTD("", m_CurrentProject->TrenchbroomPath);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Browse"))
|
||||
{
|
||||
@@ -62,8 +62,8 @@ namespace Nuake {
|
||||
auto flags = ImGuiWindowFlags_NoTitleBar;
|
||||
if (ImGui::BeginPopupModal("Create new point entity", NULL, flags))
|
||||
{
|
||||
ImGuiTextSTD("Name", newEntity.Name);
|
||||
ImGuiTextMultiline("Description", newEntity.Description);
|
||||
//ImGuiTextSTD("Name", newEntity.Name);
|
||||
//ImGuiTextMultiline("Description", newEntity.Description);
|
||||
|
||||
if (ImGui::BeginTable("DictCreate", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
|
||||
{
|
||||
@@ -75,7 +75,7 @@ namespace Nuake {
|
||||
int idx = 0;
|
||||
for (auto& p : newEntity.Properties)
|
||||
{
|
||||
ImGuiTextSTD("Name", p.name);
|
||||
//ImGuiTextSTD("Name", p.name);
|
||||
ImGui::TableNextColumn();
|
||||
std::string current_item = NULL;
|
||||
if (ImGui::BeginCombo(("TypeSelection" + std::to_string(idx)).c_str(), current_item.c_str()))
|
||||
@@ -146,18 +146,18 @@ namespace Nuake {
|
||||
int i = 0;
|
||||
for (auto& pE : file->PointEntities)
|
||||
{
|
||||
ImGuiTextSTD("##PName" + std::to_string(i), pE.Name);
|
||||
//ImGuiTextSTD("##PName" + std::to_string(i), pE.Name);
|
||||
for (int i = 0; i < pE.Name.size(); i++)
|
||||
{
|
||||
if (pE.Name[i] == ' ')
|
||||
pE.Name[i] = '_';
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiTextSTD("Desc" + std::to_string(i), pE.Description);
|
||||
//ImGuiTextSTD("Desc" + std::to_string(i), pE.Description);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button("Edit");
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiTextSTD("Prefab##" + std::to_string(i), pE.Prefab);
|
||||
//ImGuiTextSTD("Prefab##" + std::to_string(i), pE.Prefab);
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Prefab"))
|
||||
@@ -201,10 +201,10 @@ namespace Nuake {
|
||||
int i = 0;
|
||||
for (auto& pE : file->BrushEntities)
|
||||
{
|
||||
ImGuiTextSTD("##Name" + std::to_string(i), pE.Name);
|
||||
//ImGuiTextSTD("##Name" + std::to_string(i), pE.Name);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiTextSTD("Desc" + std::to_string(i), pE.Description);
|
||||
//ImGuiTextSTD("Desc" + std::to_string(i), pE.Description);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::Checkbox(std::string("Visible##" + std::to_string(i)).c_str(), &pE.Visible);
|
||||
@@ -215,7 +215,7 @@ namespace Nuake {
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGuiTextSTD("Script##" + std::to_string(i), pE.Script);
|
||||
//ImGuiTextSTD("Script##" + std::to_string(i), pE.Script);
|
||||
if (ImGui::BeginDragDropTarget())
|
||||
{
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script"))
|
||||
@@ -227,7 +227,7 @@ namespace Nuake {
|
||||
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
ImGuiTextSTD("Class##" + std::to_string(i), pE.Class);
|
||||
//ImGuiTextSTD("Class##" + std::to_string(i), pE.Class);
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
i++;
|
||||
@@ -238,8 +238,8 @@ namespace Nuake {
|
||||
|
||||
if (ImGui::BeginPopupModal("CreateBrush", NULL, flags))
|
||||
{
|
||||
ImGuiTextSTD("Name", newEntity.Name);
|
||||
ImGuiTextMultiline("Description", newEntity.Description);
|
||||
//ImGuiTextSTD("Name", newEntity.Name);
|
||||
//ImGuiTextMultiline("Description", newEntity.Description);
|
||||
|
||||
bool isSolid = true;
|
||||
bool isTrigger = false;
|
||||
83
Editor/src/Windows/WelcomeWindow.cpp
Normal file
83
Editor/src/Windows/WelcomeWindow.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "WelcomeWindow.h"
|
||||
#include <src/Vendors/imgui/imgui.h>
|
||||
|
||||
#include "../Misc/InterfaceFonts.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
void WelcomeWindow::Draw()
|
||||
{
|
||||
std::vector<std::string> projects = {
|
||||
"C:/Dev/Nuake-DemoProject/test.project"
|
||||
};
|
||||
|
||||
ImGuiViewport* viewport = ImGui::GetMainViewport();
|
||||
ImGui::SetNextWindowPos(viewport->GetWorkPos());
|
||||
ImGui::SetNextWindowSize(viewport->GetWorkSize());
|
||||
ImGui::SetNextWindowViewport(viewport->ID);
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(32.0f, 32.0f));
|
||||
ImGui::Begin("AL:SDAL:SKd", 0, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
|
||||
{
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::Title);
|
||||
|
||||
std::string text = "Nuake Engine";
|
||||
auto windowWidth = ImGui::GetWindowSize().x;
|
||||
auto textWidth = ImGui::CalcTextSize(text.c_str()).x;
|
||||
|
||||
ImGui::SetCursorPosX((windowWidth - textWidth) * 0.5f);
|
||||
ImGui::Text(text.c_str());
|
||||
}
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::SubTitle);
|
||||
std::string text = "An IdTech inspired game engine";
|
||||
auto windowWidth = ImGui::GetWindowSize().x;
|
||||
auto textWidth = ImGui::CalcTextSize(text.c_str()).x;
|
||||
|
||||
ImGui::SetCursorPosX((windowWidth - textWidth) * 0.5f);
|
||||
ImGui::Text(text.c_str());
|
||||
}
|
||||
ImGui::Separator();
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::SubTitle);
|
||||
ImGui::Text("Projects recently opened");
|
||||
}
|
||||
|
||||
ImVec2 projectsWindowSize = ImGui::GetContentRegionAvail();
|
||||
projectsWindowSize.x *= 0.6f;
|
||||
|
||||
int idx = 0;
|
||||
ImGui::BeginChild("Projects", projectsWindowSize, true);
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
float cursorY = ImGui::GetCursorPosY();
|
||||
std::string selectableName = "##My new project" + std::to_string(i);
|
||||
ImGui::Selectable(selectableName.c_str(), false, 0, ImVec2(ImGui::GetContentRegionAvailWidth(), 100));
|
||||
ImGui::SetCursorPosY(cursorY);
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::LargeBold);
|
||||
ImGui::Text("Name of project");
|
||||
}
|
||||
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::Bold);
|
||||
ImGui::Text("last modified on 10/20/2022");
|
||||
}
|
||||
{
|
||||
UIFont boldfont = UIFont(Fonts::Normal);
|
||||
ImGui::TextWrapped("Description lajsflkahjfklashklashgkASDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDlashglkashlkghalskghaslghaslkghaklsg");
|
||||
//ImGui::Text("Description lajsflkahjfklashklashgklashglkashlkghalskghaslghaslkghaklsg");
|
||||
}
|
||||
ImGui::SetCursorPosY(cursorY + 100);
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar();
|
||||
ImGui::PopStyleVar();
|
||||
}
|
||||
9
Editor/src/Windows/WelcomeWindow.h
Normal file
9
Editor/src/Windows/WelcomeWindow.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
class WelcomeWindow {
|
||||
public:
|
||||
int SelectedProject = 0;
|
||||
|
||||
void Draw();
|
||||
};
|
||||
Reference in New Issue
Block a user