Skip to content

Commit 0cbcf42

Browse files
fix clipping
1 parent 165d950 commit 0cbcf42

File tree

7 files changed

+77
-42
lines changed

7 files changed

+77
-42
lines changed

Flamui/Drawing/GlCanvas.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -187,21 +187,33 @@ public void ClipRect(float x, float y, float width, float height)
187187
ClipRoundedRect(x, y, width, height, 0);
188188
}
189189

190+
public void ClearClip()
191+
{
192+
Flush();
193+
194+
_renderer.Gl.StencilMask(0xFF);
195+
_renderer.Gl.ClearStencil(1);
196+
_renderer.Gl.Clear(ClearBufferMask.StencilBufferBit);
197+
_renderer.Gl.StencilMask(0x00);
198+
199+
}
200+
190201
public void ClipRoundedRect(float x, float y, float width, float height, float radius)
191202
{
192203
//magic code that I don't really understand...
193204

194-
_renderer.Gl.Enable(EnableCap.StencilTest);
195-
196-
_renderer.Gl.Clear(ClearBufferMask.StencilBufferBit);
197-
_renderer.Gl.StencilMask(0x00); //disables writing to the stencil buffer
205+
// _renderer.Gl.StencilMask(0x00); //disables writing to the stencil buffer
198206

199207
//draw the vertex buffer up to the clip
200208
Flush();
201209

210+
_renderer.Gl.StencilMask(0xFF); //enables writing to the stencil buffer
211+
212+
_renderer.Gl.ClearStencil(0);
213+
_renderer.Gl.Clear(ClearBufferMask.StencilBufferBit);
214+
202215
//explain: glStencilFunc(GL_EQUAL, 1, 0xFF) is tells OpenGL that whenever the stencil value of a fragment is equal (GL_EQUAL) to the reference value 1, the fragment passes the test and is drawn, otherwise discarded.
203216
_renderer.Gl.StencilFunc(StencilFunction.Always,1, 0xFF); //compares stencil buffer content to ref, to determine if the pixel should have an effect
204-
_renderer.Gl.StencilMask(0xFF); //enables writing to the stencil buffer
205217
_renderer.Gl.StencilOp(StencilOp.Keep, StencilOp.Keep, StencilOp.Replace); //how to actually update the stencil buffer
206218

207219
_renderer.Gl.ColorMask(false, false, false, false);
@@ -228,6 +240,8 @@ public void Start()
228240
_renderer.Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit | ClearBufferMask.StencilBufferBit);
229241
_renderer.Gl.StencilMask(0xFF);
230242
_renderer.Gl.StencilFunc(StencilFunction.Always, 1, 0xFF);
243+
244+
231245
}
232246

233247
public void Flush()

Flamui/Drawing/Renderer.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,8 @@ public void Initialize(IWindow window)
135135
}
136136

137137
CheckError();
138+
139+
Gl.Enable(EnableCap.StencilTest);
138140
}
139141

140142
private int[] textureSlotUniformLocations = new int[10];
@@ -241,6 +243,9 @@ private TextureUnit IntToTextureUnit(int i)
241243

242244
public unsafe void DrawMesh(Mesh mesh, bool stencilMode = false)
243245
{
246+
if (mesh.Indices.Length == 0) //empty mesh, noting to do...
247+
return;
248+
244249
using var _ = Systrace.BeginEvent(nameof(DrawMesh));
245250

246251
Gl.BindVertexArray(_vao);
@@ -264,6 +269,8 @@ public unsafe void DrawMesh(Mesh mesh, bool stencilMode = false)
264269
Gl.BufferData(BufferTargetARB.ElementArrayBuffer, mesh.Indices.ReadonlySpan, BufferUsageARB.StaticDraw);
265270
}
266271

272+
//todo, do we need to do this on every DrawMesh call?
273+
267274
const int stride = 3 + 2 + 1 + 4 + 1 + 1; //10 because of 3 vertices + 2 UVs + 1 filltype + 4 color + 1 texturetype + 1 textureId
268275

269276
const uint positionLoc = 0; //aPosition in shader

Flamui/RenderContext.cs

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public RenderContext()
1919
public Arena Arena;
2020
public Dictionary<int, ArenaChunkedList<Command>> CommandBuffers = [];
2121
private Stack<Matrix4X4<float>> MatrixStack = [];
22+
private Stack<Command> ClipStack = [];
2223

2324
public void Reset()
2425
{
@@ -48,16 +49,6 @@ public void AddPath(GlPath path, ColorDefinition color)
4849
Add(cmd);
4950
}
5051

51-
public void AddClipRect(Bounds bounds, float radius = 0)
52-
{
53-
var cmd = new Command();
54-
cmd.Bounds = bounds;
55-
cmd.Radius = radius;
56-
cmd.Type = CommandType.ClipRect;
57-
58-
Add(cmd);
59-
}
60-
6152
public void AddText(UiElement uiElement, Bounds bounds, ArenaString text, ColorDefinition color, ScaledFont scaledFont)
6253
{
6354
var cmd = new Command();
@@ -93,6 +84,34 @@ public void AddVectorGraphics(int vgId, Slice<byte> vgData, Bounds bounds)
9384
Add(cmd);
9485
}
9586

87+
public void PushClip(Bounds bounds, float radius = 0)
88+
{
89+
var cmd = new Command();
90+
cmd.Bounds = bounds;
91+
cmd.Radius = radius;
92+
cmd.Type = CommandType.ClipRect;
93+
94+
ClipStack.Push(cmd);
95+
96+
Add(cmd);
97+
}
98+
99+
public void PopClip()
100+
{
101+
ClipStack.Pop();
102+
103+
if (ClipStack.TryPeek(out var cmd))
104+
{
105+
Add(cmd);
106+
}
107+
else
108+
{
109+
cmd = new Command();
110+
cmd.Type = CommandType.ClearClip;
111+
Add(cmd);
112+
}
113+
}
114+
96115
/// <summary>
97116
/// Multiplies the current matrix with the new matrix
98117
/// </summary>
@@ -196,10 +215,13 @@ public void PrintCommands()
196215
Console.WriteLine($"Matrix: {command.Matrix}");
197216
break;
198217
case CommandType.TinyVG:
199-
Console.WriteLine("VG");
218+
Console.WriteLine("VG:");
200219
break;
201220
case CommandType.Picture:
202-
Console.WriteLine("Picture");
221+
Console.WriteLine("Picture:");
222+
break;
223+
case CommandType.ClearClip:
224+
Console.WriteLine("ClearClip:");
203225
break;
204226
default:
205227
throw new ArgumentOutOfRangeException(command.Type.ToString());
@@ -251,6 +273,9 @@ public void Rerender(Renderer renderer)
251273
case CommandType.TinyVG:
252274
canvas.DrawTinyVG(command.VGId, command.VGData, command.Bounds);
253275
break;
276+
case CommandType.ClearClip:
277+
canvas.ClearClip();
278+
break;
254279
default:
255280
throw new ArgumentOutOfRangeException(command.Type.ToString());
256281
}

Flamui/Renderable.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ public enum CommandType : byte
128128
Matrix,
129129
Path,
130130
Picture,
131-
TinyVG
131+
TinyVG,
132+
ClearClip
132133
}
133134

134135
public struct Command : IEquatable<Command>

Flamui/UiElements/FlexContainerRenderer.cs

Lines changed: 6 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ public static void Render(RenderContext renderContext, FlexContainer flexContain
8080
renderContext.AddRect(flexContainer.Rect.ToBounds(offset), flexContainer, color, flexContainer.Info.Radius);
8181
}
8282

83-
ClipContent(renderContext, flexContainer, flexContainer.Info, offset);
83+
84+
if (NeedsClip(flexContainer.Info))
85+
{
86+
renderContext.PushClip(flexContainer.Rect.ToBounds(offset), flexContainer.Info.Radius);
87+
}
8488

8589
if (flexContainer.Info.ScrollConfigY.CanScroll || flexContainer.Info.ScrollConfigX.CanScroll)
8690
{
@@ -107,8 +111,7 @@ public static void Render(RenderContext renderContext, FlexContainer flexContain
107111

108112
if (NeedsClip(flexContainer.Info))
109113
{
110-
// renderContext.AddClipRect(new Bounds(new Vector2(-1000, -1000), new Vector2(2000, 2000)), 1);
111-
// renderContext.Add(new Restore());
114+
renderContext.PopClip();
112115
}
113116

114117
if (flexContainer.Info.Rotation != 0)
@@ -125,22 +128,6 @@ public static void Render(RenderContext renderContext, FlexContainer flexContain
125128
}
126129
}
127130

128-
private static void ClipContent(RenderContext renderContext, UiElement uiElement, FlexContainerInfo Info, Point offset)
129-
{
130-
if (NeedsClip(Info))
131-
{
132-
// renderContext.Add(new Save());
133-
134-
renderContext.AddClipRect(uiElement.Rect.ToBounds(offset), Info.Radius);
135-
// renderContext.Add(new RectClip
136-
// {
137-
// Bounds = ,
138-
// Radius = Info.Radius,
139-
// ClipOperation = SKClipOperation.Intersect
140-
// });
141-
}
142-
}
143-
144131
private static bool NeedsClip(FlexContainerInfo Info)
145132
{
146133
return Info.ScrollConfigY.CanScroll || Info.ScrollConfigX.CanScroll || Info.IsClipped;

Flamui/UiWindow.cs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,6 @@ private void RenderToCanvas()
302302
{
303303
// using var _ = Systrace.BeginEvent("RenderToCanvas");
304304

305-
306-
//RenderContext.PrintCommands();//todo remove
307-
//todo check if something has actually changed
308-
309305
if (!RenderContextAreSame(RenderContext, LastRenderContext))
310306
{
311307
RenderContext.PrintCommands();

Sample.LayoutTest/Program.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
app.Run();
1616

17-
public class LayoutTest(FlamuiApp app) : FlamuiComponent
17+
public class LayoutTest : FlamuiComponent
1818
{
1919
private ColorDefinition cc = new(43, 45, 48);
2020
private ColorDefinition c2 = new(30, 31, 34);
@@ -60,5 +60,10 @@ public override void Build(Ui ui)
6060
}
6161
}
6262
}
63+
64+
using (ui.Div().Color(C.Green7))
65+
{
66+
67+
}
6368
}
6469
}

0 commit comments

Comments
 (0)