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)?
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
I've seen comments like this, but am not sure if they apply in my case:
QuoteCheck 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.
I guess I should post a compilable example. This one is attempting to use a 2nd dialog as the OpenGL canvas.
'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
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.
...
Patrice,
Thank you for the response.
But I'm not sure what you meant by this (the SDK reference):
QuoteYou 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.
'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
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.
...
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.
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.
::) ::) ::)