Login  Register

Re: New tutorial on AWT/SWT/Swing/GLJPanel/GLCanvas

Posted by Sven Gothel on Feb 12, 2011; 4:47am
URL: https://forum.jogamp.org/New-tutorial-on-AWT-SWT-Swing-GLJPanel-GLCanvas-tp2363921p2478525.html

On Friday, February 11, 2011 23:47:03 Wade Walker [via jogamp] wrote:

>
> Sven Gothel wrote:
> >
> > On Friday, February 11, 2011 11:02:37 Sven Gothel wrote:
> >>   89     long hdc = WGL.wglGetCurrentDC();
> >>   90     if (0 == hdc) {
> >>   91       throw new GLException("Error: attempted to make an external
> >> GLDrawable without a drawable current, werr " + GDI.GetLastError());
> >>   92     }
> >>   93     int hdcType = GDI.GetObjectType(hdc);
> >>   94     if( GDI.OBJ_DC != hdcType ) {
> >>   95         // FIXME: Turns out in above use case (WinXP-32bit, GDI,
> >> SWT) the returned DC (not 0) is invalid!
> >
>
> I know why this fails now  If you wrap the external context creation like
> this, my SWT tutorial works:
>
> int hDC = OS.GetDC( glcanvas.handle );
> final GLContext glcontext = GLDrawableFactory.getFactory( glprofile
> ).createExternalGLContext();
> OS.ReleaseDC(glcanvas.handle, hDC);
>
> The reason is because SWT doesn't leave a current DC. In the GLCanvas()
> constructor and in GLCanvas.makeCurrent(), they create a temp DC like this
> and release it immediately after use.
>
> So when you call WGL.wglGetCurrentDC() it returns a DC handle, but it's
> invalid because SWT released it

I see your point ..

yup, the SWT GLCanvas.setCurrent() source code reads:

+++

public  void setCurrent()
{
        checkWidget ();
        if (WGL.wglGetCurrentContext () == context) return;
        int /*long*/ hDC = OS.GetDC (handle);
        WGL.wglMakeCurrent (hDC, context);
        OS.ReleaseDC (handle, hDC);
}

+++

Hence it 'breaks' the contract of
providing a current _and_ usable HDC via wglGetCurrentDC().

We could hack our way through it via:

- The GDI function 'HWND WindowFromDC(HDC)' is only available >= Windows 2000,
  I will give that a try.

- ignoring the GLCapabilities / configuration, this would 'allow' us to not rely on HDC.

- pass a window handle 'hint' as an optional factory argument
  allowing not to rely on the current DC

both are pretty ugly IMHO.


>
> Looking at the JOGL 1.1.1.a code for
> GLDrawableFactory.createExternalGLContext(), you can see that they didn't
> use a DC anywhere inside, so they didn't have this problem.
>
> I guess the solution is to remove the need for a DC inside the new JOGL 2
> createExternalGLContext(). I'm not sure of the best way to do that -- I'd
> probably end up butchering your code

The SWT solution here is to provide a prober binding IMHO,
since it's implementation breaks the above 'contract'.

You test code gives hope to a very simple solution.

GLCanvas.handle is a HWND, since you derive the DC from it ?

Composite is GLCanvas's parent.
Is Composite's handle the HWND as well ? I assume.

We could simply hook a NativeSurface/Window to Composite
and handle _all_ GL stuff by JOGL here.

1) Short cut:
-------------
The common code pieces (already exist) are in
WindowsDummyWGLDrawable and ProxySurface.

Extracting the 'surface/DC' update part (lock-/unlockSurface)
to a win32 specialisation of ProxySurface or impl. of NativeSurface
(as done in NEWT's WindowsWindow) would allow proper JOGL usage.

Sure, this would assume that SWT would not interfere with the eg Composite
resource, which is 'unsure'.

This leads us to the 2nd solution:

2a) NEWT Native Parenting
-------------------------

We could also just use the NEWT model here, utilizing
Composite's HWND (or X11 window id, ..) exposed as Composite.handle
(is this true?).

Then the normal (NEWT) workflow would be possible within SWT,
as exercised for NewtCanvasAWT.

The implementation 'key' is to have:
  'NativeWindow NewtFactoryAWT.getNativeWindow(java.awt.Component awtComp, CapabilitiesImmutable capsRequested)'
for SWT, ie
  'NativeWindow NewtFactorySWT.getNativeWindow(Composition swtComp, CapabilitiesImmutable capsRequested)'

This would simply use Composition.handle and query the pixel format here (X11) or later (Win32/OSX).
Code reusage at it's best - all pure Java code :)

The resulting NewtCanvasSWT would just bind SWT events to NEWT for lifecycle events etc, thats all.

I guess with a little SWT help, we could do that.

2b) Creating a JOGL GLCanvas for SWT, as done with AWT

This is IMHO a bad solution, since it forces does not allow the user to use SWT
window system agnostic, (2a) would allow you to drop your NEWT / JOGL code to SWT, AWT and core NEWT.

This path also makes assumptions in SWT behavior and available 'hooks' in regards to the
configuration / initialization, as we do this with AWT.

For example the AWT GLCanvas is broken by design, using non public AWT API,
where the NewtCanvasAWT is a proper design using only the JAWT public API.

However .. somebody might like to implement this.

>
> MS probably changed the behavior of DC release in 64-bit versions of
> Windows, so you can sometimes access a DC after release without crashing.
> But it's probably not good to count on this.
>
> _______________________________________________
> If you reply to this email, your message will be added to the discussion below:
> http://jogamp.762907.n3.nabble.com/New-tutorial-on-AWT-SWT-Swing-GLJPanel-GLCanvas-tp2363921p2477248.html
> To start a new topic under jogl, email [hidden email]
> To unsubscribe from jogl, visit
health & wealth
mailto:
[hidden email] ; http://jausoft.com
land : +49 (471) 4707742 ; cell: +49 (151) 28145941
Timezone CET: PST+9, EST+6, UTC+1