Open antoinecla opened 6 years ago
This seems related to other issue #70. Tonight I'll investigate on this.
Are you setting Animation to true? Do you have tried to use a Forms.Timer calling Invalidate() on GlControl?
Many thanks for replying so quickly.
Just tried to disable Animation and use a Timer instead. This solve the issue.
What I don't understand is that the first thing I tried is to disable Animation and still had the refresh issue on the rest of the UI. Now, it seems to work.
In between, I tried many different things. Maybe I changed something else that had a positive side effect. In any case, try the steps above to reproduce the issue.
At least, I now have a working solution! Thanks again for your feedback.
I am not sure this is related.
I have a strange behavior when using two GlControl
in the same form. Both controls use the OwnContext
property. It seems anyway that setting a texture in one control affects the other one. Is this expected?
On a side note, I have checked the ContextSharing/SimpleSharing sample and get an exception on start:
System.InvalidOperationException: no GlControl sharing with TestGroup
at OpenGL.GlControl.ReuseOtherContext() in GlControl.cs:line 836
at OpenGL.GlControl.CreateContext() in GlControl.cs:line 668
at OpenGL.GlControl.OnHandleCreated(EventArgs e) in GlControl.cs:line 1108
at System.Windows.Forms.Control.WmCreate(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.UserControl.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
I have found an explanation for the first part of my last comment.
Here is what I am doing:
GlControl
has a property to set a Bitmap
Bitmap
is used to create an OpenGL textureSince everything is happening on the same thread, the approach appeared valid to me. Wrong! Obviously, this cannot work. There is no way to guaranty that an OpenGL resource is created on the DeviceContext
of the corresponding GlControl
.
A call to MakeCurrentContext()
prior to creating the GL resource solve the issue.
What can be confusing is that you do not need to do that inside OnContextCreated(), OnRender(), the related events and all methods called by them. The problem arises when one of this methods is also called from the "outside".
A note in the Common Mistakes section in your wiki could be useful!
I have a strange behavior when using two GlControl in the same form. Both controls use the OwnContext property. It seems anyway that setting a texture in one control affects the other one. Is this expected?
Leaving ContextSharing
to OwnContext
, creates a GL context for each GlControl; and they share the same namespace using wglShareLists
. Indeed textures and other objects exists for every GL context. This behavior is expected: contexts shares resources.
A call to MakeCurrentContext() prior to creating the GL resource solve the issue.
I suspect that the thread executing the event handle is not the UI thread. Normally all UserControl
methods are called by the UI thread, which the context is current due the OnPaint
override. What is the value of DeviceContext.GetCurrentContext() in the event handler? What is the thread ID?
Normally this issue is solved by having a dirty bit that command a GL operation in ContextUpdate
.
I suspect that the thread executing the event handle is not the UI thread. Normally all UserControl methods are called by the UI thread, which the context is current due the OnPaint override. What is the value of DeviceContext.GetCurrentContext() in the event handler? What is the thread ID?
Remember there are two GlControl
in the same form. At any moment, the Context can switch from one to the other. Here is a scenario:
Normally this issue is solved by having a dirty bit that command a GL operation in ContextUpdate.
Totally agree. I was thinking about something like that.
Assuming a Form
with two GlControl
and the following code:
public partial class Form1 : Form
{
uint _Shader;
public Form1()
{
InitializeComponent();
}
private void glControl1_ContextCreated(object sender, GlControlEventArgs e)
{
}
private void glControl1_ContextDestroying(object sender, GlControlEventArgs e)
{
}
private void glControl2_ContextCreated(object sender, GlControlEventArgs e)
{
_Shader = Gl.CreateShader(ShaderType.VertexShader);
}
private void glControl2_ContextDestroying(object sender, GlControlEventArgs e)
{
IntPtr context = DeviceContext.GetCurrentContext();
if(context != IntPtr.Zero)
{
Gl.DeleteShader(_Shader);
}
}
}
When closing the form and upon deletion of the shader, I get the GL error: InvalidValue
(call stack below).
Inspecting the CurrentContext in glControl2_ContextDestroying()
shows it is different from both the glControl1
and glControl2
context.
What is this third context? Why the shader cannot be deleted?
If I move the code from glControl2 to glControl1, the shader is deleted without issue.
Partial Call Stack:
> OpenGL.Net.dll!OpenGL.Gl.CheckErrors() Line 499 C#
OpenGL.Net.dll!OpenGL.Gl.DebugCheckErrors(object returnValue) Line 511 C#
OpenGL.Net.dll!OpenGL.Gl.DeleteShader(uint shader) Line 1227 C#
GlNetDualControlTest.exe!GlNetDualControlTest.Form1.glControl2_ContextDestroying(object sender, OpenGL.GlControlEventArgs e) Line 47 C#
OpenGL.Net.WinForms.dll!OpenGL.GlControl.OnContextDestroying() Line 1024 C#
OpenGL.Net.WinForms.dll!OpenGL.GlControl.OnHandleDestroyed(System.EventArgs e) Line 1130 C#
System.Windows.Forms.dll!System.Windows.Forms.Control.WmDestroy(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.UserControl.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.UnsafeNativeMethods.DestroyWindow(System.Runtime.InteropServices.HandleRef hWnd) Unknown
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DestroyHandle() Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.DestroyHandle() Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.Dispose(bool disposing) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Form.Dispose(bool disposing) Unknown
Steps to reproduce:
This is a simple example but in my own application with a complex user interface most of the other controls are not refreshed at all.
I just discovered the issue when integrating to my main application the GlControl / Scene I developed separately. Problem: I am due to present the prototype at the end of the week!!
This presentation is critical for me and I am stuck. I am unable to debug the issue and have no enough time to switch to an other binding.
Let me know if you can look into this issue.