diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..9fa3746 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,76 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, sex characteristics, gender identity and expression, +level of experience, education, socio-economic status, nationality, personal +appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or + advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at jnoble@voidwork.space. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see +https://www.contributor-covenant.org/faq diff --git a/README.md b/README.md index db09cdf..ce60408 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Yet Another Live Coding Tool +![Build](https://github.com/Calebsem/YALCT/workflows/Build%20codebase/badge.svg) + A glsl live coding tool strongly inspired by [Shadertoy](https://www.shadertoy.com/), but as a cross platform cross graphics API desktop application. Code in modern GLSL and view your shaders using the (almost) full power of your computer's graphics APIs. Why? Because I wanted to train on [Veldrid](https://veldrid.dev), I love live coding despite not contributing a lot to it, and Shadertoy is a really fun thing. There's also a part of me who wants to show that dotnet is fun, not only for Windows and for boring aspnet and big IT service companies. Veldrid helps a lot in this sense. @@ -10,6 +12,22 @@ Credits in this hectic gif: - ["Protean Clouds" by nimitz](https://www.shadertoy.com/view/3l23Rh) - ["[TWITCH] Isometric Cages" by Flopine](https://www.shadertoy.com/view/WdXfW7) +## Table of content + +- [Features](#features) +- [Usage](#usage) + - [Download release](#download-release) + - [Making shaders](#making-shaders) + - [Shader parameters](#shader-parameters) + - [API Support](#api-support) + - [Running different graphics APIs](#running-different-graphics-apis) + - [Building](#building) + - [Publishing releases](#publishing-releases) +- [Known issues](#known-issues) +- [Roadmap and contribution](#roadmap-and-contribution) +- [License](#license) +- [Credits](#credits) + ## Features - full GLSL v450 fragment shader support @@ -20,17 +38,20 @@ Credits in this hectic gif: ## Usage -### Building +### Download release -**This repository uses git lfs.** +Self-contained releases are provided for the following systems : -Requires [.Net Core 3.1](https://dotnet.microsoft.com/download/dotnet-core/3.1) SDK for building. Nothing particular about the building process, just go inside the project folder and build/run/publish it how you wish. +- Windows 64bit : Minimum OS version is Windows 7 +- Linux 64bit : Most desktop distributions like CentOS, Debian, Fedora, Ubuntu, and derivatives +- MacOS 64bit : Minimum OS version is macOS 10.12 Sierra + +Check out [the latest release page](https://github.com/Calebsem/YALCT/releases/latest) to download it. CI building and other platforms are in the works. + +Builds are self-contained and don't require the .Net Core runtime to be installed. Extract files to whatever folder you wish and launch YALCT executable through your file explorer or via CLI [for backend switching](#running-different-graphics-apis). + +MacOS will require you to allow the app in your system preferences to able to launch directly from the finder. Unless you have a nice graphics card on your mac, don't expect wonderful performances. -Quickstart : -``` -cd YALCT -dotnet run -c Release -``` ### Making shaders Wether you create or load a shader, the entry point is the `main()` function. Regarding the rest, you are free to declare as many functions as you need, the entire Vulkan flavor GLSL specs should be supported. @@ -48,24 +69,24 @@ void main() ### Shader parameters -| Name | Type | Description | -| --- | --- | --- | -| `mouse` | `vec4` | `xy` for mouse, `z` for mouse 1 click, `w` for mouse 2 click | -| `resolution` | `vec2` | screen resolution in pixels | -| `time` | `float` | global time in seconds | -| `deltaTime` | `float` | time since last frame in seconds | -| `frame` | `int` | frame number | +| Name | Type | Description | +| ------------ | ------- | ------------------------------------------------------------ | +| `mouse` | `vec4` | `xy` for mouse, `z` for mouse 1 click, `w` for mouse 2 click | +| `resolution` | `vec2` | screen resolution in pixels | +| `time` | `float` | global time in seconds | +| `deltaTime` | `float` | time since last frame in seconds | +| `frame` | `int` | frame number | ### API Support This has mostly been tested on Windows 10, but it does run on MacOS High Sierra and Ubuntu 19.10 in Virtualbox. Some more testing is required. -| API | Windows | Linux | MacOS | -|---|---|---|---| -| OpenGL (default) |:white_check_mark:|:white_check_mark:| (deprecated) | -| Vulkan|:white_check_mark:|:white_check_mark:| | -| Direct3D11 |:white_check_mark: | | | -| Metal| | | :white_check_mark:| +| API | Windows | Linux | MacOS | +| --------------------- | ------------------ | ------------------ | ------------------ | +| OpenGL 3.0+ (default) | :white_check_mark: | :white_check_mark: | (deprecated) | +| Vulkan | :white_check_mark: | :white_check_mark: | | +| Direct3D11 | :white_check_mark: | | | +| Metal | | | :white_check_mark: | ### Running different graphics APIs @@ -79,9 +100,30 @@ YALCT direct3d11 As you can guess, MacOS doesn't get a choice. +### Building + +**This repository uses git lfs.** + +Requires [.Net Core 3.1](https://dotnet.microsoft.com/download/dotnet-core/3.1) SDK for building. Nothing particular about the building process, just go inside the project folder and build/run/publish it how you wish. + +Quickstart : +``` +cd YALCT +dotnet run -c Release +``` + +### Publishing releases + +Windows only for now. A powershell script is provided to build all supported x64 platforms in self-contained zip files. You still need the .Net Core SDK as specified in [Building](#building). You also need a globally installed [7-zip](https://www.7-zip.org/download.html) because the default Windows compression util breaks folder hierarchy on unix systems. + +``` +.\publish-all.ps1 +``` + +You will find all the zip archives in the `build/` folder. + ## Known issues -- OpenGL switches y coordinates compared to the other APIs so things will be vertically switched - Vulkan doesn't like some shaders and can freeze the app on load ## Roadmap and contribution @@ -89,6 +131,7 @@ As you can guess, MacOS doesn't get a choice. Contributions are welcome, feel free to fork and open PRs. Here are some features that I wish to implement in the future: - editor with syntax highlight? Might be hard in the current state +- actual working CI ? Github actions artifacts produce bugged executables - input textures - input audio - more exotic inputs : game controllers, midi, OSC, why not some interaction with [OSSIA Score](https://ossia.io/) @@ -111,4 +154,4 @@ Trying to use some semblance of git flow, but not the tool. Main branch is `deve Fonts: - [Open Sans](https://github.com/googlefonts/opensans) as main UI font -- [Fira Code](https://github.com/tonsky/FiraCode) as editor UI font \ No newline at end of file +- [Fira Code](https://github.com/tonsky/FiraCode) as editor UI font diff --git a/YALCT/FilePicker.cs b/YALCT/FilePicker.cs index 6f91884..4a0407c 100644 --- a/YALCT/FilePicker.cs +++ b/YALCT/FilePicker.cs @@ -60,7 +60,7 @@ public void Initialize() private string RemoveItemPathMarkup(string item) { - return item.Replace(path, "").Replace(@"\", ""); + return item.Replace(path, "").Replace(@"\", "").Replace(@"/", ""); } private void SetPath(string newPath) @@ -175,7 +175,7 @@ private void HandleSelection(FilePickerItem item) { if (item.IsUpper) { - SetPath(Path.Combine(path, @"..\")); + SetPath(Path.Combine(path, @"../")); return; } string itemPath = Path.Combine(path, item.Name); diff --git a/YALCT/ImGuiController.cs b/YALCT/ImGuiController.cs index 83d949c..81f0d3a 100644 --- a/YALCT/ImGuiController.cs +++ b/YALCT/ImGuiController.cs @@ -10,7 +10,7 @@ namespace YALCT public class ImGuiController { private const int OPTIONSWIDTH = 150; - private const int OPTIONSHEIGHT = 150; + private const int OPTIONSHEIGHT = 170; private readonly RuntimeContext context; private readonly ImFontPtr mainFont; @@ -26,12 +26,15 @@ public class ImGuiController #else private bool fullscreen = true; #endif + private bool vsync = true; + private bool invertMouseY = false; private float uiAlpha = 0.75f; public RuntimeContext Context => context; public ImFontPtr MainFont => mainFont; public ImFontPtr EditorFont => editorFont; public bool ShowOptions { get => showOptions; set => showOptions = value; } + public bool InvertMouseY => invertMouseY; public float UiAlpha { get => uiAlpha; set => uiAlpha = value; } public UIState State => state; @@ -128,6 +131,11 @@ private void SubmitOptions(InputSnapshot inputSnapshot) { Context.Window.WindowState = fullscreen ? WindowState.BorderlessFullScreen : WindowState.Maximized; } + if (ImGui.Checkbox("VSync", ref vsync)) + { + Context.GraphicsDevice.SyncToVerticalBlank = vsync; + } + ImGui.Checkbox("Invert Mouse Y", ref invertMouseY); ImGui.Text("UI Opacity"); ImGui.SetNextItemWidth(OPTIONSHEIGHT - 15); if (ImGui.SliderFloat("", ref uiAlpha, 0.2f, 1)) diff --git a/YALCT/RuntimeContext.cs b/YALCT/RuntimeContext.cs index 6d460ba..e9197f9 100644 --- a/YALCT/RuntimeContext.cs +++ b/YALCT/RuntimeContext.cs @@ -89,7 +89,7 @@ public void Initialize() GraphicsDeviceOptions options = new GraphicsDeviceOptions( debug: false, swapchainDepthFormat: PixelFormat.R32_Float, - syncToVerticalBlank: false, + syncToVerticalBlank: true, resourceBindingModel: ResourceBindingModel.Improved, preferDepthRangeZeroToOne: true, preferStandardClipSpaceYDirection: true); @@ -144,7 +144,11 @@ private void CreateRenderQuad() public void CreateDynamicResources(string fragmentCode) { // shaders - string newFragmentShader = fragmentHeaderCode + fragmentCode; + string newFragmentShader; + if (backend == GraphicsBackend.OpenGL) + newFragmentShader = fragmentHeaderCode + fragmentCode; + else + newFragmentShader = fragmentHeaderCode + fragmentHeaderNonGLCode + fragmentCode; if (currentFragmentShader != null && currentFragmentShader.Equals(newFragmentShader)) { uiController.SetError(null); @@ -261,7 +265,7 @@ public void Run() private void Update(float deltaTime) { InputSnapshot inputSnapshot = window.PumpEvents(); - runtimeData.Update(window, inputSnapshot, deltaTime); + runtimeData.Update(window, inputSnapshot, deltaTime, uiController.InvertMouseY); imGuiRenderer.Update(deltaTime, inputSnapshot); SubmitImGui(deltaTime, inputSnapshot); @@ -372,5 +376,10 @@ void main() int frame; }; layout(location = 0) out vec4 out_Color;"; + + // considering shadertoy is truth on this + public const string fragmentHeaderNonGLCode = @" +#define gl_FragCoord vec4(gl_FragCoord.x, resolution.y - gl_FragCoord.y, gl_FragCoord.zw) +"; } } \ No newline at end of file diff --git a/YALCT/YALCT.csproj b/YALCT/YALCT.csproj index b35bd6b..0441fab 100644 --- a/YALCT/YALCT.csproj +++ b/YALCT/YALCT.csproj @@ -4,6 +4,7 @@ Exe netcoreapp3.1 true + 0.1.1 diff --git a/YALCT/YALCTRuntimeData.cs b/YALCT/YALCTRuntimeData.cs index 193a4f2..4691c85 100644 --- a/YALCT/YALCTRuntimeData.cs +++ b/YALCT/YALCTRuntimeData.cs @@ -19,9 +19,9 @@ public struct YALCTRuntimeData public float deltaTime; public int frame; - public void Update(Sdl2Window window, InputSnapshot input, float newDeltaTime) + public void Update(Sdl2Window window, InputSnapshot input, float newDeltaTime, bool invertMouseY) { - mouse = new Vector4(input.MousePosition, + mouse = new Vector4(invertMouseY ? input.MousePosition : new Vector2(input.MousePosition.X, window.Height - input.MousePosition.Y), input.IsMouseDown(MouseButton.Left) ? 1 : 0, input.IsMouseDown(MouseButton.Right) ? 1 : 0); resolution = new Vector2(window.Width, window.Height); diff --git a/publish-all.ps1 b/publish-all.ps1 new file mode 100644 index 0000000..d539dca --- /dev/null +++ b/publish-all.ps1 @@ -0,0 +1,21 @@ +# requires 7zip or unix systems get all bad with subfolders +$7zipPath = "$env:ProgramFiles\7-Zip\7z.exe" + +if (-not (Test-Path -Path $7zipPath -PathType Leaf)) { + throw "7 zip file '$7zipPath' not found" +} + +Set-Alias 7zip $7zipPath + +New-Item -ItemType Directory -Force -Path .\build +cd YALCT +# Windows 64 +dotnet publish -r win-x64 -c Release --self-contained true -p:PublishSingleFile=false -p:PublishTrimmed=true +7zip a -tzip -mx=9 ..\build\YALCT-win64.zip .\bin\Release\netcoreapp3.1\win-x64\publish\* +# OSX 64 +dotnet publish -r osx-x64 -c Release --self-contained true -p:PublishSingleFile=false -p:PublishTrimmed=true +7zip a -tzip -mx=9 ..\build\YALCT-osx64.zip .\bin\Release\netcoreapp3.1\osx-x64\publish\* +# Linux 64 +dotnet publish -r linux-x64 -c Release --self-contained true -p:PublishSingleFile=false -p:PublishTrimmed=true +7zip a -tzip -mx=9 ..\build\YALCT-linux64.zip .\bin\Release\netcoreapp3.1\linux-x64\publish\* +cd .. \ No newline at end of file