diff --git a/GlitchyEditor/content/Textures/EditorIcons.dds b/GlitchyEditor/content/Textures/EditorIcons.dds new file mode 100644 index 0000000..25dc22d Binary files /dev/null and b/GlitchyEditor/content/Textures/EditorIcons.dds differ diff --git a/GlitchyEditor/content/Textures/EditorIcons.psd b/GlitchyEditor/content/Textures/EditorIcons.psd new file mode 100644 index 0000000..7544cde Binary files /dev/null and b/GlitchyEditor/content/Textures/EditorIcons.psd differ diff --git a/GlitchyEditor/src/EditorLayer.bf b/GlitchyEditor/src/EditorLayer.bf index ae405ff..173dd48 100644 --- a/GlitchyEditor/src/EditorLayer.bf +++ b/GlitchyEditor/src/EditorLayer.bf @@ -11,6 +11,7 @@ using GlitchyEngine.Content; using System.Collections; using GlitchyEngine.Renderer.Animation; using System.IO; +using GlitchyEngine.Core; namespace GlitchyEditor { @@ -49,44 +50,9 @@ namespace GlitchyEditor EditorCamera _camera ~ _.Dispose(); - class CameraController : ScriptableEntity - { - protected override void OnCreate() - { - Log.EngineLogger.Trace("Cam controller created!"); - } - - protected override void OnUpdate(GameTime gameTime) - { - var transformCmp = GetComponent(); - - Vector3 position = transformCmp.Position; - - if (Input.IsKeyPressed(Key.A)) - { - position.X -= gameTime.DeltaTime; - } - if (Input.IsKeyPressed(Key.D)) - { - position.X += gameTime.DeltaTime; - } - if (Input.IsKeyPressed(Key.W)) - { - position.Y += gameTime.DeltaTime; - } - if (Input.IsKeyPressed(Key.S)) - { - position.Y -= gameTime.DeltaTime; - } - - transformCmp.Position = position; - } - - protected override void OnDestroy() - { - Log.EngineLogger.Trace("Cam controller destroyed!"); - } - } + Texture2D _editorIcons ~ _.ReleaseRef(); + SubTexture2D _iconDirectionalLight ~ _.ReleaseRef(); + SubTexture2D _iconCamera ~ _.ReleaseRef(); public this() : base("Example") { @@ -125,6 +91,11 @@ namespace GlitchyEditor _viewportTarget = new RenderTarget2D(RenderTarget2DDescription(.R8G8B8A8_UNorm, 100, 100)); _viewportTarget.SamplerState = SamplerStateManager.LinearClamp; + + _editorIcons = new Texture2D("Textures/EditorIcons.dds"); + _editorIcons.SamplerState = SamplerStateManager.AnisotropicClamp; + _iconDirectionalLight = .CreateFromGrid(_editorIcons, .(0, 0), .(64, 64)); + _iconCamera = .CreateFromGrid(_editorIcons, .(1, 0), .(64, 64)); } private void InitEditor() @@ -151,7 +122,7 @@ namespace GlitchyEditor RenderCommand.SetBlendState(_alphaBlendState); RenderCommand.SetDepthStencilState(_depthStencilState); - _scene.UpdateEditor(gameTime, _camera, _viewportTarget); + _scene.UpdateEditor(gameTime, _camera, _viewportTarget, scope => DebugDraw3D, scope => DebugDraw2D); RenderCommand.UnbindRenderTargets(); RenderCommand.SetRenderTarget(null, 0, true); @@ -160,6 +131,63 @@ namespace GlitchyEditor RenderCommand.SetViewport(_context.SwapChain.BackbufferViewport); } + private void DebugDraw3D() + { + /*for (var (entity, transform, camera) in _scene.[Friend]_ecsWorld.Enumerate()) + { + if (_editor.EntityHierarchyWindow.SelectedEntities.Contains(.(entity, _scene))) + { + DebugRenderer.DrawViewFrustum(transform.WorldTransform, camera.Camera.Projection); + } + }*/ + } + + private void DebugDraw2D() + { + RenderCommand.SetBlendState(_alphaBlendState); + + Matrix billboard = _camera.View.Invert(); + billboard.Translation = .Zero; + + Matrix Billboard(Matrix transform) + { + Vector3 worldPos = transform.Translation; + + return Matrix.Translation(worldPos) * billboard; + } + + for (var (entity, transform, camera) in _scene.[Friend]_ecsWorld.Enumerate()) + { + if (_editor.EntityHierarchyWindow.SelectedEntities.Contains(.(entity, _scene))) + { + DebugRenderer.DrawViewFrustum(transform.WorldTransform, camera.Camera.Projection, _camera.Projection * _camera.View); + } + + Matrix world = Billboard(transform.WorldTransform); + + Renderer2D.DrawQuad(world, _iconCamera); + } + + for (var (entity, transform, light) in _scene.[Friend]_ecsWorld.Enumerate()) + { + if (_editor.EntityHierarchyWindow.SelectedEntities.Contains(.(entity, _scene))) + { + Renderer.DrawRay(.Zero, .(0, 0, 20), ColorRGBA(light.SceneLight.Color, 1.0f), transform.WorldTransform); + + for (float angle = 0; angle < MathHelper.TwoPi; angle += MathHelper.TwoPi / 5.0f) + { + Vector2 pos = MathHelper.CirclePoint(angle, 0.5f); + + Renderer.DrawRay(.(pos, 0), .(pos, 20), .White, transform.WorldTransform); + } + } + + Matrix world = Billboard(transform.WorldTransform); + + Renderer2D.DrawQuad(world, _iconDirectionalLight, ColorRGBA(light.SceneLight.Color, 1.0f)); + } + } + public override void OnEvent(Event event) { EventDispatcher dispatcher = EventDispatcher(event); @@ -176,7 +204,7 @@ namespace GlitchyEditor private bool OnImGuiRender(ImGuiRenderEvent event) { - viewer.ViewTexture(_cameraTarget); + //viewer.ViewTexture(Renderer.[Friend]_gBuffer.Albedo); ImGui.Viewport* viewport = ImGui.GetMainViewport(); ImGui.DockSpaceOverViewport(viewport); @@ -217,6 +245,17 @@ namespace GlitchyEditor light.SceneLight.Color = .(1.0f, 0.95f, 0.8f); } + { + var cameraNtt = _scene.CreateEntity("My Camera"); + let transform = cameraNtt.GetComponent(); + transform.Position = .(5, 5, -5); + transform.RotationEuler = .(MathHelper.ToRadians(45), MathHelper.ToRadians(-45), 0); + + let camera = cameraNtt.AddComponent(); + camera.Primary = true; + camera.Camera.SetPerspective(MathHelper.ToRadians(45), 0.1f, 10.0f); + } + var fxLib = Application.Get().EffectLibrary; using (Effect myEffect = fxLib.Load("content/Shaders/myEffect.hlsl")) @@ -459,7 +498,7 @@ namespace GlitchyEditor bool control = Input.IsKeyPressed(Key.Control); bool shift = Input.IsKeyPressed(Key.Shift); - if (control) + if (!_camera.[Friend]BindMouse && control) { switch (e.KeyCode) { diff --git a/GlitchyEngine/src/Core/RefCounter.bf b/GlitchyEngine/src/Core/RefCounter.bf index 0d24eef..392644a 100644 --- a/GlitchyEngine/src/Core/RefCounter.bf +++ b/GlitchyEngine/src/Core/RefCounter.bf @@ -9,6 +9,11 @@ namespace GlitchyEngine.Core */ public class RefCounter : System.RefCounted, IDisposable { + protected ~this() + { + + } + public void Dispose() { ReleaseRef(); diff --git a/GlitchyEngine/src/Math/MathHelper.bf b/GlitchyEngine/src/Math/MathHelper.bf index 3a7ad5a..9b31db3 100644 --- a/GlitchyEngine/src/Math/MathHelper.bf +++ b/GlitchyEngine/src/Math/MathHelper.bf @@ -77,5 +77,11 @@ namespace GlitchyEngine.Math { return Math.Abs(value) < epsilon; } + + /// Returns the point that lies on the unit circle at the specified angle. + public static Vector2 CirclePoint(float angle, float radius = 1.0f) + { + return .(Math.Cos(angle), Math.Sin(angle)) * radius; + } } } diff --git a/GlitchyEngine/src/Renderer/DebugRenderer.bf b/GlitchyEngine/src/Renderer/DebugRenderer.bf index 32966cc..d7de1da 100644 --- a/GlitchyEngine/src/Renderer/DebugRenderer.bf +++ b/GlitchyEngine/src/Renderer/DebugRenderer.bf @@ -1,5 +1,6 @@ using GlitchyEngine.Math; using GlitchyEngine.World; +using System; namespace GlitchyEngine.Renderer { @@ -47,6 +48,145 @@ namespace GlitchyEngine.Renderer Renderer.DrawLine(.Zero, .Up, .Lime, transform); Renderer.DrawLine(.Zero, .Forward, .Blue, transform); } + + //static GeometryBinding _frustumGeometry; + //static VertexBuffer _frustumVertices; + + /** + * Draws the view frustum for the given camera transform and projection. + * @param worldTransform The cameras transform matrix. + * @param projection The cameras projection matrix. + * @param observerVP The view projection of the rendering camera. + * @param color The color of the frustum. + */ + public static void DrawViewFrustum(Matrix worldTransform, Matrix projection, Matrix observerVP, ColorRGBA color = .Red) + { + /*if (_frustumGeometry == null) + { + _frustumGeometry = new GeometryBinding(); + _frustumGeometry.SetPrimitiveTopology(.LineList); + + _frustumVertices = new VertexBuffer(typeof(Vector4), 8, .Dynamic, .Write); + _frustumGeometry.SetVertexBufferSlot(_frustumVertices, 0); + + using (IndexBuffer indexBuffer = new IndexBuffer(24, .Immutable)) + { + uint16[24] indices = .( + 0, 1, + 1, 2, + 2, 3, + 3, 0, + + 4, 5, + 5, 6, + 6, 7, + 7, 4, + + 0, 4, + 1, 5, + 2, 6, + 3, 7); + + indexBuffer.SetData(indices); + + _frustumGeometry.SetIndexBuffer(indexBuffer); + } + }*/ + + uint16[24] indices = .( + 0, 1, + 1, 2, + 2, 3, + 3, 0, + + 4, 5, + 5, 6, + 6, 7, + 7, 4, + + 0, 4, + 1, 5, + 2, 6, + 3, 7); + + Vector4[8] corners; + // Perspective + if(projection.V._43 != 0.0f) + { + // near plane for perspective projection, far plane if reversed + float d1 = -projection.V._34 / projection.V._33; + + float d2 = projection.V._34 / (1.0f - projection.V._33); + + float gOverS = projection.V._11; + float g = projection.V._22; + + //var corners = //(Vector4*)&_vbFrustum.Data; + + if(Math.Abs(d1) >= 10000) + { + d1 = 10.0f; + corners[0] = .( d1 / gOverS, d1 / g , d1, 0.0f); + corners[1] = .( corners[0].X, -corners[0].Y, d1, 0.0f); + corners[2] = .(-corners[0].X, -corners[0].Y, d1, 0.0f); + corners[3] = .(-corners[0].X, corners[0].Y, d1, 0.0f); + } + else + { + corners[0] = .( d1 / gOverS, d1 / g , d1, 1.0f); + corners[1] = .( corners[0].X, -corners[0].Y, d1, 1.0f); + corners[2] = .(-corners[0].X, -corners[0].Y, d1, 1.0f); + corners[3] = .(-corners[0].X, corners[0].Y, d1, 1.0f); + } + + if(Math.Abs(d2) >= 10000) + { + d2 = 10.0f; + + corners[4] = .( d2 / gOverS, d2 / g , d2, 0.0f); + corners[5] = .( corners[4].X, -corners[4].Y, d2, 0.0f); + corners[6] = .(-corners[4].X, -corners[4].Y, d2, 0.0f); + corners[7] = .(-corners[4].X, corners[4].Y, d2, 0.0f); + } + else + { + corners[4] = .( d2 / gOverS, d2 / g , d2, 1.0f); + corners[5] = .( corners[4].X, -corners[4].Y, d2, 1.0f); + corners[6] = .(-corners[4].X, -corners[4].Y, d2, 1.0f); + corners[7] = .(-corners[4].X, corners[4].Y, d2, 1.0f); + } + } + else + { + float l = -(projection.V._14 + 1.0f) / projection.V._11; + float r = (1.0f - projection.V._14) / projection.V._11; + + float t = -(projection.V._24 + 1.0f) / projection.V._22; + float b = (1.0f - projection.V._24) / projection.V._22; + + float n = -projection.V._34 / projection.V._33; + float f = (1 - projection.V._34) / projection.V._33; + + //var corners = (Vector4*)&_vbFrustum.Data; + corners[0] = .(r, t, n, 1.0f); + corners[1] = .(r, b, n, 1.0f); + corners[2] = .(l, b, n, 1.0f); + corners[3] = .(l, t, n, 1.0f); + + corners[4] = .(r, t, f, 1.0f); + corners[5] = .(r, b, f, 1.0f); + corners[6] = .(l, b, f, 1.0f); + corners[7] = .(l, t, f, 1.0f); + } + + for (int i = 0; i < indices.Count; i += 2) + { + uint16 index0 = indices[i]; + uint16 index1 = indices[i + 1]; + + Renderer.DrawLine(corners[index0], corners[index1], color, worldTransform, observerVP); + } + } public static void Render(EcsWorld world) { diff --git a/GlitchyEngine/src/Renderer/Renderer.bf b/GlitchyEngine/src/Renderer/Renderer.bf index e434028..ac5cdd9 100644 --- a/GlitchyEngine/src/Renderer/Renderer.bf +++ b/GlitchyEngine/src/Renderer/Renderer.bf @@ -527,7 +527,7 @@ namespace GlitchyEngine.Renderer * @param color The color of the line. * @param transform A transform matrix transforming the line. */ - public static void DrawLine(Vector3 start, Vector3 end, Color color, Matrix transform) + public static void DrawLine(Vector3 start, Vector3 end, ColorRGBA color, Matrix transform) { DrawLine(Vector4(start, 1.0f), Vector4(end, 1.0f), color, transform); } @@ -537,7 +537,7 @@ namespace GlitchyEngine.Renderer * @param direction The direction of the ray. * @param color The color of the ray. */ - public static void DrawRay(Vector3 start, Vector3 direction, Color color) + public static void DrawRay(Vector3 start, Vector3 direction, ColorRGBA color) { DrawLine(Vector4(start, 1.0f), Vector4(direction, 0.0f), color, .Identity); } @@ -548,7 +548,7 @@ namespace GlitchyEngine.Renderer * @param color The color of the ray. * @param transform A transform matrix transforming the ray. */ - public static void DrawRay(Vector3 start, Vector3 direction, Color color, Matrix transform) + public static void DrawRay(Vector3 start, Vector3 direction, ColorRGBA color, Matrix transform) { DrawLine(Vector4(start, 1.0f), Vector4(direction, 0.0f), color, transform); } @@ -559,7 +559,7 @@ namespace GlitchyEngine.Renderer * @param color The color of the line. * @param transform A transform matrix transforming the line. */ - public static void DrawLine(Vector4 start, Vector4 end, Color color, Matrix transform) + public static void DrawLine(Vector4 start, Vector4 end, ColorRGBA color, Matrix transform) { Debug.Profiler.ProfileRendererFunction!(); @@ -572,5 +572,26 @@ namespace GlitchyEngine.Renderer LineGeometry.Bind(); RenderCommand.DrawIndexed(LineGeometry); } + + /** @brief Draws a line. + * @param start The start point of the line. + * @param end The end point of the line. + * @param color The color of the line. + * @param transform A transform matrix transforming the line. + * @param viewProjection The observing cameras viewprojection + */ + public static void DrawLine(Vector4 start, Vector4 end, ColorRGBA color, Matrix transform, Matrix viewProjection) + { + Debug.Profiler.ProfileRendererFunction!(); + + LineVertices.SetData(Vector4[2](start, end), 0, .WriteDiscard); + LineEffect.Variables["ViewProjection"].SetData(viewProjection * transform); + LineEffect.Variables["Color"].SetData(color); + + LineEffect.Bind(_context); + + LineGeometry.Bind(); + RenderCommand.DrawIndexed(LineGeometry); + } } } diff --git a/GlitchyEngine/src/Renderer/Renderer2D.bf b/GlitchyEngine/src/Renderer/Renderer2D.bf index 837d7a0..1fccfc6 100644 --- a/GlitchyEngine/src/Renderer/Renderer2D.bf +++ b/GlitchyEngine/src/Renderer/Renderer2D.bf @@ -781,7 +781,7 @@ namespace GlitchyEngine.Renderer public static void DrawQuad(Matrix transform, SubTexture2D texture, ColorRGBA color = .White) { - DrawQuad(transform, texture.Texture, .White, texture.TexCoords); + DrawQuad(transform, texture.Texture, color, texture.TexCoords); } // Subtex + Texcoords diff --git a/GlitchyEngine/src/World/EditorCamera.bf b/GlitchyEngine/src/World/EditorCamera.bf index b6f7626..5386477 100644 --- a/GlitchyEngine/src/World/EditorCamera.bf +++ b/GlitchyEngine/src/World/EditorCamera.bf @@ -219,8 +219,8 @@ namespace GlitchyEngine.World float rotY = mouseDelta.X * _cameraRotationSpeedX; float rotX = mouseDelta.Y * _cameraRotationSpeedY; - - if (MouseCooldown == 0 && rotY != 0 && rotX != 0) + + if (MouseCooldown == 0) { Vector3 rotationEuler = RotationEuler + Vector3(rotX, rotY, 0); _rotation = Quaternion.FromEulerAngles(rotationEuler.Y, rotationEuler.X, rotationEuler.Z); @@ -298,7 +298,8 @@ namespace GlitchyEngine.World private void UpdateProjection() mut { - _projection = Matrix.InfinitePerspectiveProjection(_fovY, _aspectRatio, _nearPlane); + //_projection = Matrix.InfinitePerspectiveProjection(_fovY, _aspectRatio, _nearPlane); + _projection = Matrix.PerspectiveProjection(_fovY, _aspectRatio, _nearPlane, 10000); } public void OnViewportResize(uint32 sizeX, uint32 sizeY) mut diff --git a/GlitchyEngine/src/World/Scene.bf b/GlitchyEngine/src/World/Scene.bf index 960769c..f0136fd 100644 --- a/GlitchyEngine/src/World/Scene.bf +++ b/GlitchyEngine/src/World/Scene.bf @@ -111,7 +111,7 @@ namespace GlitchyEngine.World } } - public void UpdateEditor(GameTime gameTime, EditorCamera camera, RenderTarget2D viewportTarget) + public void UpdateEditor(GameTime gameTime, EditorCamera camera, RenderTarget2D viewportTarget, delegate void() DebugDraw3D, delegate void() DrawDebug2D) { Debug.Profiler.ProfileRendererFunction!(); @@ -132,16 +132,26 @@ namespace GlitchyEngine.World Renderer.Submit(light.SceneLight, transform.WorldTransform); } + DebugDraw3D(); + Renderer.EndScene(); + // TODO: alphablending + // Sprite renderer - Renderer2D.BeginScene(camera); + Renderer2D.BeginScene(camera, .BackToFront); for (var (entity, transform, sprite) in _ecsWorld.Enumerate()) { Renderer2D.DrawQuad(transform.WorldTransform, sprite.Sprite, sprite.Color); } + Renderer2D.EndScene(); + + Renderer2D.BeginScene(camera, .BackToFront); + + DrawDebug2D(); + Renderer2D.EndScene(); viewportTarget.ReleaseRef();