Skip to content

Commit

Permalink
Add Sokol samples
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalStrehovsky committed Jul 7, 2021
1 parent 97753d6 commit 14804c7
Show file tree
Hide file tree
Showing 4 changed files with 254 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# bflat
# bflat
C# as you know it but with Go-inspired tooling that produces small, selfcontained, and native executables out of the box.

```console
Expand Down
27 changes: 27 additions & 0 deletions samples/Sokol/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Sokol graphics/audio samples

Bflat includes the [Sokol](https://github.com/floooh/sokol) crossplatform 3D and audio APIs.

The C# bindings in use are these: https://github.com/MichalStrehovsky/sokol-csharp. The bindings are also available from NuGet so that they can also be used with official .NET tools outside bflat. The NuGet package is here: https://www.nuget.org/packages/sokol_csharp.unofficial/.

To build the triangle sample with bflat:

```console
$ bflat build triangle.cs --target:winexe
```

You can also build it as:

```console
$ bflat build triangle.cs --no-reflection --no-stacktrace-data --no-globalization --no-exception-messages --Os --target:winexe
```

On Windows, this will generate a small, ~720 kB executable.

To build the audio sample:

```console
$ bflat build saudio.cs --target:winexe
```

More samples are avilable at https://github.com/MichalStrehovsky/sokol-csharp. They're all C# translations of https://github.com/floooh/sokol-samples.
74 changes: 74 additions & 0 deletions samples/Sokol/saudio.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Runtime.InteropServices;

using Sokol;

App.Run(new() {
InitCb = &Init,
FrameCb = &Frame,
CleanupCb = &Cleanup,
Width = 640,
Height = 480,
WindowTitle = "Saudio (sokol-app)",
Icon = { SokolDefault = true },
});

[UnmanagedCallersOnly]
static void Init()
{
Gfx.Setup(new()
{
Context = App.Context(),
});

Audio.Setup(default);

State.PassAction.Colors[0] = new()
{
Action = Gfx.Action.Clear,
Value = new() { R = 1, G = 0.5f, B = 0, A = 1 },
};
}

[UnmanagedCallersOnly]
static void Frame()
{
Gfx.BeginDefaultPass(State.PassAction, App.Width(), App.Height());
var numFrames = Audio.Expect();
float s;
for (int i = 0; i < numFrames; i++)
{
if ((State.EvenOdd++ & (1 << 5)) != 0)
{
s = 0.05f;
}
else
{
s = -0.05f;
}
State.Samples[State.SamplePos++] = s;
if (State.SamplePos == State.Samples.Length)
{
State.SamplePos = 0;
Audio.Push(State.Samples[0], State.Samples.Length);
}

}
Gfx.EndPass();
Gfx.Commit();
}

[UnmanagedCallersOnly]
static void Cleanup()
{
Audio.Shutdown();
Gfx.Shutdown();
}

static class State
{
public static Gfx.PassAction PassAction;
public static int EvenOdd;
public static readonly float[] Samples = new float[32];
public static int SamplePos;
}
152 changes: 152 additions & 0 deletions samples/Sokol/triangle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System;
using System.Runtime.InteropServices;

using Sokol;

App.Run(new() {
InitCb = &Init,
FrameCb = &Frame,
CleanupCb = &Cleanup,
Width = 640,
Height = 480,
GlForceGles2 = true,
WindowTitle = "Triangle (sokol-app)",
Icon = { SokolDefault = true },
});

[UnmanagedCallersOnly]
static void Init()
{
Gfx.Setup(new()
{
Context = App.Context(),
});

/* a vertex buffer with 3 vertices */
ReadOnlySpan<float> vertices = stackalloc float[] {
// positions // colors
0.0f, 0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f,
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f
};

State.Bindings.VertexBuffers[0] = Gfx.MakeBuffer(
vertices,
"triangle-vertices");

Gfx.Shader shd = Gfx.MakeShader(GetShaderDesc());
Gfx.PipelineDesc pipelineDesc = new()
{
Shader = shd,
Label = "triangle-pipeline",
};
pipelineDesc.Layout.Attrs[0].Format = Gfx.VertexFormat.Float3;
pipelineDesc.Layout.Attrs[1].Format = Gfx.VertexFormat.Float4;
State.Pipeline = Gfx.MakePipeline(pipelineDesc);
}

[UnmanagedCallersOnly]
static void Frame()
{
Gfx.BeginDefaultPass(default, App.Width(), App.Height());
Gfx.ApplyPipeline(State.Pipeline);
Gfx.ApplyBindings(State.Bindings);
Gfx.Draw(0, 3, 1);
Gfx.EndPass();
Gfx.Commit();
}

[UnmanagedCallersOnly]
static void Cleanup()
{
Gfx.Shutdown();
}

// build a backend-specific ShaderDesc struct
// NOTE: the other samples are using shader-cross-compilation via the
// sokol-shdc tool, but this sample uses a manual shader setup to
// demonstrate how it works without a shader-cross-compilation tool
//
static Gfx.ShaderDesc GetShaderDesc()
{
Gfx.ShaderDesc desc = default;
switch (Gfx.QueryBackend())
{
case Gfx.Backend.D3d11:
desc.Attrs[0].SemName = "POS";
desc.Attrs[1].SemName = "COLOR";
desc.Vs.Source = @"
struct vs_in {
float4 pos: POS;
float4 color: COLOR;
};
struct vs_out {
float4 color: COLOR0;
float4 pos: SV_Position;
};
vs_out main(vs_in inp) {
vs_out outp;
outp.pos = inp.pos;
outp.color = inp.color;
return outp;
}";
desc.Fs.Source = @"
float4 main(float4 color: COLOR0): SV_Target0 {
return color;
}";
break;
case Gfx.Backend.Glcore33:
desc.Attrs[0].Name = "position";
desc.Attrs[1].Name = "color0";
desc.Vs.Source = @"
#version 330
in vec4 position;
in vec4 color0;
out vec4 color;
void main() {
gl_Position = position;
color = color0;
}";

desc.Fs.Source = @"
#version 330
in vec4 color;
out vec4 frag_color;
void main() {
frag_color = color;
}";
break;
case Gfx.Backend.MetalMacos:
desc.Vs.Source = @"
#include <metal_stdlib>
using namespace metal;
struct vs_in {
float4 position [[attribute(0)]];
float4 color [[attribute(1)]];
};
struct vs_out {
float4 position [[position]];
float4 color;
};
vertex vs_out _main(vs_in inp [[stage_in]]) {
vs_out outp;
outp.position = inp.position;
outp.color = inp.color;
return outp;
}";
desc.Fs.Source = @"
#include <metal_stdlib>
using namespace metal;
fragment float4 _main(float4 color [[stage_in]]) {
return color;
};";
break;
}
return desc;
}

static class State
{
public static Gfx.Pipeline Pipeline;
public static Gfx.Bindings Bindings;
}

0 comments on commit 14804c7

Please sign in to comment.