Skip to content

Commit 68bbb55

Browse files
committed
Added example and improved api.
1 parent b3d3713 commit 68bbb55

File tree

12 files changed

+1219
-132
lines changed

12 files changed

+1219
-132
lines changed

Example/DebugDrawRenderer.cs

Lines changed: 504 additions & 0 deletions
Large diffs are not rendered by default.

Example/Example.csproj

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Silk.NET" Version="2.21.0" />
13+
<PackageReference Include="Silk.NET.Input.Extensions" Version="2.21.0" />
14+
<PackageReference Include="Silk.NET.OpenGL" Version="2.21.0" />
15+
<PackageReference Include="System.Text.Json" Version="8.0.4" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\Hexa.NET.DebugDraw\Hexa.NET.DebugDraw.csproj" />
20+
</ItemGroup>
21+
22+
</Project>

Example/Globals.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
global using static Hexa.NET.Utilities.Utils;

Example/Program.cs

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
namespace Example
2+
{
3+
using Hexa.NET.DebugDraw;
4+
using Hexa.NET.Mathematics;
5+
using Silk.NET.Input;
6+
using Silk.NET.OpenGL;
7+
using Silk.NET.Windowing;
8+
using System.Numerics;
9+
10+
internal class Program
11+
{
12+
private static void Main(string[] args)
13+
{
14+
// Create a Silk.NET window as usual
15+
using var window = Window.Create(WindowOptions.Default);
16+
17+
// Declare some variables
18+
DebugDrawRenderer renderer = null;
19+
GL gl = null;
20+
IInputContext inputContext = null;
21+
22+
// Our loading function
23+
window.Load += () =>
24+
{
25+
renderer = new DebugDrawRenderer(
26+
gl = window.CreateOpenGL(), // load OpenGL,
27+
window
28+
);
29+
inputContext = window.CreateInput();
30+
};
31+
32+
// Handle resizes
33+
window.FramebufferResize += s =>
34+
{
35+
// Adjust the viewport to the new window size
36+
gl.Viewport(s);
37+
DebugDraw.SetViewport(new Viewport(0, 0, s.X, s.Y));
38+
};
39+
40+
Vector3 position = new(0, 5, -1);
41+
Quaternion rotation = new Vector3(0, 0, 0).ToRad().ToQuaternion();
42+
Matrix4x4 projection = MathUtil.PerspectiveFovLH(
43+
MathF.PI / 2, window.Size.X / window.Size.Y, 0.1f, 1000f
44+
);
45+
Vector3 target = Vector3.Transform(Vector3.UnitZ, rotation);
46+
Vector3 up = Vector3.Transform(Vector3.UnitY, rotation);
47+
Matrix4x4 view = MathUtil.LookAtLH(position, position + target, up);
48+
49+
Matrix4x4 vp = view * projection;
50+
51+
// The render function
52+
window.Render += delta =>
53+
{
54+
// Make sure ImGui is up-to-date
55+
renderer.BeginDraw();
56+
57+
DebugDraw.SetCamera(vp);
58+
59+
// This is where you'll do any rendering beneath the ImGui context
60+
// Here, we just have a blank screen.
61+
gl.ClearColor(System.Drawing.Color.FromArgb(255, (int)(.45f * 255), (int)(.55f * 255), (int)(.60f * 255)));
62+
gl.Clear((uint)ClearBufferMask.ColorBufferBit);
63+
gl.ClearDepth(1.0f);
64+
gl.Clear((uint)ClearBufferMask.DepthBufferBit);
65+
66+
DebugDraw.DrawGrid(Matrix4x4.Identity, 100, Vector4.One);
67+
68+
DebugDraw.DrawBox(new(2, 4, 5), Quaternion.Identity, 1, 1, 1, new(1, 0, 0, 1));
69+
70+
DebugDraw.DrawSphere(new(-2, 4, 5), Quaternion.Identity, 1, new(0, 1, 0, 1));
71+
72+
DebugDraw.DrawCapsule(new(0, 4, 5), Quaternion.Identity, 0.5f, 2, new(0, 0, 1, 1));
73+
74+
renderer.EndDraw();
75+
};
76+
77+
// The closing function
78+
window.Closing += () =>
79+
{
80+
// Dispose our controller first
81+
renderer?.Dispose();
82+
83+
// Dispose the input context
84+
inputContext?.Dispose();
85+
86+
// Unload OpenGL
87+
gl?.Dispose();
88+
};
89+
90+
// Now that everything's defined, let's run this bad boy!
91+
window.Run();
92+
93+
window.Dispose();
94+
}
95+
}
96+
}

Example/Shader.cs

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Diagnostics;
7+
using System.Runtime.CompilerServices;
8+
9+
#if GLES
10+
using Silk.NET.OpenGLES;
11+
#elif GL
12+
using Silk.NET.OpenGL;
13+
#elif LEGACY
14+
using Silk.NET.OpenGL.Legacy;
15+
#else
16+
17+
using Silk.NET.OpenGL;
18+
19+
#endif
20+
21+
#if GL
22+
namespace Silk.NET.OpenGL.Extensions.ImGui
23+
#elif GLES
24+
namespace Silk.NET.OpenGLES.Extensions.ImGui
25+
#elif LEGACY
26+
namespace Silk.NET.OpenGL.Legacy.Extensions.ImGui
27+
#else
28+
29+
namespace Example
30+
#endif
31+
{
32+
internal struct UniformFieldInfo
33+
{
34+
public int Location;
35+
public string Name;
36+
public int Size;
37+
public UniformType Type;
38+
}
39+
40+
internal class Shader
41+
{
42+
public uint Program { get; private set; }
43+
private readonly Dictionary<string, int> _uniformToLocation = new Dictionary<string, int>();
44+
private readonly Dictionary<string, int> _attribLocation = new Dictionary<string, int>();
45+
private bool _initialized = false;
46+
private GL _gl;
47+
private (ShaderType Type, string Path)[] _files;
48+
49+
public Shader(GL gl, string vertexShader, string fragmentShader)
50+
{
51+
_gl = gl;
52+
_files = new[]{
53+
(ShaderType.VertexShader, vertexShader),
54+
(ShaderType.FragmentShader, fragmentShader),
55+
};
56+
Program = CreateProgram(_files);
57+
}
58+
59+
public void UseShader()
60+
{
61+
_gl.UseProgram(Program);
62+
}
63+
64+
public void Dispose()
65+
{
66+
if (_initialized)
67+
{
68+
_gl.DeleteProgram(Program);
69+
_initialized = false;
70+
}
71+
}
72+
73+
public UniformFieldInfo[] GetUniforms()
74+
{
75+
_gl.GetProgram(Program, GLEnum.ActiveUniforms, out var uniformCount);
76+
77+
UniformFieldInfo[] uniforms = new UniformFieldInfo[uniformCount];
78+
79+
for (int i = 0; i < uniformCount; i++)
80+
{
81+
string name = _gl.GetActiveUniform(Program, (uint)i, out int size, out UniformType type);
82+
83+
UniformFieldInfo fieldInfo;
84+
fieldInfo.Location = GetUniformLocation(name);
85+
fieldInfo.Name = name;
86+
fieldInfo.Size = size;
87+
fieldInfo.Type = type;
88+
89+
uniforms[i] = fieldInfo;
90+
}
91+
92+
return uniforms;
93+
}
94+
95+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
96+
public int GetUniformLocation(string uniform)
97+
{
98+
if (_uniformToLocation.TryGetValue(uniform, out int location) == false)
99+
{
100+
location = _gl.GetUniformLocation(Program, uniform);
101+
_uniformToLocation.Add(uniform, location);
102+
103+
if (location == -1)
104+
{
105+
Debug.Print($"The uniform '{uniform}' does not exist in the shader!");
106+
}
107+
}
108+
109+
return location;
110+
}
111+
112+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
113+
public int GetAttribLocation(string attrib)
114+
{
115+
if (_attribLocation.TryGetValue(attrib, out int location) == false)
116+
{
117+
location = _gl.GetAttribLocation(Program, attrib);
118+
_attribLocation.Add(attrib, location);
119+
120+
if (location == -1)
121+
{
122+
Debug.Print($"The attrib '{attrib}' does not exist in the shader!");
123+
}
124+
}
125+
126+
return location;
127+
}
128+
129+
private uint CreateProgram(params (ShaderType Type, string source)[] shaderPaths)
130+
{
131+
var program = _gl.CreateProgram();
132+
133+
Span<uint> shaders = stackalloc uint[shaderPaths.Length];
134+
for (int i = 0; i < shaderPaths.Length; i++)
135+
{
136+
shaders[i] = CompileShader(shaderPaths[i].Type, shaderPaths[i].source);
137+
}
138+
139+
foreach (var shader in shaders)
140+
_gl.AttachShader(program, shader);
141+
142+
_gl.LinkProgram(program);
143+
144+
_gl.GetProgram(program, GLEnum.LinkStatus, out var success);
145+
if (success == 0)
146+
{
147+
string info = _gl.GetProgramInfoLog(program);
148+
Debug.WriteLine($"GL.LinkProgram had info log:\n{info}");
149+
}
150+
151+
foreach (var shader in shaders)
152+
{
153+
_gl.DetachShader(program, shader);
154+
_gl.DeleteShader(shader);
155+
}
156+
157+
_initialized = true;
158+
159+
return program;
160+
}
161+
162+
private uint CompileShader(ShaderType type, string source)
163+
{
164+
var shader = _gl.CreateShader(type);
165+
_gl.ShaderSource(shader, source);
166+
_gl.CompileShader(shader);
167+
168+
_gl.GetShader(shader, ShaderParameterName.CompileStatus, out var success);
169+
if (success == 0)
170+
{
171+
string info = _gl.GetShaderInfoLog(shader);
172+
Debug.WriteLine($"GL.CompileShader for shader [{type}] had info log:\n{info}");
173+
}
174+
175+
return shader;
176+
}
177+
}
178+
}

0 commit comments

Comments
 (0)