diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-09-04 13:36:13 +0000 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-09-04 13:36:13 +0000 |
| commit | e33ef6ca476fb9db5e4302f3af05592e29370b74 (patch) | |
| tree | 631bfae1ee86228ff8b17f1ace6c146ad3c4d406 | |
| parent | 73688f568ca5bedd6763094318034898546cf5cd (diff) | |
wip
| -rw-r--r-- | CrowWindow/CrowWindow.csproj | 31 | ||||
| -rw-r--r-- | CrowWindow/shaders/simpletexture.frag | 14 | ||||
| -rw-r--r-- | CrowWindow/src/FSQPipeline.cs | 41 | ||||
| -rw-r--r-- | CrowWindow/src/VkCrowWindow.cs | 277 | ||||
| -rwxr-xr-x | clean.sh | 2 | ||||
| -rw-r--r-- | data/models/chess.glb | bin | 7043884 -> 5164648 bytes | |||
| -rw-r--r-- | src/LogViewerWidget.cs | 185 | ||||
| -rw-r--r-- | src/Piece.cs | 2 | ||||
| -rw-r--r-- | src/VkChess.cs | 186 | ||||
| -rw-r--r-- | src/deferredPbrRenderer.cs | 2 | ||||
| -rw-r--r-- | ui/chess.style | 12 | ||||
| -rw-r--r-- | ui/slider.tmp | 7 | ||||
| -rw-r--r-- | ui/winLog.crow | 11 | ||||
| -rw-r--r-- | ui/winOptions.crow (renamed from ui/main.crow) | 24 | ||||
| -rw-r--r-- | vkChess.net.csproj | 9 | ||||
| -rw-r--r-- | vkChess.net.sln | 6 |
16 files changed, 361 insertions, 448 deletions
diff --git a/CrowWindow/CrowWindow.csproj b/CrowWindow/CrowWindow.csproj deleted file mode 100644 index d330cc5..0000000 --- a/CrowWindow/CrowWindow.csproj +++ /dev/null @@ -1,31 +0,0 @@ -<Project Sdk="Microsoft.NET.Sdk"> - - <PropertyGroup> - <AssemblyName>CrowWindow</AssemblyName> - <TargetFrameworks>netstandard2.1</TargetFrameworks> - <IncludeDefaultNoneItems>false</IncludeDefaultNoneItems> - <Description>vke.net addon to creaet a vulkan window with C.R.O.W. gui support.</Description> - <PackageTags>vulkan gui ui c# vke.net</PackageTags> - <License>MIT</License> - <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <OutputType>Library</OutputType> - <OutputPath>$(SolutionDir)build\$(Configuration)\</OutputPath> - <IntermediateOutputPath>$(SolutionDir)build\obj\$(Configuration)\</IntermediateOutputPath> - - <EnableDefaultCompileItems>false</EnableDefaultCompileItems> - </PropertyGroup> - - <ItemGroup> - <PackageReference Include="Crow" Version="0.9.5-beta" /> - <PackageReference Include="vke" Version="0.2.0-beta" /> - <PackageReference Include="SpirVTasks" Version="0.1.44" /> - </ItemGroup> - - <ItemGroup> - <Compile Include="src\**\*.cs" /> - </ItemGroup> - - <ItemGroup> - <GLSLShader Include="shaders\**\*.frag;shaders\**\*.vert;shaders\**\*.comp;shaders\**\*.geom" /> - </ItemGroup> -</Project> diff --git a/CrowWindow/shaders/simpletexture.frag b/CrowWindow/shaders/simpletexture.frag deleted file mode 100644 index 95cab5f..0000000 --- a/CrowWindow/shaders/simpletexture.frag +++ /dev/null @@ -1,14 +0,0 @@ -#version 450 - -#extension GL_ARB_separate_shader_objects : enable -#extension GL_ARB_shading_language_420pack : enable - -layout (set = 0, binding = 0) uniform sampler2D samplerColor; - -layout (location = 0) in vec2 inUV; -layout (location = 0) out vec4 outFragColor; - -void main() -{ - outFragColor = texture(samplerColor, inUV); -} diff --git a/CrowWindow/src/FSQPipeline.cs b/CrowWindow/src/FSQPipeline.cs deleted file mode 100644 index 6956a89..0000000 --- a/CrowWindow/src/FSQPipeline.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -using System; -using System.Numerics; -using vke; -using Vulkan; - -namespace vke { - - public class FSQPipeline : GraphicPipeline { - public static string FragPath = "#CrowWindow.simpletexture.frag.spv"; - public FSQPipeline (RenderPass renderPass, PipelineLayout pipelineLayout, int attachment = 0, PipelineCache pipelineCache = null) - : base (renderPass, pipelineCache, "FSQ pipeline") { - - using (GraphicPipelineConfig cfg = GraphicPipelineConfig.CreateDefault (VkPrimitiveTopology.TriangleList, this.RenderPass.Samples, false)) { - cfg.RenderPass = RenderPass; - cfg.Layout = pipelineLayout; - cfg.AddShader (Dev, VkShaderStageFlags.Vertex, "#vke.FullScreenQuad.vert.spv"); - cfg.AddShader (Dev, VkShaderStageFlags.Fragment, FragPath); - cfg.multisampleState.rasterizationSamples = Samples; - - cfg.blendAttachments[attachment] = new VkPipelineColorBlendAttachmentState (true); - - layout = cfg.Layout; - - init (cfg); - } - } - - public virtual void RecordDraw (CommandBuffer cmd) { - Bind (cmd); - cmd.Draw (3, 1, 0, 0); - } - - protected override void Dispose (bool disposing) { - base.Dispose (disposing); - } - } - -} diff --git a/CrowWindow/src/VkCrowWindow.cs b/CrowWindow/src/VkCrowWindow.cs deleted file mode 100644 index 2ea66e7..0000000 --- a/CrowWindow/src/VkCrowWindow.cs +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright (c) 2019 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> -// -// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) -using System; -using Glfw; -using Vulkan; -using Crow; -using System.Threading; - -namespace vke { - /// <summary> - /// Vulkan context with Crow enabled window. - /// Crow vector drawing is handled with Cairo Image on an Host mapped vulkan image. - /// This is an easy way to have GUI in my samples with low GPU cost. Most of the ui - /// is cached on cpu memory images. - /// </summary> - public class CrowWindow : VkWindow, IValueChange { - #region IValueChange implementation - public event EventHandler<ValueChangeEventArgs> ValueChanged; - public virtual void NotifyValueChanged (string MemberName, object _value) - { - ValueChanged?.Invoke (this, new ValueChangeEventArgs (MemberName, _value)); - } - #endregion - - protected CrowWindow() : base("vkChess.net", 800, 600,false) {} - public bool MouseIsInInterface => - iFace.HoverWidget != null; - - protected FSQPipeline fsqPl; - DescriptorPool dsPool; - protected DescriptorSet descSet; - CommandPool cmdPoolCrow; - PrimaryCommandBuffer cmdUpdateCrow; - Image crowImage; - HostBuffer crowBuffer; - protected Interface iFace; - protected RenderPass renderPass; - - volatile bool running; - - - VkDescriptorSetLayoutBinding dslBinding = new VkDescriptorSetLayoutBinding (0, VkShaderStageFlags.Fragment, VkDescriptorType.CombinedImageSampler); - FrameBuffers frameBuffers; - - protected override void initVulkan () { - base.initVulkan (); - - iFace = new Interface ((int)Width, (int)Height, WindowHandle); - iFace.Init (); - - CreateRenderPass (); - - fsqPl = new FSQPipeline (renderPass, - new PipelineLayout (dev, new DescriptorSetLayout (dev, dslBinding))); - - cmdPoolCrow = new CommandPool (presentQueue, VkCommandPoolCreateFlags.ResetCommandBuffer); - cmdUpdateCrow = cmdPoolCrow.AllocateCommandBuffer (); - - dsPool = new DescriptorPool (dev, 1, new VkDescriptorPoolSize (VkDescriptorType.CombinedImageSampler)); - descSet = dsPool.Allocate (fsqPl.Layout.DescriptorSetLayouts[0]); - - Thread ui = new Thread (crowThread); - ui.IsBackground = true; - ui.Start (); - } - protected virtual void CreateRenderPass () { - //renderPass = new RenderPass (dev, swapChain.ColorFormat, VkSampleCountFlags.SampleCount1); - renderPass = new RenderPass (dev, VkSampleCountFlags.SampleCount1); - renderPass.AddAttachment (swapChain.ColorFormat, VkImageLayout.PresentSrcKHR, VkSampleCountFlags.SampleCount1, - VkAttachmentLoadOp.Load, VkAttachmentStoreOp.DontCare, VkImageLayout.ColorAttachmentOptimal);//final outpout - SubPass subpass0 = new SubPass (); - subpass0.AddColorReference (0, VkImageLayout.ColorAttachmentOptimal); - renderPass.AddSubpass (subpass0); - renderPass.AddDependency (Vk.SubpassExternal, 0, - VkPipelineStageFlags.BottomOfPipe, VkPipelineStageFlags.ColorAttachmentOutput, - VkAccessFlags.MemoryRead, VkAccessFlags.ColorAttachmentWrite); - renderPass.AddDependency (0, Vk.SubpassExternal, - VkPipelineStageFlags.ColorAttachmentOutput, VkPipelineStageFlags.BottomOfPipe, - VkAccessFlags.ColorAttachmentWrite, VkAccessFlags.MemoryRead); - } - - - protected override void onMouseMove (double xPos, double yPos) - { - if (iFace.OnMouseMove ((int)xPos, (int)yPos)) - return; - //base.onMouseMove (xPos, yPos); - } - protected override void onMouseButtonDown (MouseButton button) { - if (iFace.OnMouseButtonDown (button)) - return; - base.onMouseButtonDown (button); - } - protected override void onMouseButtonUp (MouseButton button) - { - if (iFace.OnMouseButtonUp (button)) - return; - base.onMouseButtonUp (button); - } - protected override void onScroll (double xOffset, double yOffset) { - if (iFace.OnMouseWheelChanged ((float)yOffset)) - return; - base.onScroll (xOffset, yOffset); - } - protected override void onChar (CodePoint cp) { - if (iFace.OnKeyPress (cp.ToChar())) - return; - base.onChar (cp); - } - protected override void onKeyUp (Key key, int scanCode, Modifier modifiers) { - if (iFace.OnKeyUp (key)) - return; - base.onKeyUp (key, scanCode, modifiers); - } - protected override void onKeyDown (Key key, int scanCode, Modifier modifiers) { - if (iFace.OnKeyDown (key)) - return; - base.onKeyDown (key, scanCode, modifiers); - } - - protected override void render () { - - int idx = swapChain.GetNextImage (); - if (idx < 0) { - OnResize (); - return; - } - - if (cmds[idx] == null) - return; - - drawFence.Wait (); - drawFence.Reset (); - - if (Monitor.IsEntered (iFace.UpdateMutex)) - Monitor.Exit (iFace.UpdateMutex); - - presentQueue.Submit (cmds[idx], swapChain.presentComplete, drawComplete[idx], drawFence); - presentQueue.Present (swapChain, drawComplete[idx]); - } - - public override void Update () { - if (iFace.IsDirty) { - drawFence.Wait (); - drawFence.Reset (); - Monitor.Enter (iFace.UpdateMutex); - presentQueue.Submit (cmdUpdateCrow, default, default, drawFence); - iFace.IsDirty = false; - } - - NotifyValueChanged ("fps", fps); - } - - protected override void OnResize () - { - base.OnResize (); - dev.WaitIdle (); - initCrowSurface (); - iFace.ProcessResize (new Rectangle (0, 0, (int)Width, (int)Height)); - - frameBuffers?.Dispose(); - frameBuffers = renderPass.CreateFrameBuffers(swapChain); - } - - protected virtual void recordUICmd (PrimaryCommandBuffer cmd, int imageIndex) { - renderPass.Begin(cmd, frameBuffers[imageIndex]); - fsqPl.BindDescriptorSet (cmd, descSet, 0); - fsqPl.RecordDraw (cmd); - renderPass.End (cmd); - } - - void crowThread () { - while (iFace.surf == null) { - Thread.Sleep (10); - } - running = true; - while (running) { - iFace.Update (); - Thread.Sleep (10); - } - } - void initCrowSurface () { - lock (iFace.UpdateMutex) { - iFace.surf?.Dispose (); - crowImage?.Dispose (); - crowBuffer?.Dispose (); - - crowBuffer = new HostBuffer (dev, VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst, Width * Height * 4, true); - - crowImage = new Image (dev, VkFormat.B8g8r8a8Unorm, VkImageUsageFlags.Sampled | VkImageUsageFlags.TransferDst, - VkMemoryPropertyFlags.DeviceLocal, Width, Height, VkImageType.Image2D, VkSampleCountFlags.SampleCount1, VkImageTiling.Linear); - crowImage.CreateView (VkImageViewType.ImageView2D, VkImageAspectFlags.Color); - crowImage.CreateSampler (VkFilter.Nearest, VkFilter.Nearest, VkSamplerMipmapMode.Nearest, VkSamplerAddressMode.ClampToBorder); - crowImage.Descriptor.imageLayout = VkImageLayout.ShaderReadOnlyOptimal; - - DescriptorSetWrites dsw = new DescriptorSetWrites (descSet, dslBinding); - dsw.Write (dev, crowImage.Descriptor); - - iFace.surf = iFace.CreateSurfaceForData (crowBuffer.MappedData, (int)Width, (int)Height); - /*iFace.surf = new Crow.Cairo.ImageSurface (crowBuffer.MappedData, Crow.Cairo.Format.ARGB32, - (int)Width, (int)Height, (int)Width * 4);*/ - - PrimaryCommandBuffer cmd = cmdPoolCrow.AllocateAndStart (VkCommandBufferUsageFlags.OneTimeSubmit); - crowImage.SetLayout (cmd, VkImageAspectFlags.Color, VkImageLayout.Preinitialized, VkImageLayout.ShaderReadOnlyOptimal); - presentQueue.EndSubmitAndWait (cmd, true); - - recordUpdateCrowCmd (); - } - } - - /// <summary> - /// command buffer must have been reseted - /// </summary> - void recordUpdateCrowCmd () { - cmdPoolCrow.Reset (); - cmdUpdateCrow.Start (); - crowImage.SetLayout (cmdUpdateCrow, VkImageAspectFlags.Color, - VkImageLayout.ShaderReadOnlyOptimal, VkImageLayout.TransferDstOptimal, - VkPipelineStageFlags.FragmentShader, VkPipelineStageFlags.Transfer); - - crowBuffer.CopyTo (cmdUpdateCrow, crowImage, VkImageLayout.ShaderReadOnlyOptimal); - - crowImage.SetLayout (cmdUpdateCrow, VkImageAspectFlags.Color, - VkImageLayout.TransferDstOptimal, VkImageLayout.ShaderReadOnlyOptimal, - VkPipelineStageFlags.Transfer, VkPipelineStageFlags.FragmentShader); - cmdUpdateCrow.End (); - } - - - protected void loadWindow (string path, object dataSource = null) { - try { - Widget w = iFace.FindByName (path); - if (w != null) { - iFace.PutOnTop (w); - return; - } - w = iFace.Load (path); - w.Name = path; - w.DataSource = dataSource; - - } catch (Exception ex) { - System.Diagnostics.Debug.WriteLine (ex); - } - } - protected void loadIMLFragment (string imlFragment, object dataSource = null) { - iFace.LoadIMLFragment (imlFragment).DataSource = dataSource; - } - protected T loadIMLFragment<T> (string imlFragment, object dataSource = null) { - Widget tmp = iFace.LoadIMLFragment (imlFragment); - tmp.DataSource = dataSource; - return (T)Convert.ChangeType (tmp,typeof(T)); - } - protected void closeWindow (string path) { - Widget g = iFace.FindByName (path); - if (g != null) - iFace.DeleteWidget (g); - } - - - protected override void Dispose (bool disposing) { - dev.WaitIdle (); - - running = false; - frameBuffers?.Dispose(); - fsqPl.Dispose (); - dsPool.Dispose (); - cmdPoolCrow.Dispose (); - crowImage?.Dispose (); - crowBuffer?.Dispose (); - iFace.Dispose (); - - base.Dispose (disposing); - } - - } -} diff --git a/clean.sh b/clean.sh deleted file mode 100755 index d39df8f..0000000 --- a/clean.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -rm -fr build && find . -iname bin -o -iname obj | xargs rm -rf diff --git a/data/models/chess.glb b/data/models/chess.glb Binary files differindex fc9a8c6..bb96743 100644 --- a/data/models/chess.glb +++ b/data/models/chess.glb diff --git a/src/LogViewerWidget.cs b/src/LogViewerWidget.cs new file mode 100644 index 0000000..5dbb511 --- /dev/null +++ b/src/LogViewerWidget.cs @@ -0,0 +1,185 @@ +// Copyright (c) 2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.Xml.Serialization; +using System.ComponentModel; +using System.Collections; +using Crow.Drawing; + +namespace Crow +{ + public enum LogLevel + { + Minimal, Normal, Full, Debug + } + public enum LogType { + Low, + Normal, + High, + Debug, + Warning, + Error, + Custom1, + Custom2, + Custom3, + } + public class LogEntry { + public LogType Type; + public string msg; + public LogEntry (LogType type, string message) { + Type = type; + msg = message; + } + public override string ToString() => msg; + } + public class LogViewerWidget : ScrollingObject + { + ObservableList<LogEntry> lines; + bool scrollOnOutput; + int visibleLines = 1; + FontExtents fe; + + [DefaultValue(true)] + public virtual bool ScrollOnOutput { + get { return scrollOnOutput; } + set { + if (scrollOnOutput == value) + return; + scrollOnOutput = value; + NotifyValueChanged ("ScrollOnOutput", scrollOnOutput); + + } + } + public virtual ObservableList<LogEntry> Lines { + get { return lines; } + set { + if (lines == value) + return; + if (lines != null) { + lines.ListAdd -= Lines_ListAdd; + lines.ListRemove -= Lines_ListRemove; + lines.ListClear -= Lines_ListClear; + } + lines = value; + if (lines != null) { + lines.ListAdd += Lines_ListAdd; + lines.ListRemove += Lines_ListRemove; + lines.ListClear += Lines_ListClear; + } + NotifyValueChanged ("Lines", lines); + RegisterForGraphicUpdate (); + } + } + void Lines_ListClear (object sender, EventArgs e) + { + MaxScrollY = MaxScrollX = 0; + } + + void Lines_ListAdd (object sender, ListChangedEventArg e) + { + // try + // { + MaxScrollY = lines.Count - visibleLines; + if (scrollOnOutput) + ScrollY = MaxScrollY; + + // } + // catch (System.Exception ex) + // { + // Console.WriteLine ($"list add valueChange handler bug:{ex}"); + // } + } + + void Lines_ListRemove (object sender, ListChangedEventArg e) + { + MaxScrollY = lines.Count - visibleLines; + } + + public override void OnLayoutChanges (LayoutingType layoutType) + { + base.OnLayoutChanges (layoutType); + + if (layoutType == LayoutingType.Height) { + using (ImageSurface img = new ImageSurface (Format.Argb32, 10, 10)) { + using (Context gr = new Context (img)) { + //Cairo.FontFace cf = gr.GetContextFontFace (); + + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + + fe = gr.FontExtents; + } + } + visibleLines = (int)Math.Floor ((double)ClientRectangle.Height / fe.Height); + MaxScrollY = lines == null ? 0 : lines.Count - visibleLines; + } + } + protected override void onDraw (Context gr) + { + base.onDraw (gr); + + if (lines == null) + return; + + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + + Rectangle r = ClientRectangle; + + + double y = ClientRectangle.Y; + double x = ClientRectangle.X - ScrollX; + + lock (lines) { + for (int i = 0; i < visibleLines; i++) { + if (i + ScrollY >= Lines.Count) + break; + //if ((lines [i + Scroll] as string).StartsWith ("error", StringComparison.OrdinalIgnoreCase)) { + // errorFill.SetAsSource (gr); + // gr.Rectangle (x, y, (double)r.Width, fe.Height); + // gr.Fill (); + // Foreground.SetAsSource (gr); + //} + LogEntry le = lines[i+ScrollY]; + switch (le.Type) { + case LogType.Low: + gr.SetSource (Colors.DimGrey); + break; + case LogType.Normal: + gr.SetSource (Colors.Grey); + break; + case LogType.High: + gr.SetSource (Colors.White); + break; + case LogType.Debug: + gr.SetSource (Colors.Yellow); + break; + case LogType.Warning: + gr.SetSource (Colors.Orange); + break; + case LogType.Error: + gr.SetSource (Colors.Red); + break; + case LogType.Custom1: + gr.SetSource (Colors.Cyan); + break; + case LogType.Custom2: + gr.SetSource (Colors.Green); + break; + case LogType.Custom3: + gr.SetSource (Colors.LightPink); + break; + } + gr.MoveTo (x, y + fe.Ascent); + gr.ShowText (le.msg); + y += fe.Height; + gr.Fill (); + } + } + } + + } +} + diff --git a/src/Piece.cs b/src/Piece.cs index 7dc093c..af990ec 100644 --- a/src/Piece.cs +++ b/src/Piece.cs @@ -46,7 +46,7 @@ namespace vkChess { [DebuggerDisplay("{DebuggerDisplay}")] public class Piece { - static Vector4 blackColor = new Vector4(0.2f, 0.2f, 0.2f, 1f); + static Vector4 blackColor = new Vector4(0.03f, 0.03f, 0.03f, 1f); static Vector4 whiteColor = new Vector4(1.0f, 1.0f, 1.0f, 1f); public static HostBuffer<VkChess.InstanceData> instanceBuff; public static VkChess.InstanceData[] boardDatas; diff --git a/src/VkChess.cs b/src/VkChess.cs index 700dc02..0cb20dd 100644 --- a/src/VkChess.cs +++ b/src/VkChess.cs @@ -42,12 +42,11 @@ namespace vkChess Instance.VALIDATION = true; //Instance.RENDER_DOC_CAPTURE = true; //SwapChain.PREFERED_FORMAT = VkFormat.B8g8r8a8Unorm; - DeferredPbrRenderer.NUM_SAMPLES = VkSampleCountFlags.SampleCount1; DeferredPbrRenderer.MAX_MATERIAL_COUNT = 5; DeferredPbrRenderer.MRT_FORMAT = VkFormat.R16g16b16a16Sfloat; DeferredPbrRenderer.HDR_FORMAT = VkFormat.R16g16b16a16Sfloat; - PbrModelTexArray.TEXTURE_DIM = 256; - ShadowMapRenderer.SHADOWMAP_SIZE = 512; + PbrModelTexArray.TEXTURE_DIM = 512; + ShadowMapRenderer.SHADOWMAP_SIZE = 1024; using (VkChess app = new VkChess ()) app.Run (); @@ -86,6 +85,8 @@ namespace vkChess vke.DebugUtils.Messenger dbgmsg; #endif protected override void initVulkan () { + initLog (); + base.initVulkan (); #if DEBUG @@ -114,9 +115,16 @@ namespace vkChess camera.SetPosition (0, 0f, -12.0f); camera.AspectRatio = Width / Height; + DeferredPbrRenderer.NUM_SAMPLES = SampleCount; + renderer = new DeferredPbrRenderer (dev, swapChain, presentQueue, cubemapPathes [0], camera.NearPlane, camera.FarPlane); - dev.WaitIdle (); - renderer.LoadModel (transferQ, "data/models/chess.glb"); + + renderer.matrices.gamma = Gamma; + renderer.matrices.exposure = Exposure; + renderer.matrices.scaleIBLAmbient = IBLAmbient; + renderer.lights[0].color = new Vector4 (LightStrength); + //renderer.LoadModel (transferQ, "data/models/chess.glb"); + renderer.LoadModel (transferQ, "/mnt/devel/vkChess.net/data/models/chess.glb"); camera.Model = Matrix4x4.CreateScale (0.5f);// Matrix4x4.CreateScale(1f / Math.Max(Math.Max(renderer.modelAABB.Width, renderer.modelAABB.Height), renderer.modelAABB.Depth)); UpdateFrequency = 5; @@ -131,7 +139,6 @@ namespace vkChess iFace.Load ("ui/chess.crow").DataSource = this; } - Queue transferQ; protected override void createQueues () { base.createQueues (); @@ -209,6 +216,10 @@ namespace vkChess } public static bool updateInstanceCmds = true; + uint fpsAccum, fpsAccumCpt; + + const int fpsAccumLimit = 20; + public override void Update () { base.Update (); @@ -229,7 +240,17 @@ namespace vkChess if (Animation.HasAnimations) renderer.shadowMapRenderer.updateShadowMap = true; - animationSteps = 5 + (int)fps / 5; + fpsAccum += fps; + fpsAccumCpt++; + if (fpsAccumCpt == fpsAccumLimit) { + uint fpsMean = fpsAccum / fpsAccumLimit; + uint curFrameTime = 1000 / fpsMean; + if (curFrameTime > UpdateFrequency) + animationSteps = 300 / (int)curFrameTime; + else + animationSteps = 60; + fpsAccum = fpsAccumCpt = 0; + } Animation.ProcessAnimations (); //Piece.FlushHostBuffer (); @@ -306,7 +327,7 @@ namespace vkChess double diffX = lastMouseX - xPos; double diffY = lastMouseY - yPos; - if (GetButton (MouseButton.Right) == InputAction.Press) { + if (GetButton (MouseButton.Middle) == InputAction.Press) { camera.Rotate ((float)-diffY, (float)-diffX); updateViewRequested = true; return; @@ -344,9 +365,9 @@ namespace vkChess }else NotifyValueChanged ("DebugCurCell", ""); } - protected override void onMouseButtonDown (Glfw.MouseButton button) { + protected override void onMouseButtonDown (MouseButton button) { base.onMouseButtonDown (button); - if (MouseIsInInterface) + if (MouseIsInInterface || button != MouseButton.Left) return; //if (waitAnimationFinished) { @@ -420,6 +441,12 @@ namespace vkChess case Glfw.Key.F3: checkBoardIntegrity (); break; + case Glfw.Key.F4: + if (modifiers.HasFlag (Modifier.Shift)) + loadCurrentGame (); + else + saveCurrentGame (); + break; case Glfw.Key.S: syncStockfish (); sendToStockfish ("go"); @@ -436,7 +463,7 @@ namespace vkChess break; case Glfw.Key.R: CurrentState = GameState.Play; - resetBoard (true); + resetBoard (); break; //case Glfw.Key.Enter: //plDebugDraw.UpdateLine (4, Vector3.Zero, vMouse, 1, 0, 1); @@ -528,17 +555,14 @@ namespace vkChess } public CommandGroup Commands => new CommandGroup ( - new Command (()=>loadWindow ("ui/newGame.crow", this)) {Caption = "New Game"}, - new Command (()=>loadWindow ("ui/main.crow", this)) {Caption = "Options"}, - new Command (()=>undo()) {Caption = "Undo"}, - new Command (()=>Close()) {Caption = "Quit"} + new Command ("New Game", ()=>loadWindow ("ui/newGame.crow", this)), + new Command ("Options", ()=>loadWindow ("ui/winOptions.crow", this)), +#if DEBUG + new Command ("Log", ()=>loadWindow ("ui/winLog.crow", this)), +#endif + new Command ("Undo", ()=>undo()), + new Command ("Redo", ()=>Close()) ); - void onNewGameClick (object sender, MouseButtonEventArgs e) { - loadWindow ("ui/newGame.crow", this); - } - void onOptionsClick (object sender, MouseButtonEventArgs e) { - loadWindow ("ui/main.crow", this); - } void onNewWhiteGame (object sender, MouseButtonEventArgs e) { closeWindow ("ui/newGame.crow"); @@ -601,55 +625,77 @@ namespace vkChess #region crow public float Gamma { - get { return renderer.matrices.gamma; } + get => Configuration.Global.Get<float> ("Gamma", 1.2f); set { - if (value == renderer.matrices.gamma) + if (value == Gamma) return; + Configuration.Global.Set ("Gamma", value); renderer.matrices.gamma = value; NotifyValueChanged ("Gamma", value); updateViewRequested = true; } } public float Exposure { - get { return renderer.matrices.exposure; } + get => Configuration.Global.Get<float> ("Exposure", 2.0f); set { - if (value == renderer.matrices.exposure) + if (value == Exposure) return; + Configuration.Global.Set ("Exposure", value); renderer.matrices.exposure = value; NotifyValueChanged ("Exposure", value); updateViewRequested = true; } } public float IBLAmbient { - get { return renderer.matrices.scaleIBLAmbient; } + get => Configuration.Global.Get<float> ("IBLAmbient", 0.5f); set { - if (value == renderer.matrices.scaleIBLAmbient) + if (value == IBLAmbient) return; + Configuration.Global.Set ("IBLAmbient", value); renderer.matrices.scaleIBLAmbient = value; NotifyValueChanged ("IBLAmbient", value); updateViewRequested = true; } } public float LightStrength { - get { return renderer.lights [renderer.lightNumDebug].color.X; } + get => Configuration.Global.Get<float> ("LightStrength", 1); set { - if (value == renderer.lights [renderer.lightNumDebug].color.X) + if (value == LightStrength) return; + Configuration.Global.Set ("LightStrength", value); renderer.lights [renderer.lightNumDebug].color = new Vector4 (value); NotifyValueChanged ("LightStrength", value); renderer.uboLights.Update (renderer.lights); } } + public VkSampleCountFlags SampleCount { + get => Configuration.Global.Get<VkSampleCountFlags> ("SampleCount", VkSampleCountFlags.SampleCount1); + set { + if (value == SampleCount) + return; + Configuration.Global.Set ("SampleCount", value); + DeferredPbrRenderer.NUM_SAMPLES = value; + NotifyValueChanged ("SampleCount", value); + } + } #endregion #region LOGS - List<string> logBuffer = new List<string> (); - void AddLog (string msg) { - if (string.IsNullOrEmpty (msg)) + public CommandGroup LogContextMenu; + ObservableList<LogEntry> logs = new ObservableList<LogEntry>(); + public ObservableList<LogEntry> MainLog => logs; + void initLog () { + LogContextMenu = new CommandGroup (new Command("Clear Log", () => ResetLog())); + } + public void Log(LogType type, string message) { + if (string.IsNullOrEmpty (message)) return; - //logBuffer.Add (msg); - Console.WriteLine (msg); - NotifyValueChanged ("LogBuffer", logBuffer); + lock (logs) + logs.Add (new LogEntry(type, message)); + } + public void ResetLog () { + lock (logs) + logs.Clear (); } #endregion @@ -684,10 +730,10 @@ namespace vkChess } } public bool StockfishNotFound { - get { return stockfish == null; } + get => stockfish == null; } public string StockfishPath { - get { return Configuration.Global.Get<string> ("StockfishPath"); } + get => Configuration.Global.Get<string> ("StockfishPath"); set { if (value == StockfishPath) return; @@ -698,7 +744,7 @@ namespace vkChess } } public int AISearchTime { - get { return Configuration.Global.Get<int> ("AISearchTime"); } + get => Configuration.Global.Get<int> ("AISearchTime"); set { if (value == WhitesLevel) return; @@ -708,7 +754,7 @@ namespace vkChess } } public int WhitesLevel { - get { return Configuration.Global.Get<int> ("WhitesLevel"); } + get => Configuration.Global.Get<int> ("WhitesLevel"); set { if (value == WhitesLevel) return; @@ -718,7 +764,7 @@ namespace vkChess } } public int BlacksLevel { - get { return Configuration.Global.Get<int> ("BlacksLevel"); } + get => Configuration.Global.Get<int> ("BlacksLevel"); set { if (value == BlacksLevel) return; @@ -728,7 +774,7 @@ namespace vkChess } } public bool WhitesAreAI { - get { return Configuration.Global.Get<bool> ("WhitesAreAI"); } + get => Configuration.Global.Get<bool> ("WhitesAreAI"); set { if (value == WhitesAreAI) return; @@ -738,7 +784,7 @@ namespace vkChess } } public bool BlacksAreAI { - get { return Configuration.Global.Get<bool> ("BlacksAreAI"); } + get => Configuration.Global.Get<bool> ("BlacksAreAI"); set { if (value == BlacksAreAI) return; @@ -747,16 +793,11 @@ namespace vkChess NotifyValueChanged ("BlacksAreAI", value); } } - string stockfishPositionCommand { - get { - string tmp = "position startpos moves "; - return - StockfishMoves.Count == 0 ? tmp : tmp + StockfishMoves.Aggregate ((i, j) => i + " " + j); - } - } + string stockfishPositionCommand + => StockfishMoves.Count == 0 ? "" : StockfishMoves.Aggregate ((i, j) => i + " " + j); public bool AutoPlayHint { - get { return Configuration.Global.Get<bool> ("AutoPlayHint"); } + get => Configuration.Global.Get<bool> ("AutoPlayHint"); set { if (value == AutoPlayHint) return; @@ -766,9 +807,26 @@ namespace vkChess } public List<String> StockfishMoves { - get { return stockfishMoves; } + get => stockfishMoves; set { stockfishMoves = value; } } + void saveCurrentGame() { + Configuration.Global.Set ("CurrentGame", stockfishPositionCommand); + } + void loadCurrentGame() { + string curGame = Configuration.Global.Get<string> ("CurrentGame"); + if (string.IsNullOrEmpty (curGame)) + return; + stockfishMoves = curGame.Split (' ').ToList(); + replaySilently (); + + foreach (Piece p in whites) + p.MoveTo (p.BoardCell, true); + foreach (Piece p in whites) + p.MoveTo (p.BoardCell, true); + + syncStockfish(); + } void initStockfish () { if (stockfish != null) { @@ -807,7 +865,7 @@ namespace vkChess void syncStockfish () { NotifyValueChanged ("StockfishMoves", StockfishMoves); sendToStockfish ("setoption name Skill Level value " + (CurrentPlayer == ChessColor.White ? WhitesLevel.ToString() : BlacksLevel.ToString())); - sendToStockfish (stockfishPositionCommand); + sendToStockfish ($"position startpos moves {stockfishPositionCommand}"); } //void askStockfishIsReady () { // if (waitStockfishIsReady) @@ -818,12 +876,18 @@ namespace vkChess // AddLog ("<= isready"); //} void sendToStockfish (string msg) { - AddLog ("<= " + msg); +#if DEBUG + + Log (LogType.Normal, $"<= {msg}"); +#endif //stockfish.WaitForInputIdle (); stockfish.StandardInput.WriteLine (msg); } void P_Exited (object sender, EventArgs e) { - AddLog ("Stockfish Terminated"); +#if DEBUG + + Log (LogType.High, "Stockfish Terminated"); +#endif } void dataReceived (object sender, DataReceivedEventArgs e) { if (string.IsNullOrEmpty (e.Data)) @@ -834,7 +898,9 @@ namespace vkChess string [] tmp = e.Data.Split (' '); //if (tmp [0] != "readyok") - AddLog ("=> " + e.Data); +#if DEBUG + Log (LogType.Normal, $"=> {e.Data}"); +#endif switch (tmp [0]) { case "readyok": @@ -1446,7 +1512,9 @@ namespace vkChess } void previewBoard (string move) { if (move.EndsWith ("K")) { - AddLog ("Previewing: " + move); +#if DEBUG + Log (LogType.Debug, $"Previewing: {move}"); +#endif move = move.Substring (0, 4); } @@ -1567,7 +1635,9 @@ namespace vkChess Piece p = board [pStart.X, pStart.Y]; if (p == null) { - AddLog ("ERROR: impossible move."); +#if DEBUG + Log (LogType.Error, $"impossible move: {move}"); +#endif return; } @@ -1631,8 +1701,6 @@ namespace vkChess Piece p = board [pCurPos.X, pCurPos.Y]; - CurrentState = GameState.Play; - replaySilently (); Piece pCaptured = board [pCurPos.X, pCurPos.Y]; diff --git a/src/deferredPbrRenderer.cs b/src/deferredPbrRenderer.cs index 1337089..49c0bc9 100644 --- a/src/deferredPbrRenderer.cs +++ b/src/deferredPbrRenderer.cs @@ -129,6 +129,8 @@ namespace vkChess shadowMapRenderer = new ShadowMapRenderer (dev, this, 32); init (nearPlane, farPlane, cubemapPath); + + dev.WaitIdle (); } void init_renderpass () { diff --git a/ui/chess.style b/ui/chess.style index 0c578a1..3ac5666 100644 --- a/ui/chess.style +++ b/ui/chess.style @@ -1,3 +1,5 @@ +ControlHighlight = "DodgerBlue"; +LogFont = "consolas, 10"; icon { Width="14"; @@ -42,6 +44,10 @@ Button { MinimumSize = "80, 30"; Width="Fit"; } +Window { + CornerRadius="5"; + Background="0.1,0.1,0.1,0.8"; +} Slider { Foreground = "Jet"; } @@ -81,4 +87,10 @@ ColorSlider { Focusable="true"; Height="14"; Margin="0"; +} +LightingSlider { + Template = "ui/slider.tmp"; + Height = "40"; + Width = "Stretched"; + CursorSize = "50"; }
\ No newline at end of file diff --git a/ui/slider.tmp b/ui/slider.tmp new file mode 100644 index 0000000..ce0129b --- /dev/null +++ b/ui/slider.tmp @@ -0,0 +1,7 @@ +<?xml version="1.0"?> +<Group Background="DarkGrey" > + <Gauge Height="50%" Foreground="${ControlHighlight}" Background="Onyx" Value="{./Value}" Maximum="{./Maximum}" Minimum="{Minimum}" Orientation="{./Orientation}"/> + <Border Name="Cursor" Background="White" BorderWidth="3" Foreground="Grey" MouseEnter="{Foreground=${ControlHighlight}}" MouseLeave="{Foreground=Grey}" > + <Label Text="{./Value}" Foreground="Black"/> + </Border> +</Group> diff --git a/ui/winLog.crow b/ui/winLog.crow new file mode 100644 index 0000000..4151ee4 --- /dev/null +++ b/ui/winLog.crow @@ -0,0 +1,11 @@ +<?xml version="1.0"?> +<Window Caption="Log" Width="Stretched" Height="20%" VerticalAlignment="Top" > + <VerticalStack RootDataLevel="true" > + <HorizontalStack Spacing="0"> + <LogViewerWidget Name="log" Lines="{MainLog}" Font="${LogFont}" MaxScrollX="1000" ContextCommands="{LogContextMenu}"/> + <ScrollBar Name="scrollbarY" Value="{²../log.ScrollY}" CursorRatio="{../log.ChildHeightRatio}" Maximum="{../log.MaxScrollY}" /> + </HorizontalStack> + <ScrollBar Style="HScrollBar" Name="scrollbarX" Value="{²../log.ScrollX}" Maximum="{../log.MaxScrollX}" SmallIncrement="30"/> + </VerticalStack> +</Window> + diff --git a/ui/main.crow b/ui/winOptions.crow index 4f685ac..8b8e5d9 100644 --- a/ui/main.crow +++ b/ui/winOptions.crow @@ -1,5 +1,5 @@ <?xml version="1.0"?> -<Window Caption="Options" Left="10" Top="1" Width="70%" Height="Fit" CornerRadius="5" Background="0.1,0.1,0.1,0.8"> +<Window Caption="Options" Width="70%" Height="Fit" > <VerticalStack Spacing="1" Margin="10" > <HorizontalStack Height="Fit" Margin="5"> <Label Text="Stockfish executable path:"/> @@ -41,26 +41,30 @@ <HorizontalStack Height="Fit"> <Label Text="Pce Cell pos" Style="GridLabel"/> <Label Text="{DebugCurCellPos}" Style="GridValue"/> - </HorizontalStack> + </HorizontalStack> </VerticalStack> </HorizontalStack> <Border Margin="10"> <VerticalStack> <HorizontalStack Style="Slid" > - <Label Text="Exposure:" Width="80"/> - <Slider Height="10" Value="{²Exposure}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> - <Label Text="{Exposure}" Width="40" TextAlignment="Right" /> + <Label Text="Exposure:" Width="100"/> + <Slider Style="LightingSlider" Value="{²Exposure}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> </HorizontalStack> <HorizontalStack Style="Slid" > - <Label Text="Gamma:" Width="80" /> - <Slider Height="10" Value="{²Gamma}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> - <Label Text="{Gamma}" Width="40" TextAlignment="Right" /> + <Label Text="Gamma:" Width="100" /> + <Slider Style="LightingSlider" Value="{²Gamma}" Maximum="10.0" SmallIncrement="0.01" LargeIncrement="0.1"/> </HorizontalStack> <HorizontalStack Style="Slid" > <Label Text="IBL Ambient:" Width="100" /> - <Slider Height="10" Value="{²IBLAmbient}" Maximum="50.0" SmallIncrement="0.01" LargeIncrement="0.1"/> - <Label Text="{IBLAmbient}" Width="40" TextAlignment="Right" /> + <Slider Style="LightingSlider" Value="{²IBLAmbient}" Maximum="50.0" SmallIncrement="0.01" LargeIncrement="0.1"/> </HorizontalStack> + <EnumSelector Caption="Sample count" EnumValue="{²SampleCount}" Height="Fit" Width="Stretched"> + <Template> + <GroupBox Caption="{./Caption}" CornerRadius="{./CornerRadius}" Foreground="{./Foreground}" Background="{./Background}"> + <Wrapper Margin="5" Orientation="Vertical" Height="Fit" Width="Stretched" Name="Content"/> + </GroupBox> + </Template> + </EnumSelector> </VerticalStack> </Border> </VerticalStack> diff --git a/vkChess.net.csproj b/vkChess.net.csproj index 334830e..17314a1 100644 --- a/vkChess.net.csproj +++ b/vkChess.net.csproj @@ -18,9 +18,7 @@ <EmbeddedResource Include="ui\*.style" /> </ItemGroup> <ItemGroup> - <PackageReference Include="vke" Version="0.2.0-beta" /> - <!--<PackageReference Include="Vulkan" Version="0.2.4" />--> - <PackageReference Include="glfw-sharp" Version="0.2.12-beta" /> + <PackageReference Include="VkCrowWindow" Version="0.3.1-beta" /> <PackageReference Include="SpirVTasks" Version="0.1.44" /> <PackageReference Include="vke.EnvironmentPipeline" Version="0.2.0-beta" /> <PackageReference Include="vke.gltfLoader" Version="0.2.0-beta" /> @@ -28,7 +26,4 @@ <ItemGroup> <Compile Include="src\**\*.cs" /> </ItemGroup> - <ItemGroup> - <ProjectReference Include="CrowWindow\CrowWindow.csproj" /> - </ItemGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/vkChess.net.sln b/vkChess.net.sln index a4f9dd1..063dd12 100644 --- a/vkChess.net.sln +++ b/vkChess.net.sln @@ -4,8 +4,6 @@ VisualStudioVersion = 16.0.30711.63 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "vkChess.net", "vkChess.net.csproj", "{C7D934D4-E947-4AD8-978F-D2C2A98F4508}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CrowWindow", "CrowWindow\CrowWindow.csproj", "{B5C7E7F8-526D-4FA1-9E2B-A46D6476A47A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -16,10 +14,6 @@ Global {C7D934D4-E947-4AD8-978F-D2C2A98F4508}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7D934D4-E947-4AD8-978F-D2C2A98F4508}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7D934D4-E947-4AD8-978F-D2C2A98F4508}.Release|Any CPU.Build.0 = Release|Any CPU - {B5C7E7F8-526D-4FA1-9E2B-A46D6476A47A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B5C7E7F8-526D-4FA1-9E2B-A46D6476A47A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B5C7E7F8-526D-4FA1-9E2B-A46D6476A47A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B5C7E7F8-526D-4FA1-9E2B-A46D6476A47A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE |