Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
a3d39af
#26 Editor improvements
Av3boy Mar 25, 2025
661113f
Method for opening multiple windows
Av3boy Mar 27, 2025
dd0838e
Small refactoring
Av3boy Mar 27, 2025
f2b9534
Opening SharpEngine windows works
Av3boy Mar 27, 2025
7b2e0ab
UI improvements (WIP)
Av3boy Mar 27, 2025
5adf7b1
Launcher UI improvements
Av3boy Mar 28, 2025
c66594d
Cleanup
Av3boy Mar 28, 2025
ea21cc9
Cleanup UIElement mesh data
Av3boy Mar 29, 2025
4b5cf13
Cleanup
Av3boy Mar 29, 2025
8bd4c98
Texturing improvements
Av3boy Mar 29, 2025
93c02b6
Add basic layout placeholders
Av3boy Mar 29, 2025
d21d76a
UI shader testing (WIP)
Av3boy Mar 29, 2025
1f50cff
UI rendering works
Av3boy Mar 29, 2025
abafdd9
Actual fix
Av3boy Mar 29, 2025
95fbe33
Generalize functions
Av3boy Mar 30, 2025
90e9a87
Fiddle with Transforms and types (WIP)
Av3boy Apr 3, 2025
be73f35
Midway solution (Not finished)
Av3boy Apr 4, 2025
9c01d8a
Getting there
Av3boy Apr 4, 2025
fc04807
Transform abstraction
Av3boy Apr 4, 2025
4877f46
UI element ortographic projection
Av3boy Apr 5, 2025
b64d917
Translating somewhat works
Av3boy Apr 5, 2025
7793ffc
UI transform behaving correctly?
Av3boy Apr 5, 2025
0ba636e
Add documentation / general enhancements
Av3boy Apr 6, 2025
c6d7764
#2 Framing and rendering changes
Av3boy Apr 6, 2025
f309098
Pop stash
Av3boy Apr 6, 2025
a0c2105
#26 Fix build
Av3boy Apr 8, 2025
4f76569
#26 Fix flags
Av3boy Apr 8, 2025
48652aa
#26 Use width and height
Av3boy Apr 8, 2025
5a80363
Merge branch 'temp' into 26-editor-improvements
Av3boy Apr 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
28 changes: 28 additions & 0 deletions Core/Abstractions/IRenderable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using SharpEngine.Core.Entities.Properties.Meshes;

namespace SharpEngine.Core.Interfaces;

// TODO: Make an abstract class and move Render method here?

/// <summary>
/// Contains definitions for rendering objects.
/// </summary>
public interface IRenderable
{
/// <summary>
/// Gets or sets the vertex array object of the object.
/// </summary>
public uint VAO { get; set; }

/// <summary>
/// Initializes the necessary buffers for the object.
/// </summary>
/// <param name="mesh">The mesh that should the buffers should be initialized with.</param>
public void InitializeBuffers(Mesh mesh);

/// <summary>
/// Binds the VAO to the current context.
/// </summary>
public void Bind();

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ public interface ISettings
/// <summary>Gets or sets which renderer should be enabled for the current window.</summary>
public RenderFlags RendererFlags { get; set; }

/// <summary>Gets or sets the primary mouse button.</summary>
public MouseButton PrimaryButton { get; set; }

/// <summary>Gets or sets the secondary mouse button.</summary>
public MouseButton SecondaryButton { get; set; }
}

Expand Down
65 changes: 65 additions & 0 deletions Core/Entities/BezierCurve.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Silk.NET.Maths;
using System;
using System.Collections.Generic;

namespace SharpEngine.Core.Entities;

/// <summary>
/// Represents a cubic Bezier curve.
/// </summary>
public class BezierCurve
{
private Vector3D<float> P0, P1, P2, P3;

/// <summary>Gets the start point of the curve.</summary>
public Vector3D<float> Start => P0;

/// <summary>Gets the end point of the curve.</summary>

public Vector3D<float> End => P3;

/// <summary>
/// Initializes a new instance of <see cref="BezierCurve" />.
/// </summary>
/// <param name="initializationPosition">The point where the curve should be created.</param>
public BezierCurve(Vector3D<float> initializationPosition)
{
const float defaultWidth = 1;

P0 = initializationPosition;
P1 = new Vector3D<float>(initializationPosition.X + defaultWidth, initializationPosition.Y + defaultWidth, initializationPosition.Z);
P2 = new Vector3D<float>(initializationPosition.X + defaultWidth, initializationPosition.Y - defaultWidth, initializationPosition.Z);
P3 = new Vector3D<float>(initializationPosition.X + defaultWidth, initializationPosition.Y, initializationPosition.Z);
}

/// <summary>
/// Gets the points of the curve.
/// </summary>
/// <param name="resolution">The distance between each point, defines the roughness of the curve.</param>
/// <returns>The points for the curve with the given <paramref name="resolution"/>.</returns>
public List<Vector3D<float>> GetPoints(uint resolution)
{
var points = new List<Vector3D<float>>();
for (var i = 0; i <= resolution; i++)
{
var t = i / (float)resolution;
points.Add(GetPointAt(t));
}

return points;
}

private Vector3D<float> GetPointAt(float t)
{
var x = GetCoordinateAt(t, P0.X, P1.X, P2.X, P3.X);
var y = GetCoordinateAt(t, P0.Y, P1.Y, P2.Y, P3.Y);
var z = GetCoordinateAt(t, P0.Z, P1.Z, P2.Z, P3.Z);
return new(x, y, z);
}

private static float GetCoordinateAt(float t, float p0, float p1, float p2, float p3)
{
float u = 1 - t;
return MathF.Pow(u, 3) * p0 + 3 * MathF.Pow(u, 2) * t * p1 + 3 * u * MathF.Pow(t, 2) * p2 + MathF.Pow(t, 3) * p3;
}
}
91 changes: 67 additions & 24 deletions Core/Entities/GameObject.cs
Original file line number Diff line number Diff line change
@@ -1,74 +1,72 @@
using SharpEngine.Core.Attributes;
using SharpEngine.Core.Entities.Properties;
using SharpEngine.Core.Entities.Properties.Meshes;
using SharpEngine.Core.Extensions;
using SharpEngine.Core.Entities.Views;
using SharpEngine.Core.Interfaces;
using SharpEngine.Core.Numerics;
using SharpEngine.Core.Scenes;
using SharpEngine.Core.Shaders;
using SharpEngine.Core.Textures;
using SharpEngine.Core.Windowing;

using Silk.NET.OpenGL;

using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Threading.Tasks;

namespace SharpEngine.Core.Entities;

/// <summary>
/// Represents a game object in the scene.
/// Represents a game object in the scene.
/// </summary>
public class GameObject : SceneNode
public class GameObject : EmptyNode<Transform, Vector3>, IRenderable
{
/// <summary>
/// Initializes a new instance of the <see cref="GameObject"/>.
/// </summary>
public GameObject()
public GameObject() : base(string.Empty)
{
var shader = ShaderService.Instance.LoadShader(PathExtensions.GetAssemblyPath("Shaders/shader.vert"), PathExtensions.GetAssemblyPath("Shaders/lighting.frag"), "lighting");
var diffuse = TextureService.Instance.LoadTexture(PathExtensions.GetAssemblyPath("Textures/DefaultTextures/debug.JPG"));
// TODO: Using lightning shader here will most likely break stuff, it needs to be refactored out.
var shader = ShaderService.Instance.LoadShader(_Resources.Default.VertexShader, _Resources.Default.FragmentShader, "lighting");
var diffuse = TextureService.Instance.LoadTexture(_Resources.Default.DebugTexture);
Material = new(shader, diffuse);

BoundingBox = BoundingBox.CalculateBoundingBox(Transform);
}

/// <summary>
/// Initializes a new instance of the <see cref="GameObject"/> with specified textures and shaders.
/// Initializes a new instance of the <see cref="GameObject"/> with specified textures and shaders.
/// </summary>
/// <param name="diffuseMapFile">The file path of the diffuse map texture.</param>
/// <param name="specularMapFile">The file path of the specular map texture.</param>
/// <param name="vertShaderFile">The file path of the vertex shader.</param>
/// <param name="fragShaderFile">The file path of the fragment shader.</param>
public GameObject(string diffuseMapFile, string specularMapFile, string vertShaderFile, string fragShaderFile)
public GameObject(string? diffuseMapFile = null, string? specularMapFile = null, string? vertShaderFile = null, string? fragShaderFile = null) : base(string.Empty)
{
var diffuse = TextureService.Instance.LoadTexture(diffuseMapFile);
var specularMap = TextureService.Instance.LoadTexture(specularMapFile);
var shader = ShaderService.Instance.LoadShader(vertShaderFile, fragShaderFile, "lighting");

Material = new Material(shader, diffuse)
{
SpecularMap = specularMap
};
var shader = ShaderService.Instance.LoadShader(vertShaderFile ?? _Resources.Default.VertexShader, fragShaderFile ?? _Resources.Default.FragmentShader, "lighting");
var diffuse = TextureService.Instance.LoadTexture(diffuseMapFile ?? _Resources.Default.DebugTexture);
var specular = string.IsNullOrEmpty(specularMapFile) ? null : TextureService.Instance.LoadTexture(specularMapFile!);
Material = new Material(shader, diffuse, specular);

BoundingBox = BoundingBox.CalculateBoundingBox(Transform);
}

/// <summary>
/// Gets or sets the mesh of the game object.
/// </summary>
public List<Mesh> Mesh { get; set; } = [];
public List<Mesh> Meshes { get; set; } = [];

// TODO: Each mesh should have its own material.
/// <summary>
/// Gets or sets the material of the game object.
/// </summary>
[Inspector(DisplayInInspector = false)]
public Material Material { get; set; }

private Transform _transform = new();

/// <summary>
/// Gets or sets the transform of the game object.
/// </summary>
public Transform Transform
public override Transform Transform
{
get => _transform;
set
Expand All @@ -77,6 +75,8 @@ public Transform Transform
BoundingBox = BoundingBox.CalculateBoundingBox(_transform);
}
}

private Transform _transform = new();

/// <summary>
/// Gets the bounding box of the game object.
Expand All @@ -85,22 +85,65 @@ public Transform Transform
public BoundingBox BoundingBox { get; set; }

/// <inheritdoc />
public override Task Render()
public uint VAO { get; set; }

/// <inheritdoc />
public void Initialize()
{
VAO = Window.GL.GenVertexArray();
Bind();

foreach (var mesh in Meshes)
InitializeBuffers(mesh);

Material.Shader.Use();
}

/// <inheritdoc />
public void Bind()
{
Window.GL.BindVertexArray(VAO);
}

/// <inheritdoc />
public void InitializeBuffers(Mesh mesh)
{
var vertexBufferObject = Window.GL.GenBuffer();
Window.GL.BindBuffer(GLEnum.ArrayBuffer, vertexBufferObject);
Window.GL.BufferData<float>(GLEnum.ArrayBuffer, mesh.GetVertices(), GLEnum.StaticDraw);

var elementBufferObject = Window.GL.GenBuffer();
Window.GL.BindBuffer(GLEnum.ElementArrayBuffer, elementBufferObject);
Window.GL.BufferData<uint>(GLEnum.ElementArrayBuffer, mesh.Indices, GLEnum.StaticDraw);
}

/// <inheritdoc />
public override Task Render(CameraView camera, Window window)
{
Material.DiffuseMap.Use(TextureUnit.Texture0);
Material.Shader.SetInt("material.diffuse", Material.diffuseUnit);

if (Material.SpecularMap is not null)
if (Material.UseSpecularMap)
{
Material.SpecularMap.Use(TextureUnit.Texture1);
Material.Shader.SetInt("material.specular", Material.specularUnit);
Material.Shader.SetVector3("material.specular", Material.Specular);
Material.Shader.SetFloat("material.shininess", Material.Shininess);
}
else
{
Material.Shader.SetInt("material.specular", 0);
Material.Shader.SetVector3("material.specular", new System.Numerics.Vector3(0));
Material.Shader.SetFloat("material.shininess", 0);
}

Material.Shader.SetMatrix4(ShaderAttributes.Model, Transform.ModelMatrix);

Window.GL.DrawArrays(PrimitiveType.Triangles, 0, 36);

// foreach (var mesh in Meshes)
// Window.GL.DrawElements<uint>(PrimitiveType.Triangles, (uint)mesh.Indices.Length, DrawElementsType.UnsignedInt, []);

return Task.CompletedTask;
}
}
6 changes: 4 additions & 2 deletions Core/Entities/Lights/DirectionalLight.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using SharpEngine.Core.Entities.Properties;
using SharpEngine.Core.Entities.Properties;
using SharpEngine.Core.Entities.Views;
using SharpEngine.Core.Extensions;
using SharpEngine.Core.Shaders;
using SharpEngine.Core.Windowing;
using System.Numerics;
using System.Threading.Tasks;

Expand Down Expand Up @@ -28,7 +30,7 @@ public DirectionalLight()
}

/// <inheritdoc />
public override Task Render()
public override Task Render(CameraView camera, Window window)
{
Material.Shader.SetVector3("dirLight.direction", Direction);
Material.Shader.SetVector3("dirLight.ambient", Ambient);
Expand Down
14 changes: 8 additions & 6 deletions Core/Entities/Lights/PointLight.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using SharpEngine.Core.Extensions;
using SharpEngine.Core.Entities.Views;
using SharpEngine.Core.Extensions;
using SharpEngine.Core.Shaders;
using SharpEngine.Core.Windowing;
using System.Numerics;
using System.Threading.Tasks;

Expand All @@ -18,7 +20,7 @@ public class PointLight : Light
public PointLight(Vector3 position, int index)
{
Transform.Scale = new(0.2f, 0.2f, 0.2f);
Transform.Position = position;
Transform.Position = (SharpEngine.Core.Numerics.Vector3)position;
Constant = 1.0f;
Linear = 0.09f;
Quadratic = 0.032f;
Expand Down Expand Up @@ -50,18 +52,18 @@ public PointLight(Vector3 position, int index)
public float Quadratic { get; set; }

/// <inheritdoc />
public override Task Render()
public override Task Render(CameraView camera, Window window)
{
Material.Shader.SetVector3($"pointLights[{_index}].position", Transform.Position);
Material.Shader.SetVector3($"pointLights[{_index}].position", (Vector3)Transform.Position);
Material.Shader.SetVector3($"pointLights[{_index}].ambient", Ambient);
Material.Shader.SetVector3($"pointLights[{_index}].diffuse", Diffuse);
Material.Shader.SetVector3($"pointLights[{_index}].specular", Specular);
Material.Shader.SetFloat($"pointLights[{_index}].constant", Constant);
Material.Shader.SetFloat($"pointLights[{_index}].linear", Linear);
Material.Shader.SetFloat($"pointLights[{_index}].quadratic", Quadratic);

var lampMatrix = Matrix4x4.CreateScale(Transform.Scale);
lampMatrix *= Matrix4x4.CreateTranslation(Transform.Position);
var lampMatrix = Matrix4x4.CreateScale((Vector3)Transform.Scale);
lampMatrix *= Matrix4x4.CreateTranslation((Vector3)Transform.Position);

LampShader.Shader?.SetMatrix4(ShaderAttributes.Model, lampMatrix);

Expand Down
8 changes: 5 additions & 3 deletions Core/Entities/Lights/SpotLight.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using SharpEngine.Core.Extensions;
using SharpEngine.Core.Entities.Views;
using SharpEngine.Core.Extensions;
using SharpEngine.Core.Shaders;
using SharpEngine.Core.Windowing;
using System.Numerics;
using System.Threading.Tasks;

Expand Down Expand Up @@ -56,9 +58,9 @@ public SpotLight()
public float Quadratic { get; set; }

/// <inheritdoc />
public override Task Render()
public override Task Render(CameraView camera, Window window)
{
Material.Shader.SetVector3("spotLight.position", Transform.Position);
Material.Shader.SetVector3("spotLight.position", (Vector3)Transform.Position);
Material.Shader.SetVector3("spotLight.direction", Direction);
Material.Shader.SetVector3("spotLight.ambient", Ambient);
Material.Shader.SetVector3("spotLight.diffuse", Diffuse);
Expand Down
5 changes: 3 additions & 2 deletions Core/Entities/Properties/BoundingBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ public BoundingBox(Vector3 min, Vector3 max)
Max = max;
}

// TODO: This should be calculated by the mesh.
/// <summary>
/// Calculates the bounding box of the game object.
/// </summary>
/// <returns>The bounding box of the game object.</returns>
public static BoundingBox CalculateBoundingBox(Transform transform)
public static BoundingBox CalculateBoundingBox(ITransform<SharpEngine.Core.Numerics.Vector3> transform)
{
var min = transform.Position - (transform.Scale / 2);
var max = transform.Position + (transform.Scale / 2);
return new BoundingBox(min, max);
return new BoundingBox((Vector3)min, (Vector3)max);
}
}
Loading