Author Topic: OpenGL in 2nd Window (Dialog or Graphic Window)  (Read 5914 times)

0 Members and 1 Guest are viewing this topic.

Offline Gary Beene

  • Jr. Member
  • **
  • Posts: 96
  • User-Rate: +3/-0
OpenGL in 2nd Window (Dialog or Graphic Window)
« on: June 17, 2010, 05:05:19 PM »
Are there some examples around for putting an OpenGL canvas in a 2nd dialog and also for putting it in a Graphic Window?

I thought the only real change would be to use the DC for the new window (dialog or Graphic Window) from this part of my OpenGL template (hDlg2 is the handle for the new window). But it doesn't seem to do the trick.

Is there some other initialization that has to be done to put a rendering context into a 2nd window (dialog or Graphic Window)?

Code: [Select]
Sub GetRenderContext
   Local pfd As PIXELFORMATDESCRIPTOR   'pixel format properties for device context
   pfd.nSize       =  SizeOf(PIXELFORMATDESCRIPTOR)
   pfd.nVersion    =  1
   pfd.dwFlags     = %pfd_draw_to_window Or %pfd_support_opengl Or %pfd_doublebuffer
   pfd.dwlayermask = %pfd_main_plane
   pfd.iPixelType  = %pfd_type_rgba
   pfd.ccolorbits  = 24
   pfd.cdepthbits  = 24

   hDC = GetDC(hDlg2)   '<---- this had used hDlg, handle to the main window
   SetPixelFormat(hDC, ChoosePixelFormat(hDC, pfd), pfd)  'set properties of device context
   hRC = wglCreateContext (hDC)                           'get rendering context
   wglMakeCurrent hDC, hRC                                'make the RC current
End Sub
« Last Edit: June 17, 2010, 05:07:12 PM by Gary Beene »

Offline Gary Beene

  • Jr. Member
  • **
  • Posts: 96
  • User-Rate: +3/-0
Re: OpenGL in 2nd Window (Dialog or Graphic Window)
« Reply #1 on: June 17, 2010, 05:28:31 PM »
I've seen comments like this, but am not sure if they apply in my case:

Quote
Check that you set the WS_CLIPCHILDREN style flag in the parent window, and the WS_CLIPSIBLINGS and WS_CHILD in the child.

I've experimented, adding this to my main and 2nd dialogs, but they seem to make no difference.

Offline Gary Beene

  • Jr. Member
  • **
  • Posts: 96
  • User-Rate: +3/-0
Re: OpenGL in 2nd Window (Dialog or Graphic Window)
« Reply #2 on: June 17, 2010, 05:31:08 PM »
I guess I should post a compilable example. This one is attempting to use a 2nd dialog as the OpenGL canvas.

Code: [Select]
'Compilable Example:
#Compile Exe
#Dim All
#Include "win32api.inc"
#Include "gl.inc"
#Include "glu.inc"

%ID_Timer = 1000 : %ID_Graphic = 1002

Global hDlg, hDlg2, hDC, hRC, hGraphic As DWord
Global scalefactor As Single

Function PBMain() As Long
  Dialog New Pixels, 0, "OpenGL Main Screen",,, 320, 240,%WS_OverlappedWindow To hDlg
  Dialog Show Modal hdlg Call dlgproc
End Function

CallBack Function dlgproc()
   Select Case CB.Msg
      Case %WM_InitDialog : OpenDialog
      Case %WM_Close      : Dialog End hDlg2
   End Select
End Function


Sub OpenDialog
  Dialog New Pixels, 0, "OpenGL Canvas",200,200, 320, 240,%WS_OverlappedWindow To hDlg2
  Dialog Show Modeless hdlg2 Call dlgproc2
End Sub

CallBack Function dlgproc2()
   Local pt As Point
   Local XDelta, YDelta as Single
   Static SpinInWork,XLast,YLast As Long

   Select Case CB.Msg
      Case %WM_InitDialog : GetRenderContext
                            InitializeScene
                            SetTimer(hDlg2, %ID_Timer, 50, %NULL)
      Case %WM_Timer      : DrawScene 1,1,0  'redraw with rotation on all 3 axes
      Case %WM_Paint      : DrawScene 0,0,0  'redraw with no rotation
      Case %WM_Size       : GetRenderContext : InitializeScene
                            ResizeScene Lo(Word, CB.lParam)-20, Hi(Word, CB.lParam)-20
                            DrawScene 0,0,0  'redraw with no rotation
      Case %WM_Close      : wglmakecurrent %null, %null 'unselect rendering context
                            wgldeletecontext hRC        'delete the rendering context
                            releasedc hDlg2, hDC         'release device context
      Case %WM_MouseWheel
         Select Case Hi(Integer,CB.wParam)
            Case > 0  : ScaleFactor = ScaleFactor + 0.1 : DrawScene 0,0,0
            Case < 0  : ScaleFactor = ScaleFactor - 0.1 : DrawScene 0,0,0
         End Select
      Case %WM_SetCursor
         Dialog Set Text hDlg2, Time$
         GetCursorPos pt          'p.x and p.y are in screen coordinates
         ScreenToClient hDlg2, pt  'p.x and p.y are now dialog client coordinates
         Select Case Hi(Word, CB.lParam)
            Case %WM_LButtonDown
               KillTimer CB.Hndl, %ID_Timer     
               SpinInWork = 1
               GetCursorPos pt              'pt has xy screen coordinates
               ScreenToClient hDC, pt       'pt now has dialog client coordinates
               XLast = Pt.x
               YLast = Pt.y
            Case %WM_MouseMove
               If SpinInWork Then
                  GetCursorPos pt           'pt has xy screen coordinates
                  ScreenToClient hDC, pt    'pt now has dialog client coordinates
                  XDelta = XLast - Pt.x
                  YDelta = YLast - Pt.y
                  DrawScene -YDelta, -XDelta, 0
                  XLast = pt.x
                  YLast = pt.y
               End If
            Case %WM_LButtonUp
               SetTimer(hDlg2, %ID_Timer, 50, %NULL)
               SpinInWork = 0 
         End Select
   End Select
End Function

Sub GetRenderContext
   Local pfd As PIXELFORMATDESCRIPTOR   'pixel format properties for device context
   pfd.nSize       =  SizeOf(PIXELFORMATDESCRIPTOR)
   pfd.nVersion    =  1
   pfd.dwFlags     = %pfd_draw_to_window Or %pfd_support_opengl Or %pfd_doublebuffer
   pfd.dwlayermask = %pfd_main_plane
   pfd.iPixelType  = %pfd_type_rgba
   pfd.ccolorbits  = 24
   pfd.cdepthbits  = 24

   hDC = GetDC(hDlg2)
   SetPixelFormat(hDC, ChoosePixelFormat(hDC, pfd), pfd)  'set properties of device context
   hRC = wglCreateContext (hDC)                           'get rendering context
   wglMakeCurrent hDC, hRC                                'make the RC current
End Sub

Sub InitializeScene
   glClearColor 0,0,0,0     'sets color to be used with glClear
   glClearDepth 1           'sets zvalue to be used with glClear
   glEnable %gl_depth_test                             'enable depth testing   
   glHint %gl_perspective_correction_hint, %gl_nicest  'best quality rendering
   BuildDisplayList 1
End Sub

Sub ResizeScene (w As Long, h As Long)
   glViewport 0, 0, w, h               'resize viewport to match window size
   glMatrixMode %gl_projection         'select the projection matrix
   glLoadIdentity                    'reset the projection matrix
   gluPerspective 45, w/h, 0.1, 100  'set frustum using viewport aspect ratio
   glMatrixMode %gl_modelview          'select the modelview matrix
End Sub

Sub DrawScene (dx As Single, dy As Single, dz As Single)
   Static anglex, angley, anglez As Single
   glClear %gl_color_buffer_bit Or %gl_depth_buffer_bit  'clear buffers
   glLoadIdentity               'clear the modelview matrix

   gluLookAt 0,0,6,0,0,0,0,1,0

   glScalef scalefactor, scalefactor, scalefactor

   anglex = anglex + dx : glRotatef anglex, 1,0,0
   angley = angley + dy : glRotatef angley, 0,1,0
   anglez = anglez + dz : glRotatef anglez, 0,0,1

   glCallList 1

   SwapBuffers hDC              'display the buffer (image)
End Sub

Sub BuildDisplayList(ListNumber As Long)
   glNewList ListNumber, %gl_compile
      glBegin %GL_QUADS
         glColor3f   0.0,  1.0,  0.0         ' Set the color to green
         glVertex3f  1.0,  1.0, -1.0         ' Top right of the quad (Top)
         glVertex3f -1.0,  1.0, -1.0         ' Top left of the quad (Top)
         glVertex3f -1.0,  1.0,  1.0         ' Bottom left of the quad (Top)
         glVertex3f  1.0,  1.0,  1.0         ' Bottom right of the quad (Top)
   
         glColor3f   1.0,  0.5,  0.0         ' Set the color to orange
         glVertex3f  1.0, -1.0,  1.0         ' Top right of the quad (Bottom)
         glVertex3f -1.0, -1.0,  1.0         ' Top left of the quad (Bottom)
         glVertex3f -1.0, -1.0, -1.0         ' Bottom left of the quad (Bottom)
         glVertex3f  1.0, -1.0, -1.0         ' Bottom right of the quad (Bottom)
   
         glColor3f   1.0,  0.0,  0.0         ' Set the color to red
         glVertex3f  1.0,  1.0,  1.0         ' Top right of the quad (Front)
         glVertex3f -1.0,  1.0,  1.0         ' Top left of the quad (Front)
         glVertex3f -1.0, -1.0,  1.0         ' Bottom left of the quad (Front)
         glVertex3f  1.0, -1.0,  1.0         ' Bottom right of the quad (Front)
   
         glColor3f   1.0,  1.0,  0.0         ' Set the color to yellow
         glVertex3f  1.0, -1.0, -1.0         ' Top right of the quad (Back)
         glVertex3f -1.0, -1.0, -1.0         ' Top left of the quad (Back)
         glVertex3f -1.0,  1.0, -1.0         ' Bottom left of the quad (Back)
         glVertex3f  1.0,  1.0, -1.0         ' Bottom right of the quad (Back)
   
         glColor3f   0.0,  0.0,  1.0         ' Set the color to blue
         glVertex3f -1.0,  1.0,  1.0         ' Top right of the quad (Left)
         glVertex3f -1.0,  1.0, -1.0         ' Top left of the quad (Left)
         glVertex3f -1.0, -1.0, -1.0         ' Bottom left of the quad (Left)
         glVertex3f -1.0, -1.0,  1.0         ' Bottom right of the quad (Left)
   
         glColor3f   1.0,  0.0,  1.0         ' Set the color to violet
         glVertex3f  1.0,  1.0, -1.0         ' Top right of the quad (Right)
         glVertex3f  1.0,  1.0,  1.0         ' Top left of the quad (Right)
         glVertex3f  1.0, -1.0,  1.0         ' Bottom left of the quad (Right)
         glVertex3f  1.0, -1.0, -1.0         ' Bottom right of the quad (Right)
      glEnd
   glEndList
End Sub

Offline Patrice Terrier

  • ROMs
  • Hero Member
  • *****
  • Posts: 936
  • User-Rate: +62/-1
    • www.zapsolution.com
Re: OpenGL in 2nd Window (Dialog or Graphic Window)
« Reply #3 on: June 17, 2010, 06:14:16 PM »
Gary,

There are many examples related to OpenGL on this forum, however if you restrict yourself to DDT Graphic, then you won't find much here.

You can render OpenGL everywhere, in one single or in several window container, and even hover the Windows desktop (see the Boing demo), but then i am afraid you have to go the SDK way.

...
« Last Edit: June 17, 2010, 06:19:10 PM by Patrice Terrier »
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Gary Beene

  • Jr. Member
  • **
  • Posts: 96
  • User-Rate: +3/-0
Re: OpenGL in 2nd Window (Dialog or Graphic Window)
« Reply #4 on: June 17, 2010, 06:31:13 PM »
Patrice,

Thank you for the response.

But I'm not sure what you meant by this (the SDK reference):

Quote
You can render OpenGL everywhere, in one single or in several window container, and even hover the Windows desktop (see the Boing demo), but then i am afraid you have to go the SDK way.

Would you clarify?  Are you suggesting that a DDT solution has limits of some kind, in using OpenGL? Or were you just referring to the BOING example?

As to the problem I've posted, I just came up with the following example that shows that I can use a 2nd DDT window to display OpenGL. Apparently my earlier example doesn't refresh the OpenGL canvas correctly (the 3D image appears, then disappears too quickly to see).  I'm still don't know exactly why the earlier example does not work, but at least this most recent example indicated that the basic approach is what I thought it was.

Code: [Select]
'Compilable Example:
#Compile Exe
#Dim All
#Include "win32api.inc"
#Include "gl.inc"
#Include "glu.inc"

Global hDlg, hDlg2, hDC, hRC As Dword

Function PBMain() As Long
  Dialog New Pixels, 0, "Main Screen",,, 320, 240,%WS_OverlappedWindow To hDlg
  Dialog Show Modal hdlg Call dlgproc
End Function

CallBack Function dlgproc()
   Select Case Cb.Msg
      Case %WM_InitDialog : OpenDialog2
      Case %WM_Size       : ResizeScene Lo(Word, Cb.LParam), Hi(Word, Cb.LParam)
                            DrawScene
   End Select
End Function

Sub OpenDialog2
  Dialog New Pixels, 0, "OpenGL Canvas",200,200, 320, 240,%WS_OverlappedWindow To hDlg2
  Dialog Show Modeless hdlg2 Call dlgproc2
End Sub

CallBack Function dlgproc2()
   Select Case Cb.Msg
      Case %WM_InitDialog : GetRenderContext
                            InitializeScene
      Case %WM_Size       : ResizeScene Lo(Word, Cb.LParam), Hi(Word, Cb.LParam)
                            DrawScene
      Case %WM_Paint      : DrawScene
      Case %WM_Close      : wglmakecurrent %null, %null 'unselect rendering context
                            wgldeletecontext hRC        'delete the rendering context
                            releasedc hDlg2, hDC         'release device context
   End Select
End Function

Sub GetRenderContext
   Local pfd As PIXELFORMATDESCRIPTOR   'pixel format properties for device context
   pfd.nSize       =  SizeOf(PIXELFORMATDESCRIPTOR)
   pfd.nVersion    =  1
   pfd.dwFlags     = %pfd_draw_to_window Or %pfd_support_opengl Or %pfd_doublebuffer
   pfd.dwlayermask = %pfd_main_plane
   pfd.iPixelType  = %pfd_type_rgba
   pfd.ccolorbits  = 24
   pfd.cdepthbits  = 24

   hDC = GetDC(hDlg2)                                      'DC for dialog
   SetPixelFormat(hDC, ChoosePixelFormat(hDC, pfd), pfd)  'set properties of device context
   hRC = wglCreateContext (hDC)                           'get rendering context
   wglMakeCurrent hDC, hRC                                'make the RC current
End Sub

Sub InitializeScene
   glClearColor 0,0,0,0     'sets color to be used with glClear
   glClearDepth 1           'sets zvalue to be used with glClear
End Sub

Sub ResizeScene (w As Long, h As Long)
   glViewport 0, 0, w, h             'resize viewport to match window size
   glMatrixMode %gl_projection       'select the projection matrix
   glLoadIdentity                    'reset the projection matrix
   gluPerspective 45, w/h, 0.1, 100  'calculate the aspect ratio of the Window
   glMatrixMode %gl_modelview        'select the modelview matrix
End Sub

Sub DrawScene
   glClear %gl_color_buffer_bit Or %gl_depth_buffer_bit  'clear buffers
   glLoadIdentity               'clear the modelview matrix
   glBegin %gl_triangles        'select triangles as primitive
      glcolor3ub 255,0,0        'set default vertex color
      glvertex3f  0, 1,  -4     'vertex1
      glvertex3f  -1, 0, -4     'vertex2
      glvertex3f  1, -1, -4     'vertex3
   glEnd
   SwapBuffers hDC              'display the buffer (image)
End Sub
« Last Edit: June 17, 2010, 06:39:12 PM by Gary Beene »

Offline Patrice Terrier

  • ROMs
  • Hero Member
  • *****
  • Posts: 936
  • User-Rate: +62/-1
    • www.zapsolution.com
Re: OpenGL in 2nd Window (Dialog or Graphic Window)
« Reply #5 on: June 17, 2010, 07:10:40 PM »
Gary

SDK allows you to take full control of what is going on inside of the render target without to resort on subclassing, especially if you need keyboard or mouse interactivity. You can even render OpenGL on a DirectDraw surface like DWM, or use a mix of GDIPLUS and OpenGL like in the AeroGL demo. But this would be very hard to do with the CreateDialog API and DDT Graphic, and as long as we speak of graphic, sooner or later you will hit the wall if you want to limit yourself to DDT.

There is a lot of thechnology in the BassBox project, going deep under the hood, you should take the time to studdy it, especially because this is a wonderful OpenGL project to learn from.

...

Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Offline Gary Beene

  • Jr. Member
  • **
  • Posts: 96
  • User-Rate: +3/-0
Re: OpenGL in 2nd Window (Dialog or Graphic Window)
« Reply #6 on: June 17, 2010, 07:14:13 PM »
Thanks, Patrice, for the clarification.

Not being much of a music person, I haven't looked at BassBox, to know that the source code is available and the it was OpenGL.  Thanks for the info.


Offline Gary Beene

  • Jr. Member
  • **
  • Posts: 96
  • User-Rate: +3/-0
Re: OpenGL in 2nd Window (Dialog or Graphic Window)
« Reply #7 on: June 17, 2010, 07:27:18 PM »
As to my problem, I'm afraid it was simply a stupid mistake on my part.

I failed to set my drawing ScaleFactor.  It defaulted to zero, so the image was not visible.

With that fixed, the image shows up just fine.

 ::) ::) ::)