my good god never look at this code again
This commit is contained in:
Родитель
3645e8f1ef
Коммит
55271c91a5
|
@ -1,4 +1,3 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31612.314
|
||||
|
@ -556,8 +555,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions",
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Direct3D11.Extensions.D3D11On12", "src\Microsoft\Extensions\Silk.NET.Direct3D11.Extensions.D3D11On12\Silk.NET.Direct3D11.Extensions.D3D11On12.csproj", "{82626916-C5F3-46E7-B0EC-1D38191450C7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlankWindowWasm", "src\Lab\Experiments\BlankWindow\BlankWindowWasm.csproj", "{F7019F5A-B03C-467F-B15A-C6D5852F27A6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.DirectComposition", "src\Microsoft\Silk.NET.DirectComposition\Silk.NET.DirectComposition.csproj", "{8773396C-5EDF-498C-97D7-1D2728CB969B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.WebGPU.Native.WGPU", "src\Native\Silk.NET.WebGPU.Native.WGPU\Silk.NET.WebGPU.Native.WGPU.csproj", "{4031A5EB-820B-478D-A656-85C93210054E}"
|
||||
|
@ -574,8 +571,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.OpenXR.Extensions.
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.OpenXR.Extensions.OPPO", "src\OpenXR\Extensions\Silk.NET.OpenXR.Extensions.OPPO\Silk.NET.OpenXR.Extensions.OPPO.csproj", "{ABC4717F-2863-4B79-8812-7C1D851EE336}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TriangleWasm", "src\Lab\Experiments\Triangle\TriangleWasm.csproj", "{0F567702-771D-4686-81EC-F29F41367197}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BlankWindowWasm", "src\Lab\Experiments\BlankWindow\BlankWindowWasm.csproj", "{F7019F5A-B03C-467F-B15A-C6D5852F27A6}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TriangleWasm", "src\Lab\Experiments\Triangle\TriangleWasm.csproj", "{0F567702-771D-4686-81EC-F29F41367197}"
|
||||
|
@ -3997,11 +3992,8 @@ Global
|
|||
{E1624E31-C702-42EC-AC47-20358B3CCF49} = {90471225-AC23-424E-B62E-F6EC4C6ECAC0}
|
||||
{82D76E01-3166-4549-A433-4C2C4FD6788E} = {90471225-AC23-424E-B62E-F6EC4C6ECAC0}
|
||||
{ABC4717F-2863-4B79-8812-7C1D851EE336} = {90471225-AC23-424E-B62E-F6EC4C6ECAC0}
|
||||
{F7019F5A-B03C-467F-B15A-C6D5852F27A6} = {39B598E9-44BA-4A61-A1BB-7C543734DBA6}
|
||||
{0F567702-771D-4686-81EC-F29F41367197} = {39B598E9-44BA-4A61-A1BB-7C543734DBA6}
|
||||
{8773396C-5EDF-498C-97D7-1D2728CB969B} = {F2CF5D32-4B41-425E-B229-8FFC48F88063}
|
||||
{F7019F5A-B03C-467F-B15A-C6D5852F27A6} = {39B598E9-44BA-4A61-A1BB-7C543734DBA6}
|
||||
{0F567702-771D-4686-81EC-F29F41367197} = {39B598E9-44BA-4A61-A1BB-7C543734DBA6}
|
||||
{F58B1280-668E-4B4A-ADA5-6F0F54B6295A} = {72E7FA64-5B1E-477D-BD30-63B7F206B3C4}
|
||||
{15FC3D1A-25D7-446B-87A7-B45BA3C2225F} = {16AFCF73-8CC1-4B5D-8969-A90F468DC6D5}
|
||||
{535018A8-FFD8-4D3E-97FD-C6A3E23AF48A} = {15FC3D1A-25D7-446B-87A7-B45BA3C2225F}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
@ -69,6 +70,7 @@ partial class Build
|
|||
return path / next;
|
||||
}
|
||||
|
||||
Debug.Assert(OriginalSolution is not null);
|
||||
var include = OriginalSolution.GetProjects("*")
|
||||
.Where
|
||||
(
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 174e65e859012a393cca6d90def85699a31d2914
|
||||
Subproject commit 5f9ed9b16931c7155171d31f75004f73f0a3abc8
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102",
|
||||
"version": "8.0.100-rc.2.23502.2",
|
||||
"allowPrerelease": true,
|
||||
"rollForward": "major"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace Silk.NET.Core.Loader
|
|||
? UnderlyingPlatform.MacOS
|
||||
: OperatingSystem.IsWindows()
|
||||
? Environment.Is64BitProcess ? UnderlyingPlatform.Windows64 : UnderlyingPlatform.Windows86
|
||||
: UnderlyingPlatform.Unknown;
|
||||
: OperatingSystem.IsBrowser() ? UnderlyingPlatform.Browser : UnderlyingPlatform.Unknown;
|
||||
#else
|
||||
public static UnderlyingPlatform Platform { get; set; } = RuntimeInformation.IsOSPlatform(OSPlatform.Linux)
|
||||
? RuntimeInformation.IsOSPlatform(OSPlatform.Create("ANDROID"))
|
||||
|
@ -86,19 +86,24 @@ namespace Silk.NET.Core.Loader
|
|||
/// Gets the possible library names to use for the current platform.
|
||||
/// </summary>
|
||||
/// <returns>The library names.</returns>
|
||||
public string[] GetLibraryNames() => Platform switch
|
||||
public string[] GetLibraryNames()
|
||||
{
|
||||
UnderlyingPlatform.Unknown => ThrowInvalidPlatform(),
|
||||
UnderlyingPlatform.Windows64 => Windows64,
|
||||
UnderlyingPlatform.Windows86 => Windows86,
|
||||
UnderlyingPlatform.Linux => Linux,
|
||||
UnderlyingPlatform.Android => Android,
|
||||
UnderlyingPlatform.MacOS => MacOS,
|
||||
UnderlyingPlatform.IOS => IOS,
|
||||
UnderlyingPlatform.Browser => Browser,
|
||||
_ => ThrowInvalidPlatform()
|
||||
};
|
||||
|
||||
var ret = Platform switch
|
||||
{
|
||||
UnderlyingPlatform.Unknown => ThrowInvalidPlatform(),
|
||||
UnderlyingPlatform.Windows64 => Windows64,
|
||||
UnderlyingPlatform.Windows86 => Windows86,
|
||||
UnderlyingPlatform.Linux => Linux,
|
||||
UnderlyingPlatform.Android => Android,
|
||||
UnderlyingPlatform.MacOS => MacOS,
|
||||
UnderlyingPlatform.IOS => IOS,
|
||||
UnderlyingPlatform.Browser => Browser,
|
||||
_ => ThrowInvalidPlatform()
|
||||
};
|
||||
Console.WriteLine("HELLO THERE: " + string.Join(", ", ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the library name to use on the current platform.
|
||||
/// </summary>
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace Silk.NET.SilkTouch
|
|||
return result.Slice(offset, MaxLength - offset).ToString();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
#if true
|
||||
public static string Name(string suggestion) => suggestion;
|
||||
#else
|
||||
public static string Name(string suggestion)
|
||||
|
|
|
@ -4,7 +4,6 @@ using System.Diagnostics;
|
|||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Silk.NET.GLFW;
|
||||
using Silk.NET.Input;
|
||||
using Silk.NET.Windowing;
|
||||
using MouseButton = Silk.NET.Input.MouseButton;
|
||||
|
|
|
@ -55,6 +55,47 @@ namespace SampleBase
|
|||
}
|
||||
}
|
||||
|
||||
public void SetUniform(string name, int value)
|
||||
{
|
||||
int location = _gl.GetUniformLocation(Handle, name);
|
||||
if (location == -1)
|
||||
{
|
||||
throw new Exception($"{name} uniform not found on shader.");
|
||||
}
|
||||
_gl.Uniform1(location, value);
|
||||
}
|
||||
|
||||
public unsafe void SetUniform(string name, Matrix4x4 value)
|
||||
{
|
||||
//A new overload has been created for setting a uniform so we can use the transform in our shader.
|
||||
int location = _gl.GetUniformLocation(Handle, name);
|
||||
if (location == -1)
|
||||
{
|
||||
throw new Exception($"{name} uniform not found on shader.");
|
||||
}
|
||||
_gl.UniformMatrix4(location, 1, false, (float*) &value);
|
||||
}
|
||||
|
||||
public void SetUniform(string name, float value)
|
||||
{
|
||||
int location = _gl.GetUniformLocation(Handle, name);
|
||||
if (location == -1)
|
||||
{
|
||||
throw new Exception($"{name} uniform not found on shader.");
|
||||
}
|
||||
_gl.Uniform1(location, value);
|
||||
}
|
||||
|
||||
public void SetUniform(string name, Vector3 value)
|
||||
{
|
||||
int location = _gl.GetUniformLocation(Handle, name);
|
||||
if (location == -1)
|
||||
{
|
||||
throw new Exception($"{name} uniform not found on shader.");
|
||||
}
|
||||
_gl.Uniform3(location, value.X, value.Y, value.Z);
|
||||
}
|
||||
|
||||
private string LoadEmbeddedResource(string path, Type type)
|
||||
{
|
||||
using (var s = type.Assembly.GetManifestResourceStream(path))
|
||||
|
@ -123,4 +164,4 @@ namespace SampleBase
|
|||
_gl.Uniform3(_uniformLocations[name], data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#if !WASM
|
||||
#define REOPEN_EXPERIMENT
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
|
@ -26,10 +28,8 @@ namespace Triangle
|
|||
private static uint _vertexBufferObject;
|
||||
private static uint _vertexArrayObject;
|
||||
private static GL _gl;
|
||||
private static IView _window;
|
||||
internal static IView _window;
|
||||
private static Shader _shader;
|
||||
|
||||
public static GraphicsAPI API { get; set; } = GraphicsAPI.Default;
|
||||
|
||||
#if !ANDROID
|
||||
// Exclude the entry point if we're running in .NET 6, as this file is
|
||||
|
@ -53,7 +53,7 @@ namespace Triangle
|
|||
var opts = ViewOptions.Default;
|
||||
opts.FramesPerSecond = 90;
|
||||
opts.UpdatesPerSecond = 90;
|
||||
opts.API = API;
|
||||
opts.API = GraphicsAPI.Default;
|
||||
|
||||
#if WASM
|
||||
//On WASM, we should be using OpenGLES 3.0
|
||||
|
@ -104,14 +104,14 @@ namespace Triangle
|
|||
{
|
||||
Console.WriteLine("Before GL");
|
||||
_gl = _window.CreateOpenGL();
|
||||
// Console.WriteLine("=== BEGIN OPENGL INFORMATION");
|
||||
// foreach (StringName val in Enum.GetValues(typeof(StringName)))
|
||||
// {
|
||||
// Console.WriteLine($"{val} = {_gl.GetStringS(val)}");
|
||||
// }
|
||||
// Console.WriteLine("=== END OPENGL INFORMATION");
|
||||
Console.WriteLine("=== BEGIN OPENGL INFORMATION");
|
||||
foreach (StringName val in Enum.GetValues(typeof(StringName)))
|
||||
{
|
||||
Console.WriteLine($"{val} = {_gl.GetStringS(val)}");
|
||||
}
|
||||
Console.WriteLine("=== END OPENGL INFORMATION");
|
||||
|
||||
if (API.API == ContextAPI.OpenGL)
|
||||
if (_window.API.API == ContextAPI.OpenGL)
|
||||
{
|
||||
_gl.Enable(GLEnum.DebugOutput);
|
||||
_gl.Enable(GLEnum.DebugOutputSynchronous);
|
||||
|
@ -132,6 +132,8 @@ namespace Triangle
|
|||
Console.WriteLine("Before shader");
|
||||
#if ANDROID
|
||||
_shader = new Shader("TriangleNET6.shader.vert", "TriangleNET6.shader.frag", _gl, typeof(Program));
|
||||
#elif WASM
|
||||
_shader = new Shader("TriangleWasm.shader.vert", "TriangleWasm.shader.frag", _gl, typeof(Program));
|
||||
#else
|
||||
_shader = new Shader("Triangle.shader.vert", "Triangle.shader.frag", _gl, typeof(Program));
|
||||
#endif
|
||||
|
|
|
@ -2,8 +2,11 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<EmccExtraLDFlags>-s USE_SDL=2 -s USE_WEBGL2=1 -s ERROR_ON_UNDEFINED_SYMBOLS=0</EmccExtraLDFlags>
|
||||
<WasmAllowUndefinedSymbols>true</WasmAllowUndefinedSymbols>
|
||||
<RunAOTCompilation>True</RunAOTCompilation>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
|
||||
|
@ -25,13 +28,9 @@
|
|||
<ProjectReference Include="..\InputTest\InputTest.csproj" />
|
||||
<ProjectReference Include="..\SampleBase\SampleBase.csproj" />
|
||||
|
||||
<PackageReference Include="Uno.Foundation.Runtime.WebAssembly" Version="4.7.0-dev.730" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap" Version="8.0.0-dev.65" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap.DevServer" Version="8.0.0-dev.65" PrivateAssets="all" />
|
||||
|
||||
<WasmShellAdditionalPInvokeLibrary Include="SDL" />
|
||||
<WasmShellAdditionalPInvokeLibrary Include="__Internal_emscripten" />
|
||||
<WasmShellExtraEmccFlags Include="-s USE_SDL=2 -s USE_WEBGL2=1" />
|
||||
<PackageReference Include="Uno.Foundation.Runtime.WebAssembly" Version="5.0.0-dev.3597" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap" Version="8.0.0-dev.306" />
|
||||
<PackageReference Include="Uno.Wasm.Bootstrap.DevServer" Version="8.0.0-dev.306" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
// For more information on how shaders work, check out the web version of this tutorial
|
||||
// I'll include a simpler summary here.
|
||||
|
||||
// First non-comment line should always be a #version statement; this just tells the GLSL compiler what version it should use
|
||||
#version 300 es
|
||||
|
||||
// GLSL's syntax is somewhat like C, but it has a few differences.
|
||||
|
@ -25,7 +21,7 @@
|
|||
// Next, the keyword "in" defines this as an input variable. We'll have an example of the "out" keyword in the next tutorial.
|
||||
// Then, the keyword "vec3" means this is a vector with 3 floats inside.
|
||||
|
||||
layout(location = 0) in highp vec3 aPosition;
|
||||
in highp vec3 aPosition;
|
||||
|
||||
|
||||
// Like C, we have an entrypoint function. In this case, it takes void and returns void, and must be named main.
|
||||
|
@ -38,4 +34,4 @@ layout(location = 0) in highp vec3 aPosition;
|
|||
void main(void)
|
||||
{
|
||||
gl_Position = vec4(aPosition, 1.0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
|
@ -0,0 +1,16 @@
|
|||
@inherits LayoutComponentBase
|
||||
<div class="page">
|
||||
<div class="sidebar">
|
||||
<NavMenu />
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="top-row px-4">
|
||||
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
|
@ -0,0 +1,77 @@
|
|||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.top-row ::deep a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row ::deep .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row.auth ::deep a:first-child {
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
<div class="top-row ps-3 navbar navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="">TriangleWasm</a>
|
||||
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="@NavMenuCssClass nav-scrollable" @onclick="ToggleNavMenu">
|
||||
<nav class="flex-column">
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="bi bi-house-door-fill" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="basictriangle">
|
||||
<span class="bi bi-list-nested" aria-hidden="true"></span> Basic Triangle
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="lightingmaps">
|
||||
<span class="bi bi-list-nested" aria-hidden="true"></span> Lighting Maps
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="counter">
|
||||
<span class="bi bi-plus-square-fill" aria-hidden="true"></span> Counter
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="weather">
|
||||
<span class="bi bi-list-nested" aria-hidden="true"></span> Weather
|
||||
</NavLink>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool collapseNavMenu = true;
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private void ToggleNavMenu()
|
||||
{
|
||||
collapseNavMenu = !collapseNavMenu;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
.navbar-toggler {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.bi {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
margin-right: 0.75rem;
|
||||
top: -1px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.bi-house-door-fill {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-plus-square-fill {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.bi-list-nested {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255,255,255,0.37);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
|
||||
.nav-scrollable {
|
||||
/* Allow sidebar to scroll for tall menus */
|
||||
height: calc(100vh - 3.5rem);
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
@page "/basictriangle"
|
||||
@using Silk.NET.Core.Loader
|
||||
@using Silk.NET.Core.Native
|
||||
@using Silk.NET.Windowing
|
||||
@using System.Diagnostics.CodeAnalysis
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
|
||||
<PageTitle>Home</PageTitle>
|
||||
|
||||
<h1>Basic Triangle Demo</h1>
|
||||
|
||||
<p>
|
||||
It's literally just a triangle.
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<canvas style="width: 1920px; height: 1080px;" id="canvas" oncontextmenu="event.preventDefault()" onloadend="console.log('added canvas: ' + (Module['canvas'] = document.getElementById('canvas')))" />
|
||||
|
||||
@code {
|
||||
[System.Runtime.InteropServices.DllImport("SDL", EntryPoint = "SDL_GetPlatform", CallingConvention = (System.Runtime.InteropServices.CallingConvention)2)]
|
||||
static extern unsafe byte* I_SDL_GetPlatform();
|
||||
[System.Runtime.InteropServices.UnmanagedCallersOnly(CallConvs = new[] { typeof(System.Runtime.CompilerServices.CallConvCdecl) })]
|
||||
static unsafe byte* S_SDL_GetPlatform() => I_SDL_GetPlatform();
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await JSRuntime.InvokeVoidAsync("setCanvas", typeof(BasicTriangle).Assembly.GetName().Name, $"{typeof(BasicTriangle).FullName}.CanvasDropped");
|
||||
unsafe
|
||||
{
|
||||
Console.WriteLine(SilkMarshal.PtrToString((nint) I_SDL_GetPlatform()));
|
||||
delegate* unmanaged[Cdecl]<byte*> gp = &S_SDL_GetPlatform;
|
||||
if (gp == null)
|
||||
{
|
||||
throw new("what");
|
||||
}
|
||||
}
|
||||
SearchPathContainer.Platform = UnderlyingPlatform.Browser;
|
||||
Triangle.Program.Run();
|
||||
}
|
||||
|
||||
[JSInvokable("TriangleWasm.Components.Pages.BasicTriangle.CanvasDropped")]
|
||||
public static void CanvasDropped() => Window.CanvasDropped(Triangle.Program._window);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
@page "/counter"
|
||||
|
||||
<PageTitle>Counter</PageTitle>
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p role="status">Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
@page "/"
|
||||
|
||||
<PageTitle>Silk.NET WASM Lab Home</PageTitle>
|
||||
|
||||
<h1>Silk.NET Lab: Blazor/WebAssembly Experiments</h1>
|
||||
|
||||
<p>
|
||||
TODO WRITE WORDS
|
||||
</p>
|
|
@ -0,0 +1,34 @@
|
|||
@page "/lightingmaps"
|
||||
@using Silk.NET.Core.Loader
|
||||
@using Silk.NET.Core.Native
|
||||
@using Silk.NET.Windowing
|
||||
@inject IJSRuntime JSRuntime
|
||||
|
||||
|
||||
<PageTitle>Lighting Maps</PageTitle>
|
||||
|
||||
<h1>Lighting Maps Demo</h1>
|
||||
|
||||
<p>
|
||||
Use WASD and the mouse to move about the scene.
|
||||
</p>
|
||||
|
||||
<br />
|
||||
|
||||
<canvas style="width: 1920px; height: 1080px;" id="canvas" oncontextmenu="event.preventDefault()" onloadend="console.log('added canvas: ' + (Module['canvas'] = document.getElementById('canvas')))" />
|
||||
|
||||
@code {
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!firstRender)
|
||||
{
|
||||
return;
|
||||
}
|
||||
await JSRuntime.InvokeVoidAsync("setCanvas", typeof(LightingMaps).Assembly.GetName().Name, $"{typeof(LightingMaps).FullName}.CanvasDropped");
|
||||
SearchPathContainer.Platform = UnderlyingPlatform.Browser;
|
||||
Tutorial.Program.Run();
|
||||
}
|
||||
|
||||
[JSInvokable("TriangleWasm.Components.Pages.LightingMaps.CanvasDropped")]
|
||||
public static void CanvasDropped() => Window.CanvasDropped(Tutorial.Program.window);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
@page "/weather"
|
||||
@inject HttpClient Http
|
||||
|
||||
<PageTitle>Weather</PageTitle>
|
||||
|
||||
<h1>Weather</h1>
|
||||
|
||||
<p>This component demonstrates fetching data from the server.</p>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.Date.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@code {
|
||||
private WeatherForecast[]? forecasts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
forecasts = await Http.GetFromJsonAsync<WeatherForecast[]>("sample-data/weather.json");
|
||||
}
|
||||
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateOnly Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public string? Summary { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
@using System.Net.Http
|
||||
@using System.Net.Http.Json
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Microsoft.AspNetCore.Components.Routing
|
||||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.AspNetCore.Components.WebAssembly.Http
|
||||
@using Microsoft.JSInterop
|
||||
@using TriangleWasm
|
||||
@using TriangleWasm.Components
|
||||
@using TriangleWasm.Components.Layout
|
|
@ -0,0 +1,12 @@
|
|||
using Microsoft.AspNetCore.Components.Web;
|
||||
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
|
||||
using TriangleWasm.Components;
|
||||
|
||||
var builder = WebAssemblyHostBuilder.CreateDefault(args);
|
||||
builder.RootComponents.Add<App>("#app");
|
||||
builder.RootComponents.Add<HeadOutlet>("head::after");
|
||||
|
||||
|
||||
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
|
||||
|
||||
await builder.Build().RunAsync();
|
|
@ -0,0 +1,91 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
|
||||
<DefineConstants>$(DefineConstants);TRACE;WASM</DefineConstants>
|
||||
<EmccExtraLDFlags>-s USE_CLOSURE_COMPILER=1 -lSDL -s USE_SDL=2 -sFULL_ES3</EmccExtraLDFlags>
|
||||
<EnableAggressiveTrimming>true</EnableAggressiveTrimming>
|
||||
<InvariantTimezone>true</InvariantTimezone>
|
||||
<!--<WasmEnableWebcil>false</WasmEnableWebcil>-->
|
||||
<WasmEmitSymbolMap>true</WasmEmitSymbolMap>
|
||||
<!--<EmccEnableAssertions>true</EmccEnableAssertions>-->
|
||||
<!--<EmccEnvironment>web,worker</EmccEnvironment>-->
|
||||
<!-- add OpenGL emulation -->
|
||||
<!-- just to prove we don't do JS eval() -->
|
||||
<_ServeHeaders>$(_ServeHeaders) -h "Content-Security-Policy: default-src 'self' 'wasm-unsafe-eval'"</_ServeHeaders>
|
||||
<!-- enable reporting to profiler in browser dev tools -->
|
||||
<!--<WasmProfilers>browser;</WasmProfilers>-->
|
||||
|
||||
<!-- Put "framework" (dotnet.js, dlls, etc) files directly into the AppBundle -->
|
||||
<!--<WasmRuntimeAssetsLocation>./</WasmRuntimeAssetsLocation>-->
|
||||
<WasmCachePath>$([System.IO.Path]::GetFullPath('$(BaseIntermediateOutputPath)/$(TargetFramework)/wasm-cache'))</WasmCachePath>
|
||||
<WasmAllowUndefinedSymbols>true</WasmAllowUndefinedSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0-rc.2.23480.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0-rc.2.23480.2" PrivateAssets="all" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.6" />
|
||||
<ProjectReference Include="..\..\..\Core\Silk.NET.Core\Silk.NET.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\Input\Silk.NET.Input.Common\Silk.NET.Input.Common.csproj" />
|
||||
<ProjectReference Include="..\..\..\Input\Silk.NET.Input.Sdl\Silk.NET.Input.Sdl.csproj" />
|
||||
<ProjectReference Include="..\..\..\Maths\Silk.NET.Maths\Silk.NET.Maths.csproj" />
|
||||
<ProjectReference Include="..\..\..\OpenGL\Silk.NET.OpenGL\Silk.NET.OpenGL.csproj" />
|
||||
<ProjectReference Include="..\..\..\Windowing\Silk.NET.SDL\Silk.NET.SDL.csproj" />
|
||||
<ProjectReference Include="..\..\..\Windowing\Silk.NET.Windowing.Common\Silk.NET.Windowing.Common.csproj" />
|
||||
<ProjectReference Include="..\..\..\Windowing\Silk.NET.Windowing.Sdl\Silk.NET.Windowing.Sdl.csproj" />
|
||||
<ProjectReference Include="..\SampleBase\SampleBase.csproj" />
|
||||
<EmbeddedResource Include="..\Triangle\shader.vert" Link="shader.vert" />
|
||||
<EmbeddedResource Include="..\Triangle\shader.frag" Link="shader.frag" />
|
||||
<Compile Include="../Triangle/Program.cs" Link="Triangle.cs" />
|
||||
<Compile Include="../InputTest/Program.cs" Link="InputTest.cs" />
|
||||
<RuntimeHostConfigurationOption Include="SILK_NET_SDL_SDL_ENABLE_PINVOKE_OVERRIDE_2" Value="true" Trim="true" />
|
||||
<DirectPInvoke Include="SDL" />
|
||||
<DirectPInvoke Include="__Internal_emscripten" />
|
||||
<EmccExportedRuntimeMethod Include="SDL" />
|
||||
<EmccExportedRuntimeMethod Include="GL" />
|
||||
<EmccExportedRuntimeMethod Include="emscripten_set_main_loop" />
|
||||
<EmccExportedRuntimeMethod Include="emscripten_set_main_loop_timing" />
|
||||
<EmccExportedRuntimeMethod Include="emscripten_cancel_main_loop_timing" />
|
||||
<None Remove="Tutorial\silkSpecular.png" />
|
||||
<EmbeddedResource Include="Tutorial\silkSpecular.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<None Remove="Tutorial\silkBoxed.png" />
|
||||
<EmbeddedResource Include="Tutorial\silkBoxed.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<None Remove="Tutorial\shader.frag" />
|
||||
<EmbeddedResource Include="Tutorial\shader.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<None Remove="Tutorial\shader.vert" />
|
||||
<EmbeddedResource Include="Tutorial\shader.vert">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
<None Remove="Tutorial\lighting.frag" />
|
||||
<EmbeddedResource Include="Tutorial\lighting.frag">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="AddSDL" BeforeTargets="_GenerateManagedToNative" DependsOnTargets="_PrepareForWasmBuildNative">
|
||||
<ItemGroup>
|
||||
<_WasmPInvokeModules Include="SDL" /> <!-- TODO not this -->
|
||||
<_WasmPInvokeModules Include="__Internal_emscripten" /> <!-- TODO not this -->
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="UnfreezeCache" DependsOnTargets="AddSDL" BeforeTargets="_WasmCompileNativeFiles;_WasmCompileAssemblyBitCodeFilesForAOT;_WasmCalculateInitialHeapSize;_WasmLinkDotNet;_CheckEmccIsExpectedVersion">
|
||||
<ItemGroup>
|
||||
<EmscriptenEnvVars Remove="EM_FROZEN_CACHE=True" />
|
||||
<EmscriptenEnvVars Include="EM_FROZEN_CACHE=0" />
|
||||
<EmscriptenEnvVars Include="FROZEN_CACHE=0" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
using Silk.NET.OpenGL;
|
||||
using System;
|
||||
|
||||
namespace Tutorial
|
||||
{
|
||||
public class BufferObject<TDataType> : IDisposable
|
||||
where TDataType : unmanaged
|
||||
{
|
||||
private uint _handle;
|
||||
private BufferTargetARB _bufferType;
|
||||
private GL _gl;
|
||||
|
||||
public unsafe BufferObject(GL gl, Span<TDataType> data, BufferTargetARB bufferType)
|
||||
{
|
||||
_gl = gl;
|
||||
_bufferType = bufferType;
|
||||
|
||||
_handle = _gl.GenBuffer();
|
||||
Bind();
|
||||
fixed (void* d = data)
|
||||
{
|
||||
_gl.BufferData(bufferType, (nuint) (data.Length * sizeof(TDataType)), d, BufferUsageARB.StaticDraw);
|
||||
}
|
||||
}
|
||||
|
||||
public void Bind()
|
||||
{
|
||||
_gl.BindBuffer(_bufferType, _handle);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_gl.DeleteBuffer(_handle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
namespace Tutorial
|
||||
{
|
||||
public class Camera
|
||||
{
|
||||
public Vector3 Position { get; set; }
|
||||
public Vector3 Front { get; set; }
|
||||
|
||||
public Vector3 Up { get; private set; }
|
||||
public float AspectRatio { get; set; }
|
||||
|
||||
public float Yaw { get; set; } = -90f;
|
||||
public float Pitch { get; set; }
|
||||
|
||||
private float Zoom = 45f;
|
||||
|
||||
public Camera(Vector3 position, Vector3 front, Vector3 up, float aspectRatio)
|
||||
{
|
||||
Position = position;
|
||||
AspectRatio = aspectRatio;
|
||||
Front = front;
|
||||
Up = up;
|
||||
}
|
||||
|
||||
public void ModifyZoom(float zoomAmount)
|
||||
{
|
||||
//We don't want to be able to zoom in too close or too far away so clamp to these values
|
||||
Zoom = Math.Clamp(Zoom - zoomAmount, 1.0f, 45f);
|
||||
}
|
||||
|
||||
public void ModifyDirection(float xOffset, float yOffset)
|
||||
{
|
||||
Yaw += xOffset;
|
||||
Pitch -= yOffset;
|
||||
|
||||
//We don't want to be able to look behind us by going over our head or under our feet so make sure it stays within these bounds
|
||||
Pitch = Math.Clamp(Pitch, -89f, 89f);
|
||||
|
||||
var cameraDirection = Vector3.Zero;
|
||||
cameraDirection.X = MathF.Cos(MathHelper.DegreesToRadians(Yaw)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
|
||||
cameraDirection.Y = MathF.Sin(MathHelper.DegreesToRadians(Pitch));
|
||||
cameraDirection.Z = MathF.Sin(MathHelper.DegreesToRadians(Yaw)) * MathF.Cos(MathHelper.DegreesToRadians(Pitch));
|
||||
|
||||
Front = Vector3.Normalize(cameraDirection);
|
||||
}
|
||||
|
||||
public Matrix4x4 GetViewMatrix()
|
||||
{
|
||||
return Matrix4x4.CreateLookAt(Position, Position + Front, Up);
|
||||
}
|
||||
|
||||
public Matrix4x4 GetProjectionMatrix()
|
||||
{
|
||||
return Matrix4x4.CreatePerspectiveFieldOfView(MathHelper.DegreesToRadians(Zoom), AspectRatio, 0.1f, 100.0f);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
namespace Tutorial
|
||||
{
|
||||
public static class MathHelper
|
||||
{
|
||||
public static float DegreesToRadians(float degrees)
|
||||
{
|
||||
return MathF.PI / 180f * degrees;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
using Silk.NET.Input;
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Windowing;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using Silk.NET.Maths;
|
||||
|
||||
namespace Tutorial
|
||||
{
|
||||
class Program
|
||||
{
|
||||
internal static IView window;
|
||||
private static GL Gl;
|
||||
private static IKeyboard primaryKeyboard;
|
||||
|
||||
private static BufferObject<float> Vbo;
|
||||
private static BufferObject<uint> Ebo;
|
||||
private static VertexArrayObject<float, uint> VaoCube;
|
||||
private static SampleBase.Shader LightingShader;
|
||||
private static SampleBase.Shader LampShader;
|
||||
private static Vector3 LampPosition = new Vector3(1.2f, 1.0f, 2.0f);
|
||||
|
||||
private static Texture DiffuseMap;
|
||||
private static Texture SpecularMap;
|
||||
|
||||
private static Camera Camera;
|
||||
|
||||
//Track when the window started so we can use the time elapsed to rotate the cube
|
||||
private static DateTime StartTime;
|
||||
|
||||
private static readonly float[] Vertices =
|
||||
{
|
||||
//X Y Z Normals U V
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f,
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
-0.5f, 0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, -0.5f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, -0.5f, -0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, -0.5f, 0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, -0.5f, -0.5f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f,
|
||||
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f,
|
||||
0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||
0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
|
||||
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f,
|
||||
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f
|
||||
};
|
||||
|
||||
private static readonly uint[] Indices =
|
||||
{
|
||||
0, 1, 3,
|
||||
1, 2, 3
|
||||
};
|
||||
|
||||
internal static void Run()
|
||||
{
|
||||
var options = ViewOptions.Default with { API = new GraphicsAPI(ContextAPI.OpenGLES, new APIVersion(3, 0)) };
|
||||
window = Window.GetView(options);
|
||||
|
||||
window.Load += OnLoad;
|
||||
window.Update += OnUpdate;
|
||||
window.Render += OnRender;
|
||||
window.Closing += OnClose;
|
||||
|
||||
window.Run();
|
||||
|
||||
if (window.IsClosing)
|
||||
{
|
||||
window.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnLoad()
|
||||
{
|
||||
StartTime = DateTime.UtcNow;
|
||||
IInputContext input = window.CreateInput();
|
||||
primaryKeyboard = input.Keyboards.FirstOrDefault();
|
||||
if (primaryKeyboard != null)
|
||||
{
|
||||
primaryKeyboard.KeyDown += KeyDown;
|
||||
}
|
||||
for (int i = 0; i < input.Mice.Count; i++)
|
||||
{
|
||||
input.Mice[i].MouseDown += OnMouseDown;
|
||||
input.Mice[i].MouseUp += OnMouseUp;
|
||||
input.Mice[i].MouseMove += OnMouseMove;
|
||||
input.Mice[i].Scroll += OnMouseWheel;
|
||||
}
|
||||
|
||||
Gl = GL.GetApi(window);
|
||||
|
||||
Ebo = new BufferObject<uint>(Gl, Indices, BufferTargetARB.ElementArrayBuffer);
|
||||
Vbo = new BufferObject<float>(Gl, Vertices, BufferTargetARB.ArrayBuffer);
|
||||
VaoCube = new VertexArrayObject<float, uint>(Gl, Vbo, Ebo);
|
||||
|
||||
VaoCube.VertexAttributePointer(0, 3, VertexAttribPointerType.Float, 8, 0);
|
||||
VaoCube.VertexAttributePointer(1, 3, VertexAttribPointerType.Float, 8, 3);
|
||||
VaoCube.VertexAttributePointer(2, 2, VertexAttribPointerType.Float, 8, 6);
|
||||
|
||||
//The lighting shader will give our main cube its colour multiplied by the light's intensity
|
||||
LightingShader = new SampleBase.Shader("TriangleWasm.Tutorial.shader.vert", "TriangleWasm.Tutorial.lighting.frag", Gl, typeof(Program));
|
||||
//The Lamp shader uses a fragment shader that just colours it solid white so that we know it is the light source
|
||||
LampShader = new SampleBase.Shader("TriangleWasm.Tutorial.shader.vert", "TriangleWasm.Tutorial.shader.frag", Gl, typeof(Program));
|
||||
|
||||
//Start a camera at position 3 on the Z axis, looking at position -1 on the Z axis
|
||||
Camera = new Camera(Vector3.UnitZ * 6, Vector3.UnitZ * -1, Vector3.UnitY, (float)window.FramebufferSize.X / (float)window.FramebufferSize.Y);
|
||||
|
||||
DiffuseMap = new Texture(Gl, "TriangleWasm.Tutorial.silkBoxed.png", typeof(Program));
|
||||
SpecularMap = new Texture(Gl, "TriangleWasm.Tutorial.silkSpecular.png", typeof(Program));
|
||||
}
|
||||
|
||||
private static Vector2? _lastDownOff;
|
||||
private static void OnMouseDown(IMouse arg1, MouseButton arg2)
|
||||
{
|
||||
if (arg2 == MouseButton.Left)
|
||||
{
|
||||
_lastDownOff = arg1.Position;
|
||||
}
|
||||
}
|
||||
private static void OnMouseUp(IMouse arg1, MouseButton arg2)
|
||||
{
|
||||
if (arg2 == MouseButton.Left)
|
||||
{
|
||||
_lastDownOff = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe void OnUpdate(double deltaTime)
|
||||
{
|
||||
var moveSpeed = 2.5f * (float) deltaTime;
|
||||
|
||||
if (primaryKeyboard.IsKeyPressed(Key.W))
|
||||
{
|
||||
//Move forwards
|
||||
Camera.Position += moveSpeed * Camera.Front;
|
||||
}
|
||||
if (primaryKeyboard.IsKeyPressed(Key.S))
|
||||
{
|
||||
//Move backwards
|
||||
Camera.Position -= moveSpeed * Camera.Front;
|
||||
}
|
||||
if (primaryKeyboard.IsKeyPressed(Key.A))
|
||||
{
|
||||
//Move left
|
||||
Camera.Position -= Vector3.Normalize(Vector3.Cross(Camera.Front, Camera.Up)) * moveSpeed;
|
||||
}
|
||||
if (primaryKeyboard.IsKeyPressed(Key.D))
|
||||
{
|
||||
//Move right
|
||||
Camera.Position += Vector3.Normalize(Vector3.Cross(Camera.Front, Camera.Up)) * moveSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe void OnRender(double deltaTime)
|
||||
{
|
||||
Gl.Enable(EnableCap.DepthTest);
|
||||
Gl.ClearColor(Color.Black);
|
||||
Gl.Clear((uint) (ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit));
|
||||
|
||||
VaoCube.Bind();
|
||||
LightingShader.Use();
|
||||
|
||||
//Bind the diffuse map and and set to use texture0.
|
||||
DiffuseMap.Bind(TextureUnit.Texture0);
|
||||
//Bind the specular map and and set to use texture1.
|
||||
SpecularMap.Bind(TextureUnit.Texture1);
|
||||
|
||||
//Setup the coordinate systems for our view
|
||||
LightingShader.SetUniform("uModel", Matrix4x4.Identity);
|
||||
LightingShader.SetUniform("uView", Camera.GetViewMatrix());
|
||||
LightingShader.SetUniform("uProjection", Camera.GetProjectionMatrix());
|
||||
//Let the shaders know where the Camera is looking from
|
||||
LightingShader.SetUniform("viewPos", Camera.Position);
|
||||
//Configure the materials variables.
|
||||
//Diffuse is set to 0 because our diffuseMap is bound to Texture0
|
||||
LightingShader.SetUniform("material.diffuse", 0);
|
||||
//Specular is set to 1 because our diffuseMap is bound to Texture1
|
||||
LightingShader.SetUniform("material.specular", 1);
|
||||
LightingShader.SetUniform("material.shininess", 32.0f);
|
||||
|
||||
var diffuseColor = new Vector3(0.5f);
|
||||
var ambientColor = diffuseColor * new Vector3(0.2f);
|
||||
|
||||
LightingShader.SetUniform("light.ambient", ambientColor);
|
||||
LightingShader.SetUniform("light.diffuse", diffuseColor); // darkened
|
||||
LightingShader.SetUniform("light.specular", new Vector3(1.0f, 1.0f, 1.0f));
|
||||
LightingShader.SetUniform("light.position", LampPosition);
|
||||
|
||||
//We're drawing with just vertices and no indicies, and it takes 36 verticies to have a six-sided textured cube
|
||||
Gl.DrawArrays(PrimitiveType.Triangles, 0, 36);
|
||||
|
||||
LampShader.Use();
|
||||
|
||||
//The Lamp cube is going to be a scaled down version of the normal cubes verticies moved to a different screen location
|
||||
var lampMatrix = Matrix4x4.Identity;
|
||||
lampMatrix *= Matrix4x4.CreateScale(0.2f);
|
||||
lampMatrix *= Matrix4x4.CreateTranslation(LampPosition);
|
||||
|
||||
LampShader.SetUniform("uModel", lampMatrix);
|
||||
LampShader.SetUniform("uView", Camera.GetViewMatrix());
|
||||
LampShader.SetUniform("uProjection", Camera.GetProjectionMatrix());
|
||||
|
||||
Gl.DrawArrays(PrimitiveType.Triangles, 0, 36);
|
||||
}
|
||||
|
||||
private static unsafe void OnMouseMove(IMouse mouse, Vector2 position)
|
||||
{
|
||||
const float lookSensitivity = 0.1f;
|
||||
if (_lastDownOff is not null)
|
||||
{
|
||||
if (_lastDownOff.Value == default)
|
||||
{
|
||||
_lastDownOff = position;
|
||||
}
|
||||
else
|
||||
{
|
||||
var xOffset = (position.X - _lastDownOff.Value.X) * lookSensitivity;
|
||||
var yOffset = (position.Y - _lastDownOff.Value.Y) * lookSensitivity;
|
||||
_lastDownOff = position;
|
||||
|
||||
Camera.ModifyDirection(xOffset, yOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe void OnMouseWheel(IMouse mouse, ScrollWheel scrollWheel)
|
||||
{
|
||||
Camera.ModifyZoom(scrollWheel.Y);
|
||||
}
|
||||
|
||||
private static void OnClose()
|
||||
{
|
||||
Vbo.Dispose();
|
||||
Ebo.Dispose();
|
||||
VaoCube.Dispose();
|
||||
// TODO LightingShader.Dispose();
|
||||
// TODO LampShader.Dispose();
|
||||
DiffuseMap.Dispose();
|
||||
SpecularMap.Dispose();
|
||||
}
|
||||
|
||||
private static void KeyDown(IKeyboard keyboard, Key key, int arg3)
|
||||
{
|
||||
if (key == Key.Escape)
|
||||
{
|
||||
window.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
using Silk.NET.OpenGL;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.PixelFormats;
|
||||
using System;
|
||||
|
||||
namespace Tutorial
|
||||
{
|
||||
public class Texture : IDisposable
|
||||
{
|
||||
private uint _handle;
|
||||
private GL _gl;
|
||||
|
||||
public unsafe Texture(GL gl, string path, Type type)
|
||||
{
|
||||
_gl = gl;
|
||||
|
||||
_handle = _gl.GenTexture();
|
||||
Bind();
|
||||
|
||||
using var s = type.Assembly.GetManifestResourceStream(path);
|
||||
using (var img = Image.Load<Rgba32>(s))
|
||||
{
|
||||
gl.TexImage2D(TextureTarget.Texture2D, 0, InternalFormat.Rgba8, (uint)img.Width, (uint)img.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, null);
|
||||
|
||||
img.ProcessPixelRows(accessor =>
|
||||
{
|
||||
for (int y = 0; y < accessor.Height; y++)
|
||||
{
|
||||
fixed (void* data = accessor.GetRowSpan(y))
|
||||
{
|
||||
gl.TexSubImage2D(TextureTarget.Texture2D, 0, 0, y, (uint) accessor.Width, 1, PixelFormat.Rgba, PixelType.UnsignedByte, data);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
SetParameters();
|
||||
}
|
||||
|
||||
public unsafe Texture(GL gl, Span<byte> data, uint width, uint height)
|
||||
{
|
||||
_gl = gl;
|
||||
|
||||
_handle = _gl.GenTexture();
|
||||
Bind();
|
||||
|
||||
fixed (void* d = &data[0])
|
||||
{
|
||||
_gl.TexImage2D(TextureTarget.Texture2D, 0, (int) InternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, d);
|
||||
SetParameters();
|
||||
}
|
||||
}
|
||||
|
||||
private void SetParameters()
|
||||
{
|
||||
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int) GLEnum.ClampToEdge);
|
||||
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int) GLEnum.ClampToEdge);
|
||||
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int) GLEnum.LinearMipmapLinear);
|
||||
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int) GLEnum.Linear);
|
||||
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureBaseLevel, 0);
|
||||
_gl.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMaxLevel, 8);
|
||||
_gl.GenerateMipmap(TextureTarget.Texture2D);
|
||||
}
|
||||
|
||||
public void Bind(TextureUnit textureSlot = TextureUnit.Texture0)
|
||||
{
|
||||
_gl.ActiveTexture(textureSlot);
|
||||
_gl.BindTexture(TextureTarget.Texture2D, _handle);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_gl.DeleteTexture(_handle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
using System.Numerics;
|
||||
|
||||
namespace Tutorial
|
||||
{
|
||||
public class Transform
|
||||
{
|
||||
//A transform abstraction.
|
||||
//For a transform we need to have a position, a scale, and a rotation,
|
||||
//depending on what application you are creating, the type for these may vary.
|
||||
|
||||
//Here we have chosen a vec3 for position, float for scale and quaternion for rotation,
|
||||
//as that is the most normal to go with.
|
||||
//Another example could have been vec3, vec3, vec4, so the rotation is an axis angle instead of a quaternion
|
||||
|
||||
public Vector3 Position { get; set; } = new Vector3(0, 0, 0);
|
||||
|
||||
public float Scale { get; set; } = 1f;
|
||||
|
||||
public Quaternion Rotation { get; set; } = Quaternion.Identity;
|
||||
|
||||
//Note: The order here does matter.
|
||||
public Matrix4x4 ViewMatrix => Matrix4x4.Identity * Matrix4x4.CreateFromQuaternion(Rotation) * Matrix4x4.CreateScale(Scale) * Matrix4x4.CreateTranslation(Position);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
using Silk.NET.OpenGL;
|
||||
using System;
|
||||
|
||||
namespace Tutorial
|
||||
{
|
||||
public class VertexArrayObject<TVertexType, TIndexType> : IDisposable
|
||||
where TVertexType : unmanaged
|
||||
where TIndexType : unmanaged
|
||||
{
|
||||
private uint _handle;
|
||||
private GL _gl;
|
||||
|
||||
public VertexArrayObject(GL gl, BufferObject<TVertexType> vbo, BufferObject<TIndexType> ebo)
|
||||
{
|
||||
_gl = gl;
|
||||
|
||||
_handle = _gl.GenVertexArray();
|
||||
Bind();
|
||||
vbo.Bind();
|
||||
ebo.Bind();
|
||||
}
|
||||
|
||||
public unsafe void VertexAttributePointer(uint index, int count, VertexAttribPointerType type, uint vertexSize, int offSet)
|
||||
{
|
||||
_gl.VertexAttribPointer(index, count, type, false, vertexSize * (uint) sizeof(TVertexType), (void*) (offSet * sizeof(TVertexType)));
|
||||
_gl.EnableVertexAttribArray(index);
|
||||
}
|
||||
|
||||
public void Bind()
|
||||
{
|
||||
_gl.BindVertexArray(_handle);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_gl.DeleteVertexArray(_handle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
|
||||
in vec3 fNormal;
|
||||
in vec3 fPos;
|
||||
in vec2 fTexCoords;
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
struct Light {
|
||||
vec3 position;
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
uniform Material material;
|
||||
uniform Light light;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 ambient = light.ambient * texture(material.diffuse, fTexCoords).rgb;
|
||||
|
||||
vec3 norm = normalize(fNormal);
|
||||
vec3 lightDirection = normalize(light.position - fPos);
|
||||
float diff = max(dot(norm, lightDirection), 0.0);
|
||||
vec3 diffuse = light.diffuse * (diff * texture(material.diffuse, fTexCoords).rgb);
|
||||
|
||||
vec3 viewDirection = normalize(viewPos - fPos);
|
||||
vec3 reflectDirection = reflect(-lightDirection, norm);
|
||||
float spec = pow(max(dot(viewDirection, reflectDirection), 0.0), material.shininess);
|
||||
vec3 specular = light.specular * (spec * texture(material.specular, fTexCoords).rgb);
|
||||
|
||||
//The resulting colour should be the amount of ambient colour + the amount of additional colour provided by the diffuse of the lamp + the specular amount
|
||||
vec3 result = ambient + diffuse + specular;
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(1.0f);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#version 300 es
|
||||
|
||||
precision highp float;
|
||||
|
||||
in vec3 vPos;
|
||||
in vec3 vNormal;
|
||||
in vec2 vTexCoords;
|
||||
|
||||
uniform mat4 uModel;
|
||||
uniform mat4 uView;
|
||||
uniform mat4 uProjection;
|
||||
|
||||
out vec3 fNormal;
|
||||
out vec3 fPos;
|
||||
out vec2 fTexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
//Multiplying our uniform with the vertex position, the multiplication order here does matter.
|
||||
gl_Position = uProjection * uView * uModel * vec4(vPos, 1.0);
|
||||
//We want to know the fragment's position in World space, so we multiply ONLY by uModel and not uView or uProjection
|
||||
fPos = vec3(uModel * vec4(vPos, 1.0));
|
||||
//The Normal needs to be in World space too, but needs to account for Scaling of the object
|
||||
fNormal = mat3(transpose(inverse(uModel))) * vNormal;
|
||||
//Pass the texture coordinates straight through to the fragment shader
|
||||
fTexCoords = vTexCoords;
|
||||
}
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 11 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 12 KiB |
|
@ -0,0 +1,103 @@
|
|||
html, body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
h1:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
a, .btn-link {
|
||||
color: #0071c1;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #1b6ec2;
|
||||
border-color: #1861ac;
|
||||
}
|
||||
|
||||
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
|
||||
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 1.1rem;
|
||||
}
|
||||
|
||||
.valid.modified:not([type=checkbox]) {
|
||||
outline: 1px solid #26b050;
|
||||
}
|
||||
|
||||
.invalid {
|
||||
outline: 1px solid red;
|
||||
}
|
||||
|
||||
.validation-message {
|
||||
color: red;
|
||||
}
|
||||
|
||||
#blazor-error-ui {
|
||||
background: lightyellow;
|
||||
bottom: 0;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
|
||||
display: none;
|
||||
left: 0;
|
||||
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
#blazor-error-ui .dismiss {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 0.75rem;
|
||||
top: 0.5rem;
|
||||
}
|
||||
|
||||
.blazor-error-boundary {
|
||||
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
|
||||
padding: 1rem 1rem 1rem 3.7rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.blazor-error-boundary::after {
|
||||
content: "An error has occurred."
|
||||
}
|
||||
|
||||
.loading-progress {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 8rem;
|
||||
height: 8rem;
|
||||
margin: 20vh auto 1rem auto;
|
||||
}
|
||||
|
||||
.loading-progress circle {
|
||||
fill: none;
|
||||
stroke: #e0e0e0;
|
||||
stroke-width: 0.6rem;
|
||||
transform-origin: 50% 50%;
|
||||
transform: rotate(-90deg);
|
||||
}
|
||||
|
||||
.loading-progress circle:last-child {
|
||||
stroke: #1b6ec2;
|
||||
stroke-dasharray: calc(3.141 * var(--blazor-load-percentage, 0%) * 0.8), 500%;
|
||||
transition: stroke-dasharray 0.05s ease-in-out;
|
||||
}
|
||||
|
||||
.loading-progress-text {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
inset: calc(20vh + 3.25rem) 0 auto 0.2rem;
|
||||
}
|
||||
|
||||
.loading-progress-text:after {
|
||||
content: var(--blazor-load-percentage-text, "Loading");
|
||||
}
|
||||
|
||||
code {
|
||||
color: #c02d76;
|
||||
}
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.1 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.6 KiB |
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>TriangleWasm</title>
|
||||
<base href="/" />
|
||||
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
||||
<link rel="stylesheet" href="css/app.css" />
|
||||
<link rel="icon" type="image/png" href="favicon.png" />
|
||||
<link href="TriangleWasm.styles.css" rel="stylesheet" />
|
||||
<script>
|
||||
function setCanvas(cbAsm, cbFun){
|
||||
console.log(`setCanvas(${cbAsm}, ${cbFun})`)
|
||||
Module['canvas'] = document.getElementById('canvas');
|
||||
const observer = new MutationObserver(function(mutations_list) {
|
||||
mutations_list.forEach(function(mutation) {
|
||||
mutation.removedNodes.forEach(function(removed_node) {
|
||||
console.log("rm - " + removed_node);
|
||||
if(removed_node.id === 'canvas') {
|
||||
console.log('#canvas has been removed');
|
||||
observer.disconnect();
|
||||
DotNet.invokeMethod(cbAsm, cbFun);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
observer.observe(document, {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
subtree: true,
|
||||
characterData: true
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app">
|
||||
<svg class="loading-progress">
|
||||
<circle r="40%" cx="50%" cy="50%" />
|
||||
<circle r="40%" cx="50%" cy="50%" />
|
||||
</svg>
|
||||
<div class="loading-progress-text"></div>
|
||||
</div>
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
An unhandled error has occurred.
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
</div>
|
||||
<script src="_framework/blazor.webassembly.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
[
|
||||
{
|
||||
"date": "2022-01-06",
|
||||
"temperatureC": 1,
|
||||
"summary": "Freezing"
|
||||
},
|
||||
{
|
||||
"date": "2022-01-07",
|
||||
"temperatureC": 14,
|
||||
"summary": "Bracing"
|
||||
},
|
||||
{
|
||||
"date": "2022-01-08",
|
||||
"temperatureC": -13,
|
||||
"summary": "Freezing"
|
||||
},
|
||||
{
|
||||
"date": "2022-01-09",
|
||||
"temperatureC": -16,
|
||||
"summary": "Balmy"
|
||||
},
|
||||
{
|
||||
"date": "2022-01-10",
|
||||
"temperatureC": -2,
|
||||
"summary": "Chilly"
|
||||
}
|
||||
]
|
|
@ -1,7 +1,7 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0-android;net6.0-ios</TargetFrameworks>
|
||||
<TargetFrameworks>netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0</TargetFrameworks>
|
||||
<Nullable>enable</Nullable>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
|
|
@ -23,6 +23,8 @@ namespace Silk.NET.OpenGL
|
|||
[PInvokeOverride(0, "dummy")]
|
||||
public partial class GL
|
||||
{
|
||||
private static OVERRIDE_0? _o0;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a <see cref="GL" /> instance from an <see cref="IGLContextSource" />.
|
||||
/// </summary>
|
||||
|
@ -35,8 +37,7 @@ namespace Silk.NET.OpenGL
|
|||
public static GL GetApi(IGLContextSource contextSource)
|
||||
{
|
||||
// This is to make the Mono P/Invoke signature generator happy. Else it wont find the OpenGL function pointer signatures
|
||||
if(RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")))
|
||||
CreateDefaultContext("dummy");
|
||||
_o0 ??= new OVERRIDE_0();
|
||||
return GetApi
|
||||
(
|
||||
contextSource.GLContext ??
|
||||
|
@ -527,7 +528,7 @@ namespace Silk.NET.OpenGL
|
|||
|
||||
var length = (uint) length2;
|
||||
GetShaderInfoLog(shader, length * 2, out length, out info);
|
||||
info = info.Substring(0, (int) length);
|
||||
info = (int) length <= info.Length ? info.Substring(0, (int) length) : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -563,9 +564,15 @@ namespace Silk.NET.OpenGL
|
|||
public void GetProgramInfoLog(uint program, out string info)
|
||||
{
|
||||
GetProgram(program, GLEnum.InfoLogLength, out var length2);
|
||||
if (length2 <= 0)
|
||||
{
|
||||
info = string.Empty;
|
||||
return;
|
||||
}
|
||||
|
||||
var length = (uint) length2;
|
||||
GetProgramInfoLog(program, length * 2, out length, out info);
|
||||
info = info.Substring(0, (int) length);
|
||||
info = (int) length <= info.Length ? info.Substring(0, (int) length) : string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -9,7 +9,7 @@ using Silk.NET.Core.Attributes;
|
|||
|
||||
namespace Silk.NET.SDL
|
||||
{
|
||||
[NativeName("AnonymousName", "__AnonymousEnum_SDL_hints_L2429_C9")]
|
||||
[NativeName("AnonymousName", "__AnonymousEnum_SDL_hints_L2416_C9")]
|
||||
[NativeName("Name", "SDL_HintPriority")]
|
||||
public enum HintPriority : int
|
||||
{
|
||||
|
|
|
@ -9,7 +9,7 @@ using Silk.NET.Core.Attributes;
|
|||
|
||||
namespace Silk.NET.SDL
|
||||
{
|
||||
[NativeName("AnonymousName", "__AnonymousEnum_SDL_video_L1708_C9")]
|
||||
[NativeName("AnonymousName", "__AnonymousEnum_SDL_video_L1681_C9")]
|
||||
[NativeName("Name", "SDL_HitTestResult")]
|
||||
public enum HitTestResult : int
|
||||
{
|
||||
|
|
|
@ -13,20 +13,11 @@ namespace Silk.NET.SDL
|
|||
[NativeName("Name", "SDL_ScaleMode")]
|
||||
public enum ScaleMode : int
|
||||
{
|
||||
[Obsolete("Deprecated in favour of \"Nearest\"")]
|
||||
[NativeName("Name", "SDL_ScaleModeNearest")]
|
||||
ScaleModeNearest = 0x0,
|
||||
[Obsolete("Deprecated in favour of \"Linear\"")]
|
||||
[NativeName("Name", "SDL_ScaleModeLinear")]
|
||||
ScaleModeLinear = 0x1,
|
||||
[Obsolete("Deprecated in favour of \"Best\"")]
|
||||
[NativeName("Name", "SDL_ScaleModeBest")]
|
||||
ScaleModeBest = 0x2,
|
||||
[NativeName("Name", "SDL_ScaleModeNearest")]
|
||||
Nearest = 0x0,
|
||||
[NativeName("Name", "SDL_ScaleModeLinear")]
|
||||
Linear = 0x1,
|
||||
[NativeName("Name", "SDL_ScaleModeBest")]
|
||||
Best = 0x2,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ using Silk.NET.Core.Attributes;
|
|||
|
||||
namespace Silk.NET.SDL
|
||||
{
|
||||
[NativeName("AnonymousName", "__AnonymousEnum_SDL_stdinc_L180_C9")]
|
||||
[NativeName("AnonymousName", "__AnonymousEnum_SDL_stdinc_L186_C9")]
|
||||
[NativeName("Name", "SDL_bool")]
|
||||
public enum SdlBool : int
|
||||
{
|
||||
|
|
|
@ -12,25 +12,13 @@ namespace Silk.NET.SDL
|
|||
[NativeName("Name", "__AnonymousEnum_SDL_shape_L85_C9")]
|
||||
public enum WindowShapeModeVal : int
|
||||
{
|
||||
[Obsolete("Deprecated in favour of \"Default\"")]
|
||||
[NativeName("Name", "ShapeModeDefault")]
|
||||
ShapeModeDefault = 0x0,
|
||||
[Obsolete("Deprecated in favour of \"BinarizeAlpha\"")]
|
||||
[NativeName("Name", "ShapeModeBinarizeAlpha")]
|
||||
ShapeModeBinarizeAlpha = 0x1,
|
||||
[Obsolete("Deprecated in favour of \"ReverseBinarizeAlpha\"")]
|
||||
[NativeName("Name", "ShapeModeReverseBinarizeAlpha")]
|
||||
ShapeModeReverseBinarizeAlpha = 0x2,
|
||||
[Obsolete("Deprecated in favour of \"ColorKey\"")]
|
||||
[NativeName("Name", "ShapeModeColorKey")]
|
||||
ShapeModeColorKey = 0x3,
|
||||
[NativeName("Name", "ShapeModeDefault")]
|
||||
Default = 0x0,
|
||||
[NativeName("Name", "ShapeModeBinarizeAlpha")]
|
||||
BinarizeAlpha = 0x1,
|
||||
[NativeName("Name", "ShapeModeReverseBinarizeAlpha")]
|
||||
ReverseBinarizeAlpha = 0x2,
|
||||
[NativeName("Name", "ShapeModeColorKey")]
|
||||
ColorKey = 0x3,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,9 @@ namespace Silk.NET.SDL
|
|||
// ideally we'd only use override 1 on android, but we can't really do that until it's better supported in .net 6
|
||||
// (we'd need a preprocessor directive which is only available in xamarin)
|
||||
[PInvokeOverride(2, "SDL")]
|
||||
[PInvokeOverride(1, "libSDL2.so")]
|
||||
[PInvokeOverride(0, "__Internal")]
|
||||
public partial class Sdl
|
||||
{
|
||||
public static Sdl PleaseDontTryThisAtHomeGetApi() => new Sdl(new OVERRIDE_2());
|
||||
public const uint InitEverything = InitTimer | InitAudio | InitVideo |
|
||||
InitEvents | InitJoystick | InitHaptic |
|
||||
InitGamecontroller | InitSensor;
|
||||
|
@ -32,7 +31,7 @@ namespace Silk.NET.SDL
|
|||
|
||||
public const string HintAppleTvRemoteAllowRotation =
|
||||
"SDL_APPLE_TV_REMOTE_ALLOW_ROTATION";
|
||||
|
||||
|
||||
[Obsolete("Use HintIosHideHomeIndicator instead.")]
|
||||
public const string HintIOSHideHomeIndicator = HintIosHideHomeIndicator;
|
||||
|
||||
|
@ -43,7 +42,7 @@ namespace Silk.NET.SDL
|
|||
public const string HintJoystickHidapiPs4 = HintJoystickHidapiPS4;
|
||||
|
||||
[Obsolete("Use HintJoystickHidapiPS4Rumble instead.")]
|
||||
public const string HintJoystickHidapiPs4Rumble = HintJoystickHidapiPS4Rumble;
|
||||
public const string HintJoystickHidapiPs4Rumble =HintJoystickHidapiPS4Rumble;
|
||||
|
||||
[Obsolete("Use HintVideoX11WindowVisualid instead.")]
|
||||
public const string HintVidoX11WindowVisualid = HintVideoX11WindowVisualid;
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -3,6 +3,7 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Silk.NET.Core.Loader;
|
||||
|
||||
namespace Silk.NET.SDL
|
||||
{
|
||||
|
@ -34,7 +35,14 @@ namespace Silk.NET.SDL
|
|||
/// </summary>
|
||||
static SdlProvider()
|
||||
{
|
||||
UninitializedSDL = new Lazy<Sdl>(Sdl.GetApi);
|
||||
UninitializedSDL = new Lazy<Sdl>(() =>
|
||||
{
|
||||
Console.WriteLine("HI THERE: " + SearchPathContainer.Platform);
|
||||
return SearchPathContainer.Platform == UnderlyingPlatform.Browser
|
||||
? Sdl.PleaseDontTryThisAtHomeGetApi()
|
||||
: Sdl.GetApi();
|
||||
}
|
||||
);
|
||||
SDL = new Lazy<Sdl>(GetSdl);
|
||||
}
|
||||
|
||||
|
@ -81,7 +89,14 @@ namespace Silk.NET.SDL
|
|||
{
|
||||
SDL.Value.Quit();
|
||||
SDL.Value.Dispose();
|
||||
UninitializedSDL = new Lazy<Sdl>(Sdl.GetApi);
|
||||
UninitializedSDL = new Lazy<Sdl>(() =>
|
||||
{
|
||||
Console.WriteLine("HI THERE: " + SearchPathContainer.Platform);
|
||||
return SearchPathContainer.Platform == UnderlyingPlatform.Browser
|
||||
? Sdl.PleaseDontTryThisAtHomeGetApi()
|
||||
: Sdl.GetApi();
|
||||
}
|
||||
);
|
||||
SDL = new Lazy<Sdl>(GetSdl);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,20 +6,13 @@
|
|||
<LangVersion>preview</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net5.0|AnyCPU'">
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|net5.0|AnyCPU'">
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ultz.Native.SDL" Version="2.*" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Maths\Silk.NET.Maths\Silk.NET.Maths.csproj" />
|
||||
<SilkPInvokeOverride Include="2" SilkClass="Silk.NET.SDL.Sdl" DownstreamCondition="false" />
|
||||
<SilkPInvokeOverride Include="1" SilkClass="Silk.NET.SDL.Sdl" DownstreamCondition="%24(TargetFramework.Contains('android'))" />
|
||||
<SilkPInvokeOverride Include="0" SilkClass="Silk.NET.SDL.Sdl" DownstreamCondition="%24(TargetFramework.Contains('ios')) or %24(TargetFramework.Contains('mac')) or %24(TargetFramework.Contains('tvos'))" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace Silk.NET.Windowing;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
/// <summary>
|
||||
/// A view that receives canvas drop notifications.
|
||||
/// </summary>
|
||||
public interface INotifyCanvasDropped : IView
|
||||
{
|
||||
/// <summary>
|
||||
/// The canvas has been dropped.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("browser")]
|
||||
void CanvasDropped();
|
||||
}
|
||||
#endif
|
|
@ -146,4 +146,4 @@ namespace Silk.NET.Windowing
|
|||
/// <param name="onFrame">The callback to run each frame.</param>
|
||||
void Run(Action onFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ using System.Diagnostics;
|
|||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading;
|
||||
using Silk.NET.Core.Contexts;
|
||||
using Silk.NET.Maths;
|
||||
|
@ -33,6 +34,7 @@ namespace Silk.NET.Windowing.Internals
|
|||
private double _renderPeriod;
|
||||
private double _updatePeriod;
|
||||
private bool _inRenderLoop;
|
||||
private bool _emLooping;
|
||||
|
||||
// Invocations
|
||||
private readonly ArrayPool<object> _returnArrayPool = ArrayPool<object>.Create();
|
||||
|
@ -203,9 +205,21 @@ namespace Silk.NET.Windowing.Internals
|
|||
#if NET6_0_OR_GREATER
|
||||
if(RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")))
|
||||
{
|
||||
if (_browserView is not null)
|
||||
{
|
||||
if (_browserView == this)
|
||||
{
|
||||
Console.WriteLine("changing main loop, this is questionable behaviour.");
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("Multiple browser views in the loop!");
|
||||
}
|
||||
}
|
||||
_browserView = this;
|
||||
_onFrame = onFrame;
|
||||
emscripten_set_main_loop((IntPtr)(delegate* unmanaged[Cdecl] <void>)&onFrameCallback, 0, true);
|
||||
emscripten_set_main_loop((IntPtr)(delegate* unmanaged[Cdecl] <void>)&onFrameCallback, 0, false);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -233,7 +247,7 @@ namespace Silk.NET.Windowing.Internals
|
|||
if (!IsContextControlDisabled && _swapIntervalChanged)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Create("BROWSER")))
|
||||
if (OperatingSystem.IsBrowser())
|
||||
{
|
||||
emscripten_set_main_loop_timing(VSync ? LoopTimingMode.RAF : LoopTimingMode.SetTimeout, VSync ? 1 : 0);
|
||||
}
|
||||
|
@ -258,6 +272,22 @@ namespace Silk.NET.Windowing.Internals
|
|||
_inRenderLoop = false;
|
||||
}
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
[SupportedOSPlatform("browser")]
|
||||
internal void CanvasDropped()
|
||||
{
|
||||
emscripten_cancel_main_loop();
|
||||
DoEvents();
|
||||
Dispose();
|
||||
if (this is INotifyCanvasDropped notify)
|
||||
{
|
||||
notify.CanvasDropped();
|
||||
}
|
||||
|
||||
_browserView = null;
|
||||
}
|
||||
#endif
|
||||
|
||||
public void DoUpdate()
|
||||
{
|
||||
_inRenderLoop = true;
|
||||
|
|
|
@ -6,3 +6,7 @@ Silk.NET.Windowing.VideoMode.AspectRatioEstimate.get -> Silk.NET.Maths.Vector2D<
|
|||
Silk.NET.Windowing.WindowOptions.TopMost.get -> bool
|
||||
Silk.NET.Windowing.WindowOptions.TopMost.set -> void
|
||||
Silk.NET.Windowing.WindowOptions.WindowOptions(bool isVisible, Silk.NET.Maths.Vector2D<int> position, Silk.NET.Maths.Vector2D<int> size, double framesPerSecond, double updatesPerSecond, Silk.NET.Windowing.GraphicsAPI api, string! title, Silk.NET.Windowing.WindowState windowState, Silk.NET.Windowing.WindowBorder windowBorder, bool isVSync, bool shouldSwapAutomatically, Silk.NET.Windowing.VideoMode videoMode, int? preferredDepthBufferBits = null, int? preferredStencilBufferBits = null, Silk.NET.Maths.Vector4D<int>? preferredBitDepth = null, bool transparentFramebuffer = false, bool topMost = false, bool isEventDriven = false, Silk.NET.Core.Contexts.IGLContext? sharedContext = null, int? samples = null, string? windowClass = null, bool isContextControlDisabled = false) -> void
|
||||
static Silk.NET.Windowing.Window.PrioritizeOrAdd<T>(System.Func<T>! factory, bool isFirstParty = false) -> T
|
||||
Silk.NET.Windowing.INotifyCanvasDropped
|
||||
Silk.NET.Windowing.INotifyCanvasDropped.CanvasDropped() -> void
|
||||
static Silk.NET.Windowing.Window.CanvasDropped(Silk.NET.Windowing.IView! view) -> void
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#nullable enable
|
||||
Silk.NET.Windowing.IView.Run(System.Action! onFrame) -> bool
|
||||
Silk.NET.Windowing.IWindowPlatform.Name.get -> string!
|
||||
Silk.NET.Windowing.IWindowProperties.TopMost.get -> bool
|
||||
Silk.NET.Windowing.IWindowProperties.TopMost.set -> void
|
||||
|
|
|
@ -7,6 +7,8 @@ using System.Diagnostics;
|
|||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Versioning;
|
||||
using Silk.NET.Windowing.Internals;
|
||||
|
||||
namespace Silk.NET.Windowing
|
||||
{
|
||||
|
@ -364,5 +366,10 @@ namespace Silk.NET.Windowing
|
|||
/// <returns>The instance of the window platform type or <c>default</c></returns>
|
||||
public static T? GetOrDefault<T>() where T : class, IWindowPlatform
|
||||
=> _platformsKeys.Contains(typeof(T)) ? (T) _platformsValues[_platformsKeys.IndexOf(typeof(T))] : default;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
[SupportedOSPlatform("browser")]
|
||||
public static void CanvasDropped(IView view) => (view as ViewImplementationBase)?.CanvasDropped();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,8 +59,13 @@ namespace Silk.NET.Windowing
|
|||
}
|
||||
);
|
||||
|
||||
view.DoEvents();
|
||||
view.Reset();
|
||||
// the above may not be an infinite loop, check whether it looks like we wanted to exit an infinite loop
|
||||
// (if any)
|
||||
if (view.IsClosing)
|
||||
{
|
||||
view.DoEvents();
|
||||
view.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SwapBuffers(this IView view) => view.GLContext?.SwapBuffers();
|
||||
|
@ -113,4 +118,4 @@ namespace Silk.NET.Windowing
|
|||
(new[] { icon });
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Silk.NET.Windowing.Sdl
|
|||
{
|
||||
internal class SdlPlatform : IWindowPlatform
|
||||
{
|
||||
private SdlView? _view;
|
||||
internal SdlView? _view;
|
||||
private List<Event> _eventBuffer = new();
|
||||
private BreakneckLock _lock = BreakneckLock.Create();
|
||||
public static SdlPlatform GetOrRegister()
|
||||
|
@ -37,7 +37,7 @@ namespace Silk.NET.Windowing.Sdl
|
|||
try
|
||||
{
|
||||
Console.WriteLine($"Trying to get sdl api");
|
||||
SDL.Sdl.GetApi();
|
||||
_ = SdlProvider.UninitializedSDL.Value;
|
||||
Console.WriteLine($"after sdl API");
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
|
@ -7,6 +7,7 @@ using System.Reflection;
|
|||
using System.Threading;
|
||||
using Silk.NET.Core;
|
||||
using Silk.NET.Core.Contexts;
|
||||
using Silk.NET.Core.Loader;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.SDL;
|
||||
using Silk.NET.Windowing.Internals;
|
||||
|
@ -19,6 +20,9 @@ using Silk.NET.Windowing.Internals;
|
|||
namespace Silk.NET.Windowing.Sdl
|
||||
{
|
||||
internal unsafe class SdlView : ViewImplementationBase
|
||||
#if NET6_0_OR_GREATER
|
||||
, INotifyCanvasDropped
|
||||
#endif
|
||||
{
|
||||
protected readonly SdlPlatform _platform;
|
||||
private const int WaitTimeout = 10;
|
||||
|
@ -117,6 +121,7 @@ namespace Silk.NET.Windowing.Sdl
|
|||
{
|
||||
flags |= _platform.IsViewOnly switch
|
||||
{
|
||||
true when SearchPathContainer.Platform == UnderlyingPlatform.Browser => WindowFlags.Borderless | WindowFlags.Resizable,
|
||||
true => WindowFlags.Borderless | WindowFlags.Fullscreen | WindowFlags.Resizable,
|
||||
false => WindowFlags.Resizable
|
||||
};
|
||||
|
@ -472,5 +477,14 @@ namespace Silk.NET.Windowing.Sdl
|
|||
|
||||
EndEventProcessing(taken);
|
||||
}
|
||||
#if NET6_0_OR_GREATER
|
||||
public void CanvasDropped()
|
||||
{
|
||||
if (_platform._view == this)
|
||||
{
|
||||
_platform._view = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче