Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 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
3 changes: 3 additions & 0 deletions Silk.NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "libraries", "libraries", "{
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silk.NET.Maths", "src\libraries\Silk.NET.Maths\Silk.NET.Maths.csproj", "{7A2A3176-DBA1-4026-AF65-8E36B4F09B01}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Silk.NET.Windowing", "src\libraries\Silk.NET.Windowing\Silk.NET.Windowing.csproj", "{7A2A3176-DBA1-4026-AF65-8E36B4F09B02}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "benchmarks", "benchmarks", "{FD15E196-1C63-47D6-8AD5-64F015120B4B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "infrastructure", "infrastructure", "{F07CABFC-DC6A-4B5B-BC56-B10EEC2C0BFA}"
Expand Down Expand Up @@ -361,6 +363,7 @@ Global
{5329AC43-7177-4953-AFAB-A9FA7B9A4C7C} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C}
{66FE736C-C407-44C3-A94E-4345E22AA95E} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C}
{381D1039-3259-488F-BB25-D90EE63A3E82} = {94D5D1E1-B998-4CB1-9D04-DA138A2B0F3C}
{7A2A3176-DBA1-4026-AF65-8E36B4F09B02} = {C9718C94-2F21-4E8D-B55D-8F0B1A131346}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F5273D7F-3334-48DF-94E3-41AE6816CD4D}
Expand Down
26 changes: 26 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/ContextFlags.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Silk.NET.Windowing
{
/// <summary>
/// Represents flags related to the OpenGL context.
/// </summary>
[Flags]
public enum ContextFlags
{
/// <summary>
/// No flags enabled.
/// </summary>
Default = 0,

/// <summary>
/// Enables debug context; debug contexts provide more debugging info, but can run slower.
/// </summary>
Debug = 1,

/// <summary>
/// Enables forward compatability; this context won't support anything marked as deprecated in the current
/// version.
/// </summary>
/// <remarks>On OpenGL contexts older than 3.0, this flag does nothing.</remarks>
ForwardCompatible = 2
}
}
19 changes: 19 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/ContextProfile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace Silk.NET.Windowing
{
/// <summary>
/// Represents the context profile OpenGL should use.
/// </summary>
public enum ContextProfile
{
/// <summary>
/// Uses a core OpenGL context, which removes some deprecated functionality.
/// </summary>
Core = 0,

/// <summary>
/// Uses a compatability OpenGL context, allowing for some deprecated functionality. This should only ever be
/// used for maintaining legacy code; no newly-written software should use this.
/// </summary>
Compatability
}
}
8 changes: 8 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/Delegates.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Silk.NET.Maths;
using Silk.NET.Windowing;

public delegate void Vector2DAction(Vector2D<int> newValue);
public delegate void DeltaAction(double deltaTime);
public delegate void WindowStateAction(WindowState newState);
public delegate void FilePathsAction(string[] filePaths);
public delegate void ToggleAction(bool newValue);
150 changes: 150 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/IDesktopSurface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
using Silk.NET.Core;
using Silk.NET.Maths;

namespace Silk.NET.Windowing
{
/// <summary>
/// A surface which wraps a Desktop Window.
/// </summary>
public interface IDesktopSurface : ISurface
{
/// <summary>
/// Whether or not the window is visible.
/// </summary>
bool IsVisible { get; set; }

/// <summary>
/// The position of the window. If set to -1, use the backend default.
/// </summary>
Comment on lines +20 to +22
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a <see... To where this backend default can be found.
Also why did we make the user figure this out?

Additionally, can't a window actually be outside the screen (negative coordinates), at least with whatever anchor point is used here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Someone will need to pick apart the logic I wrote in 2.X to determine whether that's possible (or just experiment separately)

if you want to find the code you can search for marks] and you'll find it.

Copy link
Contributor Author

@Redhacker1 Redhacker1 Aug 28, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if that is something we even know AOT, or if we have a type that exposes it at all, or if GLFW and other APIs expose such a thing in the first place.

Vector2D<int> Position { get; set; }

/// <summary>
/// The size of the window in pixels.
/// </summary>
new Vector2D<int> Size { get; set; }

/// <summary>
/// The window title.
/// </summary>
string Title { get; set; }

/// <summary>
/// The window state.
/// </summary>
WindowState WindowState { get; set; }

/// <summary>
/// The window border.
/// </summary>
WindowBorder WindowBorder { get; set; }

/// <summary>
/// The video mode.
/// </summary>
VideoMode VideoMode { get; set; }

/// <summary>
/// Gets the screen on which this window is active.
/// </summary>
IScreen? CurrentScreen { get; set; }
Comment on lines +50 to +53
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does null indicate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Relic of GLFW probably

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

null means user default. It will never be null post-initialization.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in GLFW null means it is currently windowed, not sure there is a way to query that information in windowed mode

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In GLFW yes, Silk never worked that way. Ctrl+F in the codebase for marks] to see our implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok


/// <summary>
/// Gets the available screens for this surface.
/// </summary>
Comment on lines +55 to +57
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does available mean, is this a property of IScreen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who knows

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no concept of a IWindowPlatform in 3.0 (by design!!!!) and this is where that property originally lived. I moved it onto the surfaces as a "here's the screens you can move this surface onto"

IEnumerable<IScreen>? AvailableScreens { get; }

/// <summary>
/// Gets or sets whether the window waits for an event to be posted before existing <see cref="DoEvents" />.
/// </summary>
bool IsEventDriven { get; set; }
Copy link
Member

@HurricanKai HurricanKai Aug 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the proposal go into details about this? Seems like a relic of 2.x that's not really needed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given the update loop is very similar to 2.X this will still be needed for applications (e.g. UI) that do not regularly need to render (i.e. only when an animation changes or some other event happens such as the user moving their mouse or the window etc)


/// <summary>
/// Gets or sets whether the window has been requested to close.
/// </summary>
bool IsCloseRequested { get; set; }

/// <summary>
/// Gets whether the window is focused or not.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: or not is unecessary

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know, all of the interfaces are pretty much pulled from the proposal directly, if you have issues with it, it might be best to talk about overall proposal changes.

/// </summary>
bool IsFocused { get; }

/// <summary>
/// Gets the distances in screen coordinates from the edges of the content area to the corresponding edges of
/// the full window.
/// </summary>
/// <remarks>
/// Because these are distances and not coordinates, they are always zero or positive.
/// </remarks>
/// <seealso cref="WindowExtensions.GetFullSize"/>
Rectangle<int> BorderSize { get; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's unclear to me what the docs are saying here. We don't use the concept of a content area anywhere else.
Is there a different way to word this to make it easier to understand?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no idea what it is.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content area describes the space a window can actually take up. So on a 2160p monitor, it will be 3840 x (2160 - <size of taskbar>) if that makes any sense.


/// <summary>
/// Raised when the window has been requested to close.
/// </summary>
event Action CloseRequested;
Comment on lines +85 to +88
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the corresponding boolean property set before or after?
(add to remarks)

In line with other properties, there should be a delegate providing the new value and the old value should be found in the property.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set before (the user can cancel closure by setting it back to false), agree needs remarks (in proposal)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is CloseRequested fired when the boolean property is set?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this should be UserCloseRequested as this is strictly when the "X" button is pressed


/// <summary>
/// Raised when the window is moved.
/// </summary>
Comment on lines +90 to +92
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document that move is fired before the property is changed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This is something that should be documented in general)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it?

event Vector2DAction? Move;

/// <summary>
/// Raised when the window state is changed.
/// </summary>
event WindowStateAction? StateChanged;

/// <summary>
/// Raised when the user drops files onto the window.
/// </summary>
event FilePathsAction? FileDrop;

/// <summary>
/// Raised when the window focus changes.
/// </summary>
event ToggleAction? FocusChanged;

/// <summary>
/// Sets the window icons.
/// </summary>
/// <param name="icons">Either a collection of window icons, or null to set to the default icon.</param>
void SetWindowIcon(ReadOnlySpan<RawImage> icons)
{
throw new NotImplementedException();
}

/// <summary>
/// When using <see cref="WindowOptions.IsEventDriven"/> = true, wakes the main thread from
/// its blocking wait on incoming events. Can be called from any thread.
/// </summary>
void ContinueEvents()
{
throw new NotImplementedException();
}

/// <summary>
/// Converts this point to client coordinates.
/// </summary>
/// <param name="point">The point to transform.</param>
/// <returns>The transformed point.</returns>
/// <remarks>Expects screen coordinates as input.</remarks>
Vector2D<int> PointToClient(Vector2D<int> point)
{
return new Vector2D<int>(point.X - Position.X, point.Y - Position.Y);
}

/// <summary>
/// Converts this point to screen coordinates.
/// </summary>
/// <param name="point">The point to transform.</param>
/// <returns>The transformed point.</returns>
/// <remarks>Expects client coordinates as input.</remarks>
Vector2D<int> PointToScreen(Vector2D<int> point)
{
return new Vector2D<int>(point.X + Position.X, point.Y + Position.Y);
}
public Vector2D<int> PointToFramebuffer(Vector2D<int> point)
{
throw new NotImplementedException();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be no implementations here

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

namespace Silk.NET.Windowing
{
public interface IGLDesktopSurface : IDesktopSurface, IGLSurface { }
}
17 changes: 17 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/IGLSurface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Silk.NET.Windowing
{
public interface IGLSurface : INativeGLSurface
{
ContextFlags ContextFlags { get; set; }
ContextProfile ContextProfile { get; set; }
IGLSurface? SharedContext { get; set; }

/// <summary>
/// Enables OpenGL support for this surface. This will create a surface upon initialization.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The docs seem a bit vague. Maybe "... create an OpenGL surface upon initialization"? I don't know GL too well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what specifically you are talking about here, I don't even think you would want to create a gl context upon initialization, nor gles for that matter

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was quoting the doc line specifically. GitHub API is sometimes suboptimal

This will create a surface upon initialization.

Copy link
Contributor Author

@Redhacker1 Redhacker1 Aug 6, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really IMO it should expose a CreateGL(ES)Context method and not run at initialization.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initialization refers to the window actually being created on the OS. You can't create an OpenGL context without a window, and you don't have a window until Initialize is called.

POSSIBLY USEFUL INCOHERENT RAMBLING: It is possible we will want to make ISurface an abstract base class primarily because leaving this to the implementor is a lot of trust. i.e. it would be nice if all the implementation has to do is implement Run(Action) and then when that method starts we do everything that Initialize would do, same with Reset at the end, make sure the actual implementation never knows about DoUpdate and DoRender (but still expose these so users can implement their own loops) [though, I have some game loop ideas that too would render these obsolete], and leave the implementation to update the events whenever it feels like it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh and to answer the question directly, this method basically says "Hey you, surface: make an OpenGL context on the window that gets created in Initialize". But once again there is lots of talk of removing OpenGL and Vulkan context/surface creation in core windowing itself and directly using the mechanisms in each respective ecosystem directly, rather than entrusting this into a native library such as GLFW.

/// </summary>
bool TryEnableOpenGL()
{
throw new NotImplementedException();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No implementations here

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

namespace Silk.NET.Windowing
{
public interface IGLTransparentFramebuffer : INativeGLSurface
{
bool TransparentFramebuffer { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Silk.NET.Windowing
{
public interface IGlesDesktopSurface : IDesktopSurface, IGlesSurface
{

}
}
11 changes: 11 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/IGlesSurface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Silk.NET.Windowing
{
public interface IGlesSurface : INativeGLSurface
{
IGlesSurface? SharedContext { get; set; }
/// <summary>
/// Enables OpenGLES support for this surface. This will create a surface upon initialization.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as with OpenGL

/// </summary>
bool TryEnableOpenGLES();
}
}
56 changes: 56 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/INativeGLSurface.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Silk.NET.Core;
using Silk.NET.Maths;

namespace Silk.NET.Windowing
{
public interface INativeGLSurface : ISurface
{
nint Handle { get; }
bool IsContextCurrent { get; set; }
bool ShouldSwapAutomatically { get; set; }

/// <summary>
/// Sets the number of vertical blanks to wait between calling <see cref="SwapBuffers" /> and presenting the image,
/// a.k.a vertical synchronization (V-Sync). Set to <c>1</c> to enable V-Sync.
/// </summary>
/// <remarks>
/// Due to platform restrictions, this value can only be set and not retrieved.
/// </remarks>
int SwapInterval { set; }

/// <summary>
/// Preferred depth buffer bits of the window's framebuffer.
/// </summary>
/// <remarks>
/// Pass <c>null</c> or <c>-1</c> to use the system default.
/// </remarks>
int? PreferredDepthBufferBits { get; set; }

/// <summary>
/// Preferred stencil buffer bits of the window's framebuffer.
/// </summary>
/// <remarks>
/// Pass <c>null</c> or <c>-1</c> to use the system default.
/// </remarks>
int? PreferredStencilBufferBits { get; set; }

/// <summary>
/// Preferred red, green, blue, and alpha bits of the window's framebuffer.
/// </summary>
/// <remarks>
/// Pass <c>null</c> or <c>-1</c> for any of the channels to use the system default.
/// </remarks>
Vector4D<int>? PreferredBitDepth { get; set; }

/// <summary>
/// The API version to use.
/// </summary>
Version32? ApiVersion { get; set; }

nint? GetProcAddress(string proc);
void SwapBuffers()
{
throw new NotImplementedException();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No implementations here

}
}
44 changes: 44 additions & 0 deletions src/libraries/Silk.Net.Windowing/Abstract/IScreen.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Silk.NET.Maths;

namespace Silk.NET.Windowing
{
/// <summary>
/// An interface representing a screen.
/// </summary>
public interface IScreen
{
/// <summary>
/// The name of this screen.
/// </summary>
string Name { get; }

/// <summary>
/// The index of this screen.
/// </summary>
int Index { get; }

/// <summary>
/// The workarea of this screen.
/// </summary>
Rectangle<int> WorkArea { get; }

/// <summary>
/// The current video mode of this monitor.
/// </summary>
VideoMode VideoMode { get; }

/// <summary>
/// This screen's gamma correction.
/// </summary>
float Gamma { get; set; }

/// <summary>
/// Get all video modes that this screen supports.
/// </summary>
/// <returns>An array of all video modes.</returns>
IEnumerable<VideoMode> GetAllVideoModes()
{
throw new NotImplementedException();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No implementations here

}
}
Loading