Skip to content

Commit 0b90414

Browse files
committed
shader bug fixes and version bump
1 parent 3b31f8d commit 0b90414

11 files changed

Lines changed: 246 additions & 40 deletions

File tree

Directory.build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project>
22
<PropertyGroup>
33
<Deterministic>true</Deterministic>
4-
<Version>0.3.0-alpha.6</Version>
4+
<Version>0.3.0-alpha.7</Version>
55
<TargetFramework>net8.0</TargetFramework>
66
<ImplicitUsings>disable</ImplicitUsings>
77
<Nullable>enable</Nullable>
File renamed without changes.

examples/CanvasShaders/Program.cs

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
using System.Numerics;
77
using static SimulationFramework.Drawing.Shaders.ShaderIntrinsics;
88
using SimulationFramework.Drawing.Shaders.Compiler;
9+
using SimulationFramework.OpenGL;
910

11+
GLGraphics.ForceCompatability = true;
1012
Start<Program>();
1113

1214
partial class Program : Simulation
@@ -23,7 +25,7 @@ public override void OnRender(ICanvas canvas)
2325
shader.width = canvas.Width;
2426
shader.height = canvas.Height;
2527
shader.mousePosition = Vector2.Lerp(shader.mousePosition, targetPos, 1f - MathF.Pow(0.01f, Time.DeltaTime));
26-
targetPos = Mouse.Position;
28+
// targetPos = Mouse.Position - new Vector2(canvas.Width, canvas.Height);
2729
if (Keyboard.IsKeyDown(Key.Space))
2830
{
2931
shader.time += Time.DeltaTime * 100;
@@ -35,6 +37,7 @@ public override void OnRender(ICanvas canvas)
3537
ShaderCompiler.DumpShaders = true;
3638
canvas.Clear(Color.FromHSV(0, 0, .15f));
3739
canvas.Fill(shader);
40+
canvas.Fill(new illumshad());
3841
canvas.DrawRect(0, 0, canvas.Width, canvas.Height);
3942
}
4043
}
@@ -46,13 +49,18 @@ class IterationsInversions2 : CanvasShader
4649
public float time;
4750
public Vector2 mousePosition;
4851

52+
int[] i;
53+
light[] ls = [];
54+
4955
public Vector3 Shape(Vector2 uv)
5056
{
5157
float time = this.time * 0.05f + 47.0f;
5258

5359
Vector2 z = -System.Numerics.Vector2.One + 2.0f * uv;
5460
z *= 1.5f;
5561

62+
bool b = AsBool(1);
63+
5664
Vector3 col = new Vector3(1.0f);
5765
for (int j = 0; j < 48; j++)
5866
{
@@ -75,8 +83,6 @@ public Vector3 Shape(Vector2 uv)
7583

7684
public override ColorF GetPixelColor(Vector2 position)
7785
{
78-
Vector2 duv = DDX(position);
79-
8086
const int AA = 2;
8187
float e = 1.0f / width;
8288

@@ -140,4 +146,64 @@ public override ColorF GetPixelColor(Vector2 position)
140146
{
141147
return myTexture.Sample(position);
142148
}
149+
}
150+
public struct light
151+
{
152+
public Vector2 pos;
153+
public float rad;
154+
public float lum;
155+
public ColorF col;
156+
public float rnd;
157+
public bool clmp;
158+
}
159+
160+
public struct tri
161+
{
162+
public Vector2 p1, p2, p3;
163+
}
164+
165+
public class illumshad : CanvasShader
166+
{
167+
public light[] l = [];
168+
public tri[] objs = [];
169+
170+
public override ColorF GetPixelColor(Vector2 pos)
171+
{
172+
ColorF col = ColorF.Black;
173+
Vector3 _col = MakeVector3(0, 0, 0);
174+
175+
for (int i = 0; i < l.Length; i++)
176+
{
177+
float dist = Distance(pos, l[i].pos);
178+
179+
if(dist <= l[i].rad) {
180+
float r = Max((l[i].lum * l[i].col.R + (l[i].lum - 1)) * (1 - dist / l[i].rad), 0);
181+
float g = Max((l[i].lum * l[i].col.G + (l[i].lum - 1)) * (1 - dist / l[i].rad), 0);
182+
float b = Max((l[i].lum * l[i].col.B + (l[i].lum - 1)) * (1 - dist / l[i].rad), 0);
183+
184+
if (l[i].clmp) {
185+
r = Round(r / l[i].rnd) * l[i].rnd;
186+
g = Round(g / (l[i].rnd * .5f)) * (l[i].rnd * .5f);
187+
b = Round(b / l[i].rnd) * l[i].rnd;
188+
}
189+
190+
_col += MakeVector3(r, g, b);
191+
}
192+
}
193+
194+
col = new ColorF(_col.X, _col.Y, _col.Z);
195+
196+
return col;
197+
}
198+
199+
public bool intri(Vector2 p, Vector2 p1, Vector2 p2, Vector2 p3)
200+
{
201+
float areaOrig = Abs((p2.X - p1.X) * (p3.Y - p1.Y) - (p3.X - p1.X) * (p2.Y - p1.Y));
202+
203+
float area1 = Abs((p1.X - p.X) * (p2.Y - p.Y) - (p2.X - p.X) * (p1.Y - p.Y));
204+
float area2 = Abs((p2.X - p.X) * (p3.Y - p.Y) - (p3.X - p.X) * (p2.Y - p.Y));
205+
float area3 = Abs((p3.X - p.X) * (p1.Y - p.Y) - (p1.X - p.X) * (p3.Y - p.Y));
206+
207+
return (area1 + area2 + area3) == areaOrig;
208+
}
143209
}

src/SimulationFramework.OpenGL/GLCanvas.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public void DrawArc(Rectangle bounds, float begin, float end, bool includeCenter
116116

117117
public void DrawLine(Vector2 p1, Vector2 p2)
118118
{
119-
CurrentWriter.PushLine(CurrentStream, p1, p2);
119+
graphics.writers.GetWriter(in State, true).PushLine(CurrentStream, p1, p2);
120120
var effect = graphics.effects.GetEffectFromCanvasState(in State);
121121
AddRenderCommand(CreateChunk(CurrentStream, CurrentWriter.UsesTriangles), effect);
122122
}
@@ -499,7 +499,7 @@ public void AddRenderCommand(GeometryChunk chunk, GeometryEffect effect)
499499
if (command.HasSameState(lastCommand))
500500
{
501501
GeometryChunk lastChunk = lastCommand.chunk;
502-
if (chunk.vertexBuffer == lastChunk.vertexBuffer)
502+
if (chunk.vertexBuffer == lastChunk.vertexBuffer && chunk.triangles == lastChunk.triangles)
503503
{
504504
if (lastChunk.offset + lastChunk.count == chunk.offset)
505505
{

src/SimulationFramework.OpenGL/Geometry/TextureProgram.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ void main()
3030
3131
void main()
3232
{
33-
FragColor = tint * texture(textureSampler, tex);
33+
vec4 color = tint * texture(textureSampler, tex);
34+
if (color.a < 0.001) {
35+
discard;
36+
}
37+
FragColor = color;
3438
}
3539
";
3640
public TextureProgram(string shaderVersion) : base(shaderVersion, vert, frag)

src/SimulationFramework.OpenGL/ShaderProgram.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using SimulationFramework.Drawing.Shaders.Compiler;
1+
using SimulationFramework.Drawing.Shaders;
2+
using SimulationFramework.Drawing.Shaders.Compiler;
23
using System;
34
using System.Linq;
45
using System.Runtime.InteropServices;
@@ -20,7 +21,7 @@ public unsafe ShaderProgram(string shaderVersion, string vsSource, string fsSour
2021
Console.WriteLine(new string('=', 20) + " CANVAS SHADER " + new string('=', 20));
2122
Console.WriteLine(string.Join("\n", fsSource.Split('\n').Select((s, i) => $"{i + 1,-3:d}|{s}")));
2223
}
23-
24+
2425
var vs = glCreateShader(GL_VERTEX_SHADER);
2526
var fs = glCreateShader(GL_FRAGMENT_SHADER);
2627
ShaderSource(vs, shaderVersion + "\n" + vsSource);

src/SimulationFramework.OpenGL/Shaders/GLSLExpressionEmitter.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,22 @@ public override ShaderExpression VisitShaderIntrinsicCall(ShaderIntrinsicCall ex
313313
return expression;
314314
}
315315

316+
if (expression.Intrinsic.Name == nameof(ShaderIntrinsics.AsBool))
317+
{
318+
writer.Write("bool(");
319+
expression.Arguments[0].Accept(this);
320+
writer.Write(")");
321+
return expression;
322+
}
323+
324+
if (expression.Intrinsic.Name == nameof(ShaderIntrinsics.AsInt))
325+
{
326+
writer.Write("int(");
327+
expression.Arguments[0].Accept(this);
328+
writer.Write(")");
329+
return expression;
330+
}
331+
316332
if (expression.Intrinsic.Name == nameof(ShaderIntrinsics.Transform))
317333
{
318334
writer.Write('(');

src/SimulationFramework.OpenGL/Shaders/GLSLShaderEmitter.cs

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -468,18 +468,40 @@ private void EmitBufferLoadFunctions(GLGraphics graphics)
468468

469469
ReadOnlySpan<char> swizzle = "xyzw".AsSpan(field.channelOffset, field.channelCount);
470470

471-
if (field.Variable.Type.GetPrimitiveKind() is
471+
string baseName = "result";
472+
473+
if (field.NestedName.Length > 0)
474+
{
475+
baseName += ".";
476+
}
477+
478+
if (field.primitiveKind is
472479
ShaderPrimitiveKind.Float or
473480
ShaderPrimitiveKind.Float2 or
474481
ShaderPrimitiveKind.Float3 or
475482
ShaderPrimitiveKind.Float4
476483
)
477484
{
478-
writer.WriteLine($"result.{field.NestedName} = uintBitsToFloat(value{elementOffset}.{swizzle});");
485+
writer.WriteLine($"{baseName}{field.NestedName} = uintBitsToFloat(value{elementOffset}.{swizzle});");
486+
}
487+
else if(field.primitiveKind is
488+
ShaderPrimitiveKind.Int or
489+
ShaderPrimitiveKind.Int2 or
490+
ShaderPrimitiveKind.Int3 or
491+
ShaderPrimitiveKind.Int4
492+
)
493+
{
494+
string type = swizzle.Length > 1 ? $"ivec{swizzle.Length}" : "int";
495+
writer.WriteLine($"{baseName}{field.NestedName} = {type}(value{elementOffset}.{swizzle});");
479496
}
480-
else
497+
else if (field.primitiveKind is ShaderPrimitiveKind.Bool)
481498
{
482-
writer.WriteLine($"result.{field.NestedName} = uintBitsToFloat(value{elementOffset}.{swizzle});");
499+
writer.WriteLine($"{baseName}{field.NestedName} = value{elementOffset}.{swizzle} != 0;");
500+
}
501+
else // uint
502+
{
503+
string type = swizzle.Length > 1 ? $"uvec{swizzle.Length}" : "uint";
504+
writer.WriteLine($"{baseName}{field.NestedName} = {type}(value{elementOffset}.{swizzle});");
483505
}
484506

485507
fieldIndex++;
@@ -635,6 +657,8 @@ private void EmitVariable(ShaderVariable variable)
635657

636658
writer.Indent--;
637659
writer.WriteLine("};");
660+
661+
nextBufferSlot++;
638662
}
639663
else
640664
{

src/SimulationFramework.OpenGL/Shaders/SSBOShaderArray.cs

Lines changed: 61 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
using SimulationFramework.Drawing.Shaders.Compiler;
1+
using SimulationFramework.Drawing;
2+
using SimulationFramework.Drawing.Shaders.Compiler;
23
using System;
34
using System.Collections.Generic;
45
using System.Diagnostics;
56
using System.Text;
7+
using System.Xml.Linq;
68

79
namespace SimulationFramework.OpenGL;
810

@@ -27,26 +29,8 @@ protected override Field[] CreateFields(uint program, ShaderVariable uniform, ou
2729

2830
ShaderType elementType = (uniform.Type as ShaderArrayType)!.ElementType;
2931

30-
// for some reason on primitive arrays GL_TOP_LEVEL_ARRAY_STRIDE returns
31-
// 0 while on arrays of structs GL_ARRAY_STRIDE returns 0
32-
uint prop;
33-
if (elementType.GetPrimitiveKind() != null)
34-
{
35-
prop = GL_ARRAY_STRIDE;
36-
}
37-
else
38-
{
39-
prop = GL_TOP_LEVEL_ARRAY_STRIDE;
40-
}
41-
42-
fixed (int* stridePtr = &bufferStride)
43-
{
44-
glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, 0, 1, &prop, 1, null, stridePtr);
45-
}
46-
47-
Debug.Assert(bufferStride != 0);
48-
4932
arrayStride = ShaderType.CalculateTypeSize(elementType);
33+
bufferStride = QueryBufferStride(program, uniform);
5034

5135
int arrayOffset = 0;
5236
CreateFieldsHelper((uniform.Type as ShaderArrayType)!.ElementType, uniform.Name.value + "[0]");
@@ -65,7 +49,7 @@ void CreateFieldsHelper(ShaderType type, string name)
6549
else if (type.GetPrimitiveKind() != null)
6650
{
6751
uint index;
68-
fixed (byte* namePtr = Encoding.UTF8.GetBytes(name))
52+
fixed (byte* namePtr = Encoding.UTF8.GetBytes(name))
6953
{
7054
index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, namePtr);
7155
}
@@ -90,6 +74,55 @@ void CreateFieldsHelper(ShaderType type, string name)
9074
}
9175
}
9276

77+
private int QueryBufferStride(uint program, ShaderVariable uniform)
78+
{
79+
int bufferStride = 0;
80+
81+
// for some reason on primitive arrays GL_TOP_LEVEL_ARRAY_STRIDE returns
82+
// 0 while on arrays of structs GL_ARRAY_STRIDE returns 0
83+
84+
uint strideProperty = GL_ARRAY_STRIDE;
85+
var firstFieldName = uniform.Name.ToString();
86+
var firstFieldType = uniform.Type;
87+
while (true)
88+
{
89+
if (firstFieldType is ShaderArrayType arrayType)
90+
{
91+
firstFieldType = arrayType.ElementType;
92+
firstFieldName += "[0]";
93+
}
94+
else if (firstFieldType is ShaderStructureType structType)
95+
{
96+
firstFieldType = structType.structure.fields[0].Type;
97+
firstFieldName += "." + structType.structure.fields[0].Name.ToString();
98+
strideProperty = GL_TOP_LEVEL_ARRAY_STRIDE;
99+
}
100+
else if (firstFieldType.GetPrimitiveKind() is ShaderPrimitiveKind primitiveKind)
101+
{
102+
break;
103+
}
104+
else
105+
{
106+
throw new();
107+
}
108+
}
109+
110+
uint index;
111+
fixed (byte* namePtr = Encoding.UTF8.GetBytes(firstFieldName))
112+
{
113+
index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, namePtr);
114+
115+
}
116+
117+
if (index == uint.MaxValue)
118+
{
119+
throw new();
120+
}
121+
122+
glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, 1, &strideProperty, 1, null, &bufferStride);
123+
return bufferStride;
124+
}
125+
93126
public uint GetBuffer()
94127
{
95128
return buffer;
@@ -124,10 +157,13 @@ public override void WriteData(void* data, int count)
124157
{
125158
SetBufferSize(count * bufferStride);
126159

127-
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
128-
void* mappedBuf = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, size, GL_MAP_WRITE_BIT);
129-
CopyArrayToBuffer(data, mappedBuf, count);
130-
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
160+
if (count != 0)
161+
{
162+
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer);
163+
void* mappedBuf = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, size, GL_MAP_WRITE_BIT);
164+
CopyArrayToBuffer(data, mappedBuf, count);
165+
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
166+
}
131167
}
132168

133169
public override void ReadData(void* outData, int count)

0 commit comments

Comments
 (0)