Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion assets/Shaders/rectangle.frag
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
#version 150 core
in vec2 textureCoord;
in vec2 fragOffset;
uniform vec2 uAlphaTest;
uniform bool uRectangleHasColour;
uniform vec4 uColor;
uniform sampler2D uTexture;
uniform vec2 uSize;
uniform float uCornerRadius;
out vec4 fragColor;

float roundSDF(vec2 p, vec2 b, float r)
{
vec2 q = abs(p) - b + r;
return length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - r;
}

void main(void)
{
vec4 textureColour = texture(uTexture, textureCoord);

vec4 finalColor = textureColour * uColor;

if (uCornerRadius > 0.0)
{
vec2 halfSize = uSize * 0.5;
vec2 pos = (fragOffset - 0.5) * uSize;
float dist = roundSDF(pos, halfSize, uCornerRadius);

float alpha = 1.0 - smoothstep(-0.5, 0.5, dist);
if (alpha <= 0.0)
{
discard;
}
finalColor.a *= alpha;
}

/*
* NOTES:
* Unused alpha functions must not be added to the shader
Expand Down
48 changes: 16 additions & 32 deletions assets/Shaders/rectangle.vert
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,24 @@ uniform vec2 uPoint;
uniform vec2 uSize;
uniform vec2 uCoordinates;
out vec2 textureCoord;
vec4 viewPos = vec4(0,0,0,0);
out vec2 fragOffset;

// Offset lookup table to map gl_VertexID to quad corners without branching
const vec2 offsets[6] = vec2[](
vec2(0.0, 0.0), // Top-left
vec2(1.0, 0.0), // Top-right
vec2(1.0, 1.0), // Bottom-right
vec2(0.0, 0.0), // Top-left (second triangle)
vec2(0.0, 1.0), // Bottom-left
vec2(1.0, 1.0) // Bottom-right
);

void main()
{
if(gl_VertexID == 0)
{
viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y, 0), 1.0);
textureCoord = vec2(0,0);
}
else if (gl_VertexID == 1)
{
viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y, 0), 1.0);
textureCoord = vec2(uCoordinates.x,0);
}
else if (gl_VertexID == 2)
{
viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y + uSize.y, 0), 1.0);
textureCoord = uCoordinates;
}
else if (gl_VertexID == 3)
{
viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y, 0), 1.0);
textureCoord = vec2(0,0);
}
else if (gl_VertexID == 4)
{
viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x, uPoint.y + uSize.y, 0), 1.0);
textureCoord = vec2(0, uCoordinates.y);
}
else if (gl_VertexID == 5)
{
viewPos = uCurrentModelViewMatrix * vec4(vec3(uPoint.x + uSize.x, uPoint.y + uSize.y, 0), 1.0);
textureCoord = uCoordinates;
}

// Calculate vertex position and texture coordinates based on current vertex ID offsets
vec2 offset = offsets[gl_VertexID];
vec4 viewPos = uCurrentModelViewMatrix * vec4(uPoint + offset * uSize, 0.0, 1.0);
textureCoord = offset * uCoordinates;
fragOffset = offset;
gl_Position = uCurrentProjectionMatrix * viewPos;
}
27 changes: 26 additions & 1 deletion source/LibRender2/BaseRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
using OpenBveApi.FileSystem;
using OpenBveApi.Hosts;
using OpenBveApi.Interface;
using OpenBveApi.Graphics;
using OpenBveApi.Math;
using OpenBveApi.Objects;
using OpenBveApi.Routes;
Expand All @@ -42,7 +43,7 @@

namespace LibRender2
{
public abstract class BaseRenderer
public abstract class BaseRenderer : OpenBveApi.Graphics.IGLRenderer
{
// constants
protected const float inv255 = 1.0f / 255.0f;
Expand Down Expand Up @@ -1873,5 +1874,29 @@ public void RunInRenderThread(ThreadStart job, int timeout)
Monitor.Wait(job, timeout);
}
}

/// <inheritdoc />
public bool LoadTexture(ref Texture texture, OpenGlTextureWrapMode wrapMode)
{
return currentHost.LoadTexture(ref texture, wrapMode);
}

/// <inheritdoc />
public void DrawRectangle(Texture texture, Vector2 location, Vector2 size, Color128 color, OpenGlTextureWrapMode? wrapMode = null, float cornerRadius = 0f)
{
Rectangle.Draw(texture, location, size, color, null, wrapMode, cornerRadius);
}

/// <inheritdoc />
public void DrawRectangleAlpha(Texture texture, Vector2 location, Vector2 size, Color128 color, Vector2 scale, OpenGlTextureWrapMode? wrapMode = null, float cornerRadius = 0f)
{
Rectangle.DrawAlpha(texture, location, size, color, scale, wrapMode, cornerRadius);
}

/// <inheritdoc />
public void DrawText(string text, Vector2 location, Color128 color)
{
OpenGlString.Draw(Fonts.NormalFont, text, location, TextAlignment.TopLeft, color);
}
}
}
1 change: 1 addition & 0 deletions source/LibRender2/LibRender2.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@
<Compile Include="Primitives\Button.cs" />
<Compile Include="Primitives\Cube.cs" />
<Compile Include="Primitives\GLControl.cs" />
<Compile Include="Primitives\VerticalLayoutGroup.cs" />
<Compile Include="Primitives\Label.cs" />
<Compile Include="Primitives\Particle.cs" />
<Compile Include="Primitives\Picturebox.cs" />
Expand Down
16 changes: 9 additions & 7 deletions source/LibRender2/Primitives/Button.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//Simplified BSD License (BSD-2-Clause)
//Simplified BSD License (BSD-2-Clause)
//
//Copyright (c) 2023, Christopher Lees, The OpenBVE Project
//
Expand Down Expand Up @@ -38,7 +38,7 @@ public string Text
set
{
_text = value;
Size = Font.MeasureString(Text) * 1.5 * Renderer.currentOptions.UserInterfaceScaleFactor;
Size = Font.MeasureString(Text) * 1.5 * baseRenderer.currentOptions.UserInterfaceScaleFactor;
}
}

Expand All @@ -57,9 +57,11 @@ public string Text
/// <summary>The font for the button</summary>
public OpenGlFont Font;

public Button(BaseRenderer renderer, string text) : base(renderer)
private BaseRenderer baseRenderer => Renderer as BaseRenderer;

public Button(IGLRenderer renderer, string text) : base(renderer)
{
Font = Renderer.Fonts.LargeFont;
Font = baseRenderer.Fonts.LargeFont;
Text = text;
Enabled = true;
// default colors to match GLMenu
Expand All @@ -75,12 +77,12 @@ public override void Draw()
{
return;
}
Renderer.Rectangle.Draw(Texture, Location, Size, BackgroundColor);
baseRenderer.Rectangle.Draw(Texture, Location, Size, BackgroundColor, null, null, CornerRadius);
if (CurrentlySelected && Enabled)
{
Renderer.Rectangle.Draw(Texture, Location + Size * 0.1, Size - (Size * 0.2), HighlightColor);
baseRenderer.Rectangle.Draw(Texture, Location + Size * 0.1, Size - (Size * 0.2), HighlightColor, null, null, CornerRadius * 0.8f);
}
Renderer.OpenGlString.Draw(Font, Text, Location + (Size * 0.15), TextAlignment.TopLeft, Enabled ? EnabledTextColor : DisabledTextColor);
baseRenderer.OpenGlString.Draw(Font, Text, Location + (Size * 0.15), TextAlignment.TopLeft, Enabled ? EnabledTextColor : DisabledTextColor);
}

public override void MouseMove(int x, int y)
Expand Down
11 changes: 7 additions & 4 deletions source/LibRender2/Primitives/GLControl.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//Simplified BSD License (BSD-2-Clause)
//Simplified BSD License (BSD-2-Clause)
//
//Copyright (c) 2023, Christopher Lees, The OpenBVE Project
//
Expand All @@ -24,6 +24,7 @@

using System;
using OpenBveApi.Colors;
using OpenBveApi.Graphics;
using OpenBveApi.Math;
using OpenBveApi.Textures;

Expand All @@ -32,8 +33,8 @@ namespace LibRender2.Primitives
/// <summary>An abstract OpenGL based control</summary>
public abstract class GLControl
{
/// <summary>Holds a reference to the base renderer</summary>
internal readonly BaseRenderer Renderer;
/// <summary>Holds a reference to the base renderer interface</summary>
public readonly IGLRenderer Renderer;
/// <summary>The background color for the control</summary>
public Color128 BackgroundColor;
/// <summary>The texture for the control</summary>
Expand All @@ -42,14 +43,16 @@ public abstract class GLControl
public Vector2 Location;
/// <summary>The stored size for the control</summary>
public Vector2 Size;
/// <summary>The corner radius for rounded corners (in pixels)</summary>
public float CornerRadius;
/// <summary>Whether the control is currently selected by the mouse</summary>
public bool CurrentlySelected;
/// <summary>The event handler for the OnClick event</summary>
public EventHandler OnClick;
/// <summary>Whether the control is currently visible</summary>
public bool IsVisible;

protected GLControl(BaseRenderer renderer)
protected GLControl(IGLRenderer renderer)
{
Renderer = renderer;
}
Expand Down
12 changes: 7 additions & 5 deletions source/LibRender2/Primitives/Label.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//Simplified BSD License (BSD-2-Clause)
//Simplified BSD License (BSD-2-Clause)
//
//Copyright (c) 2022, Christopher Lees, The OpenBVE Project
//
Expand Down Expand Up @@ -37,10 +37,12 @@ public class Label : GLControl
/// <summary>The font for the label</summary>
public OpenGlFont Font;

public Label(BaseRenderer renderer, string text) : base(renderer)
private BaseRenderer baseRenderer => Renderer as BaseRenderer;

public Label(IGLRenderer renderer, string text) : base(renderer)
{
Text = text;
Font = Renderer.Fonts.LargeFont;
Font = baseRenderer.Fonts.LargeFont;
Size = Font.MeasureString(Text) * 1.5;
// default colors to match GLMenu
BackgroundColor = Color128.Black;
Expand All @@ -49,8 +51,8 @@ public Label(BaseRenderer renderer, string text) : base(renderer)

public override void Draw()
{
Renderer.Rectangle.Draw(Texture, Location, Size, BackgroundColor);
Renderer.OpenGlString.Draw(Font, Text, Location + (Size * 0.15), TextAlignment.TopLeft, TextColor);
baseRenderer.Rectangle.Draw(Texture, Location, Size, BackgroundColor, null, null, CornerRadius);
baseRenderer.OpenGlString.Draw(Font, Text, Location + (Size * 0.15), TextAlignment.TopLeft, TextColor);
}
}
}
19 changes: 10 additions & 9 deletions source/LibRender2/Primitives/Picturebox.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using OpenBveApi.Colors;
using OpenBveApi.Graphics;
using OpenBveApi.Math;
using OpenBveApi.Textures;
using OpenTK.Graphics.OpenGL;
Expand All @@ -13,14 +14,14 @@ public class Picturebox : GLControl
private bool flipX;
private bool flipY;

public Picturebox(BaseRenderer renderer) : base(renderer)
public Picturebox(IGLRenderer renderer) : base(renderer)
{
SizeMode = ImageSizeMode.Zoom;
}

public override void Draw()
{
if (!Renderer.currentHost.LoadTexture(ref Texture, OpenGlTextureWrapMode.ClampClamp))
if (!Renderer.LoadTexture(ref Texture, OpenGlTextureWrapMode.ClampClamp))
{
return;
}
Expand All @@ -31,7 +32,7 @@ public override void Draw()
{
case ImageSizeMode.Normal:
//Draw box containing backing color first
Renderer.Rectangle.Draw(Texture, Location, Size, BackgroundColor);
Renderer.DrawRectangle(Texture, Location, Size, BackgroundColor);
//Calculate the new size
newSize = Texture.Size;
if (newSize.X > Size.X)
Expand All @@ -44,11 +45,11 @@ public override void Draw()
newSize.Y = Size.Y;
}
//Two-pass draw the texture in appropriate place
Renderer.Rectangle.DrawAlpha(Texture, Location, newSize, Color128.White, new Vector2(newSize / Size));
Renderer.DrawRectangleAlpha(Texture, Location, newSize, Color128.White, new Vector2(newSize / Size));
break;
case ImageSizeMode.Center:
//Draw box containing backing color first
Renderer.Rectangle.Draw(Texture, Location, Size, BackgroundColor);
Renderer.DrawRectangle(Texture, Location, Size, BackgroundColor);
//Calculate the new size
newSize = Texture.Size;
if (newSize.X > Size.X)
Expand All @@ -61,15 +62,15 @@ public override void Draw()
newSize.Y = Size.Y;
}
//Two-pass draw the texture in appropriate place
Renderer.Rectangle.DrawAlpha(Texture, Location + new Vector2(newSize - Size) / 2, newSize, Color128.White, new Vector2(newSize / Size));
Renderer.DrawRectangleAlpha(Texture, Location + new Vector2(newSize - Size) / 2, newSize, Color128.White, new Vector2(newSize / Size));
break;
case ImageSizeMode.Stretch:
//No need to draw a backing color box as texture covers the whole thing
Renderer.Rectangle.Draw(Texture, Location, Size, BackgroundColor);
Renderer.DrawRectangle(Texture, Location, Size, BackgroundColor);
break;
case ImageSizeMode.Zoom:
//Draw box containing backing color first
Renderer.Rectangle.Draw(null, Location, Size, BackgroundColor);
Renderer.DrawRectangle(null, Location, Size, BackgroundColor);
//Calculate the new size
Vector2 ratio = Size / Texture.Size;
double newRatio = ratio.X < ratio.Y ? ratio.X : ratio.Y;
Expand All @@ -84,7 +85,7 @@ public override void Draw()
{
wrapMode = wrapMode == OpenGlTextureWrapMode.RepeatClamp ? OpenGlTextureWrapMode.RepeatRepeat : OpenGlTextureWrapMode.ClampRepeat;
}
Renderer.Rectangle.DrawAlpha(Texture, new Vector2(Location.X + (Size.X - newSize.X) / 2,Location.Y + (Size.Y - newSize.Y) / 2), newSize, Color128.White, new Vector2(flipX ? -1 : 1,flipY ? -1 : 1), wrapMode);
Renderer.DrawRectangleAlpha(Texture, new Vector2(Location.X + (Size.X - newSize.X) / 2,Location.Y + (Size.Y - newSize.Y) / 2), newSize, Color128.White, new Vector2(flipX ? -1 : 1,flipY ? -1 : 1), wrapMode);
break;
}
}
Expand Down
Loading