Skip to content

Commit

Permalink
Merge pull request #127 from NogginBops/context-fixes
Browse files Browse the repository at this point in the history
Fix OpenGL context issues when using multiple GLWpfControls.
  • Loading branch information
NogginBops authored May 30, 2024
2 parents 319ee53 + 1fccaa2 commit eb7fbbc
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/Example/TabbedMainWindowTest.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@ public TabbedMainWindowTest()
{
InitializeComponent();
GLWpfControlSettings mainSettings = new GLWpfControlSettings {MajorVersion = 4, MinorVersion = 1, Profile = ContextProfile.Compatability, ContextFlags = ContextFlags.Debug};
// Start() makes the controls context current.
Control1.Start(mainSettings);
// We call Context.MakeCurrent() to make this explicitly clear.
Control1.Context.MakeCurrent();
scene1.Initialize();

GLWpfControlSettings insetSettings = new GLWpfControlSettings {MajorVersion = 4, MinorVersion = 1, Profile = ContextProfile.Compatability, ContextFlags = ContextFlags.Debug, Samples = 8};
Control2.Start(insetSettings);
Control2.Context.MakeCurrent();
scene2.Initialize();

GLWpfControlSettings transparentSettings = new GLWpfControlSettings { MajorVersion = 4, MinorVersion = 1, Profile = ContextProfile.Compatability, ContextFlags = ContextFlags.Debug, TransparentBackground = true};
Control3.Start(transparentSettings);
Control3.Context.MakeCurrent();
scene3.Initialize();

Control1.KeyDown += Control1_KeyDown;
Expand Down
6 changes: 6 additions & 0 deletions src/GLWpfControl/GLWpfControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ static GLWpfControl()

/// <summary>
/// Called whenever rendering should occur.
/// GLWpfControl makes sure that it's OpenGL context is current when this event happens.
/// </summary>
public event Action<TimeSpan>? Render;

Expand All @@ -37,7 +38,10 @@ static GLWpfControl()
/// This is only for extremely advanced use, where a non-display out task needs to run.
/// Examples of these are an async Pixel Buffer Object transfer or Transform Feedback.
/// If you do not know what these are, do not use this function.
///
/// GLWpfControl makes sure that it's OpenGL context is current when this event happens.
/// </summary>
[Obsolete("There is no difference between Render and AsyncRender. Use Render.")]
public event Action? AsyncRender;

/// <summary>
Expand Down Expand Up @@ -101,6 +105,8 @@ public bool RenderContinuously {

/// <summary>
/// The currently used OpenGL context, or null if no OpenGL context is created.
/// It is not safe to call <see cref="IGraphicsContext.MakeCurrent"/> on this context on any other thread
/// than the one the <see cref="GLWpfControl"/> is running on.
/// </summary>
[CLSCompliant(false)]
public IGraphicsContext? Context => _renderer?.GLContext;
Expand Down
5 changes: 5 additions & 0 deletions src/GLWpfControl/GLWpfControlRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ internal sealed class GLWpfControlRenderer : IDisposable
private readonly DxGlContext _context;

public event Action<TimeSpan>? GLRender;
[Obsolete("There is no difference between GLRender and GLAsyncRender. Use GLRender.")]
public event Action? GLAsyncRender;

/// <summary>The width of this buffer in pixels.</summary>
Expand Down Expand Up @@ -76,6 +77,8 @@ public void ReallocateFramebufferIfNeeded(double width, double height, double dp

if (D3dImage == null || FramebufferWidth != newWidth || FramebufferHeight != newHeight || MultisampleType != msaaType)
{
_context.GraphicsContext.MakeCurrent();

if (D3dImage != null)
{
GL.DeleteFramebuffer(GLFramebufferHandle);
Expand Down Expand Up @@ -195,6 +198,8 @@ public void Render(DrawingContext drawingContext)
return;
}

_context.GraphicsContext.MakeCurrent();

TimeSpan curFrameStamp = _stopwatch.Elapsed;
TimeSpan deltaT = curFrameStamp - _lastFrameStamp;
_lastFrameStamp = curFrameStamp;
Expand Down
2 changes: 2 additions & 0 deletions src/GLWpfControl/GLWpfControlSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ public sealed class GLWpfControlSettings
/// <summary>
/// May be null. If defined, an external context will be used, of which the caller is responsible
/// for managing the lifetime and disposal of.
/// The management of the context sent to the <see cref="GLWpfControl"/> becomes the responsibility of the <see cref="GLWpfControl"/>.
/// Trying to call <see cref="IGraphicsContext.MakeCurrent"/> on this context on some other thread might lead to uninteded consequences.
/// </summary>
[CLSCompliant(false)]
public IGraphicsContext? ContextToUse { get; set; }
Expand Down

0 comments on commit eb7fbbc

Please sign in to comment.