Skip to content

Commit 9bcfe33

Browse files
OpenGL on MacOS is a reality 😎
1 parent c19ffea commit 9bcfe33

File tree

15 files changed

+571
-69
lines changed

15 files changed

+571
-69
lines changed

.scripts/Setup.ps1

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ $projectsList = @(
7373
Depends = @("Arcane")
7474
},
7575
@{
76-
Module = "Crystal"
76+
Module = "Crystal.Core"
7777
Projects = @(
7878
@{ Folder = "Modules/Crystal"; Name = "CatalystUI.Modules.Crystal.Core" }
7979
)
@@ -86,24 +86,32 @@ $projectsList = @(
8686
@{ Folder = "Modules/Crystal"; Name = "CatalystUI.Modules.Crystal.Glfw3" }
8787
)
8888
PromptIgnore = $false
89-
Depends = @("Crystal")
89+
Depends = @("Crystal.Core")
9090
},
9191
@{
9292
Module = "Crystal.Sdl2"
9393
Projects = @(
9494
@{ Folder = "Modules/Crystal"; Name = "CatalystUI.Modules.Crystal.Sdl2" }
9595
)
9696
PromptIgnore = $false
97-
Depends = @("Crystal")
97+
Depends = @("Crystal.Core")
9898
},
9999
@{
100100
Module = "Crystal.OpenGL"
101101
Projects = @(
102102
@{ Folder = "Modules/Crystal"; Name = "CatalystUI.Modules.Crystal.OpenGL" }
103103
)
104104
PromptIgnore = $false
105-
Depends = @("Crystal")
105+
Depends = @("Crystal.Core")
106106
},
107+
@{
108+
Module = "Crystal.Glfw3OpenGLSurfaceConnector"
109+
Projects = @(
110+
@{ Folder = "Modules/Crystal"; Name = "CatalystUI.Modules.Crystal.Glfw3OpenGLSurfaceConnector" }
111+
)
112+
PromptIgnore = $false
113+
Depends = @("Crystal.Glfw3", "Crystal.OpenGL")
114+
}
107115
)
108116

109117
# Build prompt options

CatalystUI/CatalystUI.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Modules.Crystal.
4444
EndProject
4545
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Modules.Crystal.OpenGL", "Modules\Crystal\CatalystUI.Modules.Crystal.OpenGL\CatalystUI.Modules.Crystal.OpenGL.csproj", "{9CD307E2-FEDA-4C64-B2EE-00E6E196175C}"
4646
EndProject
47+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CatalystUI.Modules.Crystal.Glfw3OpenGLSurfaceConnector", "Modules\Crystal\CatalystUI.Modules.Crystal.Glfw3OpenGLSurfaceConnector\CatalystUI.Modules.Crystal.Glfw3OpenGLSurfaceConnector.csproj", "{B03716DE-8B0C-4457-B71A-5E0A0D11325D}"
48+
EndProject
4749
Global
4850
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4951
Debug|Any CPU = Debug|Any CPU
@@ -114,6 +116,10 @@ Global
114116
{9CD307E2-FEDA-4C64-B2EE-00E6E196175C}.Debug|Any CPU.Build.0 = Debug|Any CPU
115117
{9CD307E2-FEDA-4C64-B2EE-00E6E196175C}.Release|Any CPU.ActiveCfg = Release|Any CPU
116118
{9CD307E2-FEDA-4C64-B2EE-00E6E196175C}.Release|Any CPU.Build.0 = Release|Any CPU
119+
{B03716DE-8B0C-4457-B71A-5E0A0D11325D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
120+
{B03716DE-8B0C-4457-B71A-5E0A0D11325D}.Debug|Any CPU.Build.0 = Debug|Any CPU
121+
{B03716DE-8B0C-4457-B71A-5E0A0D11325D}.Release|Any CPU.ActiveCfg = Release|Any CPU
122+
{B03716DE-8B0C-4457-B71A-5E0A0D11325D}.Release|Any CPU.Build.0 = Release|Any CPU
117123
EndGlobalSection
118124
GlobalSection(NestedProjects) = preSolution
119125
{68F496AC-9438-40F1-9DF8-97363033D661} = {7EC51871-49A8-4991-BDAF-F43A4E9B8C9D}
@@ -135,5 +141,6 @@ Global
135141
{BC5802D1-4C3E-4FD6-9E3B-9ED82CCB2D18} = {41BEF490-7005-4D10-9958-22D636F9DE38}
136142
{532C59A0-43D2-44E9-B6ED-E88E6B8770F5} = {41BEF490-7005-4D10-9958-22D636F9DE38}
137143
{9CD307E2-FEDA-4C64-B2EE-00E6E196175C} = {41BEF490-7005-4D10-9958-22D636F9DE38}
144+
{B03716DE-8B0C-4457-B71A-5E0A0D11325D} = {41BEF490-7005-4D10-9958-22D636F9DE38}
138145
EndGlobalSection
139146
EndGlobal
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
2+
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GL/@EntryIndexedValue">GL</s:String></wpf:ResourceDictionary>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// -------------------------------------------------------------------------------------------------
2+
// CatalystUI Framework for .NET Core - https://catalystui.org/
3+
// Copyright (c) 2025 CatalystUI LLC. All rights reserved.
4+
//
5+
// This file is part of CatalystUI and is provided as part of an early-access release.
6+
// Unauthorized commercial use, distribution, or modification is strictly prohibited.
7+
//
8+
// This software is not open source and is not publicly licensed.
9+
// For full terms, see the LICENSE and NOTICE files in the project root.
10+
// -------------------------------------------------------------------------------------------------
11+
12+
using Catalyst.Connectors;
13+
14+
namespace Catalyst.Modules.Crystal {
15+
16+
/// <summary>
17+
/// Represents the surface connector for visual or graphical windowing to rendering.
18+
/// </summary>
19+
public interface ISurfaceConnector : ISurfaceConnector<IWindowLayer, IRendererLayer> {
20+
21+
/// <summary>
22+
/// Creates a render target for the specified window.
23+
/// </summary>
24+
/// <param name="window">The window to create the render target for.</param>
25+
/// <returns>The created render target.</returns>
26+
IRenderTarget CreateRenderTarget(IWindow window);
27+
28+
}
29+
30+
}

CatalystUI/Modules/Crystal/CatalystUI.Modules.Crystal.Core/Renderer/IRenderLayer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
// For full terms, see the LICENSE and NOTICE files in the project root.
1010
// -------------------------------------------------------------------------------------------------
1111

12+
13+
1214
// ReSharper disable once CheckNamespace
1315
namespace Catalyst.Modules.Crystal {
1416

CatalystUI/Modules/Crystal/CatalystUI.Modules.Crystal.Core/Renderer/IRenderTarget.cs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
// For full terms, see the LICENSE and NOTICE files in the project root.
1010
// -------------------------------------------------------------------------------------------------
1111

12+
13+
1214
// ReSharper disable once CheckNamespace
1315
namespace Catalyst.Modules.Crystal {
1416

@@ -115,16 +117,24 @@ public interface IRenderTarget {
115117
double SurfaceHeight { get; }
116118

117119
/// <summary>
118-
/// Gets the pixel density of the surface.
120+
/// Gets the PPI (pixels per inch) of the surface.
121+
/// </summary>
122+
/// <value>The PPI of the surface.</value>
123+
/// <seealso cref="IDisplay.PixelsPerInch"/>
124+
double SurfacePpi { get; }
125+
126+
/// <summary>
127+
/// Gets the scaling factor of the surface.
119128
/// </summary>
120-
/// <value>The pixel density of the surface.</value>
121-
double SurfacePixelDensity { get; }
129+
/// <value>The scaling factor of the surface.</value>
130+
/// <seealso cref="IDisplay.ScalingFactor"/>
131+
double SurfaceScalingFactor { get; }
122132

123133
/// <summary>
124-
/// Gets the DPI (dots per inch) of the surface.
134+
/// Gets a value indicating whether the render target is currently visible.
125135
/// </summary>
126-
/// <value>The DPI of the surface.</value>
127-
double SurfaceDpi { get; }
136+
/// <value><see langword="true"/> if the render target is visible; otherwise, <see langword="false"/>.</value>
137+
bool IsVisible { get; }
128138

129139
/// <summary>
130140
/// Gets a value indicating whether the render target is currently enabled.

CatalystUI/Modules/Crystal/CatalystUI.Modules.Crystal.Core/Window/IWindow.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,15 @@ public interface IWindow : IDisposable {
159159
/// </remarks>
160160
event WindowClosingEventHandler? Closing;
161161

162+
/// <summary>
163+
/// Invoked when the window is disposing of its resources.
164+
/// </summary>
165+
/// <remarks>
166+
/// Raised after the window close operation has been
167+
/// confirmed, but before resources have been released.
168+
/// </remarks>
169+
event WindowEventHandler? Disposing;
170+
162171
/// <summary>
163172
/// Invoked when the window has closed and resources have been released.
164173
/// </summary>

CatalystUI/Modules/Crystal/CatalystUI.Modules.Crystal.Glfw3/Window/GlfwWindow.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public unsafe class GlfwWindow : IWindow {
3535
/// The minimum polling rate for the window in milliseconds.
3636
/// </summary>
3737
/// <remarks>
38-
/// Prevents lockups of the main thread when the
38+
/// Prevents lockups of the thread when the
3939
/// window may not be responding.
4040
/// </remarks>
4141
public const ushort MINIMUM_POLL_RATE = 3000;
@@ -82,6 +82,9 @@ public unsafe class GlfwWindow : IWindow {
8282
/// <inheritdoc/>
8383
public event IWindow.WindowClosingEventHandler? Closing;
8484

85+
/// <inheritdoc/>
86+
public event IWindow.WindowEventHandler? Disposing;
87+
8588
/// <inheritdoc/>
8689
public event IWindow.WindowEventHandler? Closed;
8790

@@ -1101,6 +1104,12 @@ protected virtual bool OnClosing() {
11011104
if (result) Glfw3.DebugContext.Log(LogLevel.Debug, "Window closure cancelled by event handler.", prefix: LogId);
11021105
return result;
11031106
}
1107+
1108+
/// <inheritdoc cref="IWindow.Disposing"/>
1109+
protected virtual void OnDisposing() {
1110+
Glfw3.DebugContext.Log(LogLevel.Info, "Window disposing...", prefix: LogId);
1111+
Disposing?.Invoke(this);
1112+
}
11041113

11051114
/// <inheritdoc cref="IWindow.Closed"/>
11061115
protected virtual void OnClosed() {
@@ -1129,6 +1138,9 @@ private void Dispose(bool disposing) {
11291138
try {
11301139
if (_disposed) return;
11311140

1141+
// Disposing
1142+
OnDisposing();
1143+
11321144
// Dispose managed state (managed objects)
11331145
if (disposing) {
11341146
// ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<!-- Project Properties -->
4+
<PropertyGroup>
5+
<!-- Build Properties -->
6+
<RootNamespace>Catalyst.Modules.Crystal.Connectors</RootNamespace>
7+
<PackageId>Catalyst.Modules.Crystal.Glfw3OpenGLSurfaceConnector</PackageId>
8+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
9+
10+
<!-- Metadata -->
11+
<Title>CatalystUI Crystal – Glfw3OpenGLSurfaceConnector</Title>
12+
<VersionPrefix>1.0.0</VersionPrefix>
13+
<VersionSuffix>alpha.1</VersionSuffix>
14+
<Authors>CatalystUI LLC</Authors>
15+
<Description>Glfw3 to OpenGL API for the Crystal subset of modules provided by the CatalystUI library.</Description>
16+
<PackageTags>CatalystUI,Crystal,glfw3,glfw,opengl,gl,ui,gui,graphics,visual,window</PackageTags>
17+
</PropertyGroup>
18+
19+
<!-- NuGet Dependencies -->
20+
<ItemGroup>
21+
<PackageReference Include="Catalyst.Modules.Crystal.Glfw3" Version="1.0.0-alpha.1" />
22+
<PackageReference Include="Catalyst.Modules.Crystal.OpenGL" Version="1.0.0-alpha.1" />
23+
</ItemGroup>
24+
25+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// -------------------------------------------------------------------------------------------------
2+
// CatalystUI Framework for .NET Core - https://catalystui.org/
3+
// Copyright (c) 2025 CatalystUI LLC. All rights reserved.
4+
//
5+
// This file is part of CatalystUI and is provided as part of an early-access release.
6+
// Unauthorized commercial use, distribution, or modification is strictly prohibited.
7+
//
8+
// This software is not open source and is not publicly licensed.
9+
// For full terms, see the LICENSE and NOTICE files in the project root.
10+
// -------------------------------------------------------------------------------------------------
11+
12+
// ReSharper disable once CheckNamespace
13+
14+
using Catalyst.Modules.Crystal.Connectors;
15+
16+
namespace Catalyst.Builders.Extensions {
17+
18+
/// <summary>
19+
/// Builder extensions for the <see cref="CatalystAppBuilder"/>.
20+
/// </summary>
21+
public static class CatalystAppBuilderExtensions {
22+
23+
/// <summary>
24+
/// Adds the Crystal-based Glfw3 to OpenGL surface connector to the <see cref="CatalystAppBuilder"/>.
25+
/// </summary>
26+
/// <remarks>
27+
/// <para>
28+
/// The Crystal-based Glfw3 to OpenGL surface connector adds the following to your CatalystUI application:
29+
/// <list type="bullet">
30+
/// <item><see cref="Glfw3OpenGLSurfaceConnector"/></item>
31+
/// </list>
32+
/// Click on any of the above links to learn more about each component.
33+
/// </para>
34+
/// </remarks>
35+
/// <param name="builder">The <see cref="CatalystAppBuilder"/> to add the connector to.</param>
36+
/// <returns>The <see cref="CatalystAppBuilder"/> with the Glfw3 to OpenGL surface connector added.</returns>
37+
public static CatalystAppBuilder AddCrystalGlfw3OpenGLSurfaceConnector(this CatalystAppBuilder builder) {
38+
Glfw3OpenGLSurfaceConnector connector = new();
39+
ModelRegistry.RegisterConnector(connector);
40+
return builder;
41+
}
42+
43+
}
44+
45+
}

0 commit comments

Comments
 (0)