Skip to content

Commit 10d15f6

Browse files
ThomasMizPerksey
andauthored
Project Templates for Windowing, OpenGL (#748)
* Initial template design * Applied first batch of suggestions * Removed unwanted coma (oops) * Applied suggestions on packaging * Added template projects to nuke exclusions * Added nuke exclusions, 2nd try * Moved templates to src/Templates * Code style changes * Applied meeting review suggestions Co-authored-by: Dylan Perks <[email protected]>
1 parent 487b526 commit 10d15f6

File tree

14 files changed

+365
-3
lines changed

14 files changed

+365
-3
lines changed

Silk.NET.sln

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PrototypeStructChaining.Tes
474474
EndProject
475475
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.Vulkan.Tests", "src\Vulkan\Silk.NET.Vulkan.Tests\Silk.NET.Vulkan.Tests.csproj", "{225BA79C-36FE-421A-85E4-D15F8B61869B}"
476476
EndProject
477+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Templates", "Templates", "{278FE083-D2F7-4DD2-9D27-6AD883E3A4B8}"
478+
EndProject
479+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.Templates", "src\Templates\Silk.NET.Templates\Silk.NET.Templates.csproj", "{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}"
480+
EndProject
477481
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.OpenGLES.ANGLE.Native", "src\Native\Silk.NET.OpenGLES.ANGLE.Native\Silk.NET.OpenGLES.ANGLE.Native.csproj", "{8D02DFEB-121A-449B-BC39-09C3F9A88E07}"
478482
EndProject
479483
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.Vulkan.Loader.Native", "src\Native\Silk.NET.Vulkan.Loader.Native\Silk.NET.Vulkan.Loader.Native.csproj", "{36C38837-8250-42F9-ABDA-DEFC1AB129E1}"
@@ -2925,6 +2929,18 @@ Global
29252929
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|x64.Build.0 = Release|Any CPU
29262930
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|x86.ActiveCfg = Release|Any CPU
29272931
{225BA79C-36FE-421A-85E4-D15F8B61869B}.Release|x86.Build.0 = Release|Any CPU
2932+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2933+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Debug|Any CPU.Build.0 = Debug|Any CPU
2934+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Debug|x64.ActiveCfg = Debug|Any CPU
2935+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Debug|x64.Build.0 = Debug|Any CPU
2936+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Debug|x86.ActiveCfg = Debug|Any CPU
2937+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Debug|x86.Build.0 = Debug|Any CPU
2938+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Release|Any CPU.ActiveCfg = Release|Any CPU
2939+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Release|Any CPU.Build.0 = Release|Any CPU
2940+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Release|x64.ActiveCfg = Release|Any CPU
2941+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Release|x64.Build.0 = Release|Any CPU
2942+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Release|x86.ActiveCfg = Release|Any CPU
2943+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2}.Release|x86.Build.0 = Release|Any CPU
29282944
{8D02DFEB-121A-449B-BC39-09C3F9A88E07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
29292945
{8D02DFEB-121A-449B-BC39-09C3F9A88E07}.Debug|Any CPU.Build.0 = Debug|Any CPU
29302946
{8D02DFEB-121A-449B-BC39-09C3F9A88E07}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -3574,6 +3590,8 @@ Global
35743590
{EEFF37DA-E4F2-406E-AF97-8615BB7BC34C} = {B15922CB-815C-4038-B635-EE2D8A8F700B}
35753591
{BD19250B-E143-4F4E-9E1D-18829CCB3642} = {B15922CB-815C-4038-B635-EE2D8A8F700B}
35763592
{225BA79C-36FE-421A-85E4-D15F8B61869B} = {E2ABDF45-C329-47B2-8E09-B7298E2557F7}
3593+
{278FE083-D2F7-4DD2-9D27-6AD883E3A4B8} = {16AFCF73-8CC1-4B5D-8969-A90F468DC6D5}
3594+
{4D65197C-79B2-40CF-846E-C1EAB4F6EEA2} = {278FE083-D2F7-4DD2-9D27-6AD883E3A4B8}
35773595
{8D02DFEB-121A-449B-BC39-09C3F9A88E07} = {72E7FA64-5B1E-477D-BD30-63B7F206B3C4}
35783596
{36C38837-8250-42F9-ABDA-DEFC1AB129E1} = {72E7FA64-5B1E-477D-BD30-63B7F206B3C4}
35793597
{54F439B6-36E4-4FB0-8731-F73D42AD921F} = {72E7FA64-5B1E-477D-BD30-63B7F206B3C4}

build/nuke/Build.ReviewHelpers.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ partial class Build
1212
// ReSharper disable once RedundantEmptyObjectOrCollectionInitializer
1313
readonly HashSet<string> AllowedExclusions = new()
1414
{
15+
"silkwindow",
16+
"silkgl",
17+
"silkgltriangle",
18+
"DotZLib"
1519
};
1620

1721
Target ValidateSolution => CommonTarget
@@ -20,8 +24,8 @@ partial class Build
2024
(
2125
() =>
2226
{
23-
var files = SourceDirectory.GlobFiles("**/*.csproj").ToArray();
24-
Logger.Info($"Found {files.Length} csproj files in \"{SourceDirectory}\"");
27+
var files = RootDirectory.GlobFiles("**\\*.csproj").Concat(RootDirectory.GlobFiles("**/*.csproj")).ToArray();
28+
Logger.Info($"Found {files.Length} csproj files in \"{RootDirectory}\"");
2529
var missedOut = new List<string>();
2630
foreach (var file in files)
2731
{
@@ -41,7 +45,7 @@ partial class Build
4145
(
4246
"A project has not been included in the solution and will not be shipped! " +
4347
$"\"{file}\" if this is acceptable please add the project name (excluding the path and " +
44-
"extension) to the AllowedExclusions array in the NUKE Build.CI.AutoReview.cs file."
48+
"extension) to the AllowedExclusions array in the NUKE Build.ReviewHelpers.cs file."
4549
);
4650

4751
missedOut.Add(Path.GetRelativePath(RootDirectory, file).Replace('\\', '/'));
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#nullable enable
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#nullable enable
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
5+
<PackageType>Template</PackageType>
6+
<SilkDescription>A package with template projects for Silk.NET.</SilkDescription>
7+
<SilkExtendedDescription>This is a quick and easy way to get started with Silk.NET. First, install the templates using `dotnet new --install Silk.NET.Templates`, and then create a project using these templates:%0a- **OpenGL (with a triangle)**: `dotnet new silkgltriangle`%0a**OpenGL (blank)**: `dotnet new silkgl`%0a- **Blank Window**: `dotnet new silkwindow`</SilkExtendedDescription>
8+
<SilkSourceLinkExempt>true</SilkSourceLinkExempt>
9+
10+
<TargetFramework>netstandard2.0</TargetFramework>
11+
12+
<IncludeContentInPack>true</IncludeContentInPack>
13+
<IncludeBuildOutput>false</IncludeBuildOutput>
14+
<ContentTargetFolders>content</ContentTargetFolders>
15+
<NoWarn>$(NoWarn);NU5128</NoWarn>
16+
</PropertyGroup>
17+
18+
<ItemGroup>
19+
<Content Include="templates\**\*" Exclude="templates\**\bin\**;templates\**\obj\**" />
20+
</ItemGroup>
21+
22+
<Import Project="..\..\..\build\props\common.props"/>
23+
24+
</Project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema": "http://json.schemastore.org/template",
3+
"author": ".NET Foundation and Contributors",
4+
"classifications": [ "Silk.NET" ],
5+
"identity": "Silk.NET.Templates.SilkGL",
6+
"name": "Silk.NET Window (OpenGL)",
7+
"shortName": "silkgl",
8+
"description": "A Silk.NET Window with user input and an OpenGL Context.",
9+
"tags": {
10+
"language": "C#",
11+
"type": "project"
12+
}
13+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using Silk.NET.Windowing;
2+
using Silk.NET.Input;
3+
using Silk.NET.OpenGL;
4+
5+
WindowOptions windowOptions = WindowOptions.Default with
6+
{
7+
Title = "My Silk.NET Window",
8+
PreferredDepthBufferBits = 24,
9+
PreferredStencilBufferBits = 8,
10+
API = new GraphicsAPI(ContextAPI.OpenGL, new APIVersion(3, 3))
11+
};
12+
13+
using IWindow window = Window.Create(windowOptions);
14+
IInputContext inputContext = null!;
15+
GL gl = null!;
16+
17+
window.Load += () =>
18+
{
19+
// ran on first startup - use this event to initialize stuff.
20+
gl = window.CreateOpenGL();
21+
inputContext = window.CreateInput();
22+
gl.Viewport(window.FramebufferSize);
23+
};
24+
25+
window.Update += deltaSeconds =>
26+
{
27+
// ran every frame but before render - use this event to update data (e.g. physics).
28+
};
29+
30+
window.Render += deltaSeconds =>
31+
{
32+
// ran every frame but after update - use this event to draw.
33+
};
34+
35+
window.FramebufferResize += newSize =>
36+
{
37+
// ran when the window framebuffer is resized - usually used to update the viewport and, in 3D apps, view matrices.
38+
gl.Viewport(newSize);
39+
};
40+
41+
window.Closing += () =>
42+
{
43+
// ran just before the window closes.
44+
};
45+
46+
window.Run();
47+
gl.Dispose();
48+
inputContext.Dispose();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net6.0</TargetFramework>
6+
</PropertyGroup>
7+
8+
<ItemGroup>
9+
<PackageReference Include="Silk.NET.Windowing" Version="2.*" />
10+
<PackageReference Include="Silk.NET.Input" Version="2.*" />
11+
<PackageReference Include="Silk.NET.OpenGL" Version="2.*" />
12+
</ItemGroup>
13+
14+
</Project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"$schema": "http://json.schemastore.org/template",
3+
"author": ".NET Foundation and Contributors",
4+
"classifications": [ "Silk.NET" ],
5+
"identity": "Silk.NET.Templates.SilkGLTriangle",
6+
"name": "Silk.NET Triangle (OpenGL)",
7+
"shortName": "silkgltriangle",
8+
"description": "A Silk.NET Window with an OpenGL Context drawing a triangle.",
9+
"tags": {
10+
"language": "C#",
11+
"type": "project"
12+
}
13+
}
Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
using System;
2+
using System.Numerics;
3+
using System.Runtime.InteropServices;
4+
using Silk.NET.Windowing;
5+
using Silk.NET.Input;
6+
using Silk.NET.OpenGL;
7+
8+
WindowOptions windowOptions = WindowOptions.Default with
9+
{
10+
Title = "My Silk.NET Triangle",
11+
PreferredDepthBufferBits = 24,
12+
PreferredStencilBufferBits = 8,
13+
API = new GraphicsAPI(ContextAPI.OpenGL, new APIVersion(3, 3))
14+
};
15+
16+
using IWindow window = Window.Create(windowOptions);
17+
IInputContext inputContext = null!;
18+
GL gl = null!;
19+
20+
uint vbo = 0;
21+
uint vao = 0;
22+
uint shader = 0;
23+
24+
const string VertexShaderCode = @"
25+
#version 330 core
26+
layout (location = 0) in vec3 vPosition;
27+
layout (location = 1) in vec4 vColor;
28+
29+
out vec4 fColor;
30+
31+
void main() {
32+
gl_Position = vec4(vPosition, 1.0);
33+
fColor = vColor;
34+
}";
35+
36+
const string FragmentShaderCode = @"
37+
#version 330 core
38+
in vec4 fColor;
39+
40+
out vec4 FragColor;
41+
42+
void main() {
43+
FragColor = fColor;
44+
}";
45+
46+
window.Load += () =>
47+
{
48+
// ran on first startup - use this event to initialize stuff.
49+
gl = window.CreateOpenGL();
50+
inputContext = window.CreateInput();
51+
52+
// We create a Span with our vertex data. Since it's very little
53+
// data, we'll just allocate it in the stack.
54+
Span<Vertex> vertexData = stackalloc Vertex[]
55+
{
56+
new Vertex(new Vector3(-0.5f, -0.5f, 0), 255, 0, 0, 255),
57+
new Vertex(new Vector3(0, 0.5f, 0), 0, 255, 0, 255),
58+
new Vertex(new Vector3(0.5f, -0.5f, 0), 0, 0, 255, 255)
59+
};
60+
61+
// We create or GL Buffer Object, bind it and fill it up with data
62+
// from our span.
63+
vbo = gl.GenBuffer();
64+
gl.BindBuffer(BufferTargetARB.ArrayBuffer, vbo);
65+
gl.BufferData<Vertex>(BufferTargetARB.ArrayBuffer, vertexData, BufferUsageARB.StaticDraw);
66+
67+
// We create or GL Vertex Array Object, bind it and specify two
68+
// vertex attributes sourced from the currently bound buffer;
69+
// Attrib 0: 3 floats (a vec3)
70+
// Attrib 1: 4 unsigned bytes, normalized into a vec4
71+
vao = gl.GenVertexArray();
72+
gl.BindVertexArray(vao);
73+
unsafe
74+
{
75+
gl.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, Vertex.Size, (void*)0);
76+
gl.VertexAttribPointer(1, 4, VertexAttribPointerType.UnsignedByte, true, Vertex.Size, (void*)12);
77+
}
78+
gl.EnableVertexAttribArray(0);
79+
gl.EnableVertexAttribArray(1);
80+
81+
// We create the vertex shader, give it it's source code, and compile.
82+
uint vs = gl.CreateShader(ShaderType.VertexShader);
83+
gl.ShaderSource(vs, VertexShaderCode);
84+
gl.CompileShader(vs);
85+
86+
// We create the fragment shader, give it it's source code, and compile.
87+
uint fs = gl.CreateShader(ShaderType.FragmentShader);
88+
gl.ShaderSource(fs, FragmentShaderCode);
89+
gl.CompileShader(fs);
90+
91+
// We create the GL Shader Program Object, which links the vertex and
92+
// fragment shaders into a single program.
93+
shader = gl.CreateProgram();
94+
gl.AttachShader(shader, vs);
95+
gl.AttachShader(shader, fs);
96+
gl.LinkProgram(shader);
97+
98+
// We detach the shaders from the program and delete them. This won't
99+
// have any effect until the program itself is re-linked or deleted.
100+
gl.DetachShader(shader, vs);
101+
gl.DetachShader(shader, fs);
102+
gl.DeleteShader(vs);
103+
gl.DeleteShader(fs);
104+
105+
gl.Viewport(window.FramebufferSize);
106+
};
107+
108+
window.Update += deltaSeconds =>
109+
{
110+
// ran every frame but before render - use this event to update data (e.g. physics).
111+
};
112+
113+
window.Render += deltaSeconds =>
114+
{
115+
// ran every frame but after update - use this event to draw.
116+
117+
// Clear the whole screen to black.
118+
gl.ClearColor(0f, 0f, 0f, 1f);
119+
gl.Clear(ClearBufferMask.ColorBufferBit);
120+
121+
// Draw the 3 vertices from our buffer object as a single triangle.
122+
gl.BindVertexArray(vao);
123+
gl.UseProgram(shader);
124+
gl.DrawArrays(PrimitiveType.Triangles, 0, 3);
125+
};
126+
127+
window.FramebufferResize += newSize =>
128+
{
129+
// ran when the window framebuffer is resized - usually used to update the viewport and, in 3D apps, view matrices.
130+
gl.Viewport(newSize);
131+
};
132+
133+
window.Closing += () =>
134+
{
135+
// ran just before the window closes.
136+
gl.DeleteProgram(shader);
137+
gl.DeleteVertexArray(vao);
138+
gl.DeleteBuffer(vbo);
139+
};
140+
141+
window.Run();
142+
gl.Dispose();
143+
inputContext.Dispose();
144+
145+
[StructLayout(LayoutKind.Sequential)]
146+
record struct Vertex(Vector3 Position, byte R, byte G, byte B, byte A)
147+
{
148+
public static uint Size = 3 * 4 + 4;
149+
}

0 commit comments

Comments
 (0)