Announcement

Collapse

Maintenance

The forum could be offline for 30-60 minutes in the very near future for maintenance (said 3pm Pacific). I was behind on getting this notice. I do apologize.
See more
See less

Use Only Portion of Dialog as OpenGL RC

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Use Only Portion of Dialog as OpenGL RC

    Can I limit an OpenGL rendering context to a specified area of a dialog? Or do I have to use the whole dialog as the RC?

    For example, if I have several other controls on a dialog, can I put an OpenGL display in the unused area of a dialog, complete with the center of that area defined as the 0,0,0 point in the rendering context?

  • #2
    The alternative, of course, is to put a control in the area. But, the question occurred to me if a control was optional.

    I suppose I can use the whole dialog as an RC and color the unused areas of the RC the same color as the dialog background. But that means I'll be drawing/moving/rotating off-center from the RC 0,0,0 point - complicating the OpenGL commands somewhat.

    Hence my question about treating a specified area of a window as an RC, complete with the center of that area defined as the 0,0,0 center of the RC.
    Last edited by Gary Beene; 22 Mar 2013, 05:18 PM.

    Comment


    • #3
      Hi Gary ,
      I intend to use some OpenGl features in an app I'm working on ,and have exactly the same question you had some time ago .
      May I ask if you've found a solution to do so ?
      I saw in your "gbs 00586" you coded:
      Code:
       CONTROL ADD LABEL, hdlg, %ID_Label,"",110,50,100,100,%WS_CHILD OR %WS_VISIBLE OR %SS_SUNKEN OR %SS_NOTIFY
      Does this do the trick ?
      If so I don't understand how the parameters 100,100 in the "110,50,100,100" declaration directs OpenGl to the full drawing context
      Code:
       CONTROL HANDLE hdlg, %ID_Label TO hLabel
          hDC = GetDC(hLabel)
      as the params 100,100 are much smaller than the resulting drawing context .

      Comment


      • #4
        Hi Frank,
        Looking at my gbSnippet library, gbs_00584, I see that it worked with just a graphic control. On a quick test, it works with a label as well.

        Code:
        'Compilable Example:
        #Compiler PBWin 10
        #Compile Exe
        #Dim All
        %Unicode=1
        #Include "win32api.inc"
        #Include "gl.inc"
        #Include "glu.inc"
        
        %ID_Timer = 1000 : %ID_Graphic = 1002
        
        Global hDlg, hDC, hRC, hGraphic As Dword
        Global scalefactor As Single
        
        Function PBMain() As Long
           Dialog New Pixels, 0, "OpenGL Example",,, 320, 240,%WS_OverlappedWindow To hDlg
           Control Add Graphic, hDlg, %ID_Graphic,"",10,10,300,220, %WS_Child Or %WS_Visible Or %SS_Sunken Or %SS_Notify
           Graphic Attach hDlg, %ID_Graphic
           Dialog Show Modal hdlg Call dlgproc
        End Function
        
        CallBack Function dlgproc()
           Local pt As Point, w,h As Long
           Local XDelta, YDelta As Single
           Static SpinInWork,XLast,YLast As Long
        
           Select Case Cb.Msg
              Case %WM_InitDialog : GetRenderContext
                 InitializeScene
                 SetTimer(hDlg, %ID_Timer, 50, %NULL)
                 ScaleFactor = 1
              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
                 Control Set Size hDlg, %ID_Graphic, Lo(Word,Cb.LParam)-20,Hi(Word,Cb.LParam)-20
                 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 hDlg, 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
                 GetCursorPos pt          'p.x and p.y are in screen coordinates
                 ScreenToClient hDlg, pt  'p.x and p.y are now dialog client coordinates
                 If GetDlgCtrlID(ChildWindowFromPoint( hDlg, pt )) <> %ID_Graphic Then Exit Function
                 Select Case Hi(Word, Cb.LParam)
                    Case %WM_LButtonDown
                       GetCursorPos pt              'pt has xy screen coordinates
                       ScreenToClient hDlg, pt       'pt now has dialog client coordinates
                       If pt.y < 0 Then Exit Select
                       KillTimer Cb.Hndl, %ID_Timer
                       SpinInWork = 1
                       XLast = Pt.x
                       YLast = Pt.y
                    Case %WM_MouseMove
                       If SpinInWork Then
                          GetCursorPos pt           'pt has xy screen coordinates
                          ScreenToClient hDlg, pt    'pt now has dialog client coordinates
                          If pt.y < 0 Then Exit Select
                          XDelta = XLast - Pt.x
                          YDelta = YLast - Pt.y
                          DrawScene -YDelta, -XDelta, 0
                          XLast = pt.x
                          YLast = pt.y
                       End If
                    Case %WM_LButtonUp
                       SetTimer(hDlg, %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
        
           Control Handle hdlg, %ID_Graphic To hGraphic
           hDC = GetDC(hGraphic)
           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
        
        'gbs_00584
        'Date: 03-10-2012
        Last edited by Gary Beene; 4 Jan 2015, 02:48 PM. Reason: ... changed to PBWin code ...

        Comment


        • #5
          Hey Frank,
          I never found the solution to the question - of using just a portion of the Dialog for the render context. Have you come up with something since we last talked about this?

          Comment


          • #6
            Gary,

            You just need a window to render to. I create a child window with createwindowex of my main window.

            As for controls, they are ALL windows....everything is a window! So that kinda works, but I'd think you want ownerdrawn, and subclass it, but that's a lot of really unnecessary work, when you can just create your own window class.
            "Show me a young Conservative and I'll show you someone with no heart. Show me an old Liberal and I'll show you someone with no brains." ― Winston Churchill
            "Socialism is the philosophy of failure, the creed of ignorance and the gospel of envy." ― Winston Churchill

            Comment


            • #7
              And, I'd recommend to NOT use a DDT graphic control as the window to render to. It's unnecessary, as you will just redraw the scene in the WM_PAINT message. There is no need for any of the "under the hood" buffering or mouse processing that a graphic control does.

              Code:
              FUNCTION GraphicWindow(BYVAL hParent AS DWORD, BYVAL hInst AS DWORD) AS DWORD
                  LOCAL TLClass AS ASCIIZ * 12
                  LOCAL IsInitialized AS LONG
                  LOCAL wc            AS WndClassEx
              
                  TLClass = "TL3DWindow"
                  IsInitialized = GetClassInfoEx(EXE.INST, TLClass, wc)
                  IF IsInitialized = 0 THEN
                      wc.cbSize        = SIZEOF(wc)
                      wc.style         = %CS_DBLCLKS OR %CS_BYTEALIGNWINDOW
                      wc.lpfnWndProc   = CODEPTR(GraphicProc)
                      wc.cbClsExtra    = 0
                      wc.cbWndExtra    = 4
                      wc.hInstance     = hInst
                      wc.hIcon         = %null
                      wc.hCursor       = LoadCursor(%NULL, BYVAL %IDC_ARROW)
                      wc.hbrBackground = %null
                      wc.lpszMenuName  = %NULL
                      wc.lpszClassName = VARPTR(TLClass)
                      wc.hIconSm       = wc.hIcon
                      IF RegisterClassEx(wc) THEN IsInitialized = %TRUE
                  END IF
              
                  IF IsInitialized=0 THEN EXIT FUNCTION
              
                  FUNCTION = CreateWindowEx(0, _
                          TLClass, _
                          "", _
                          %WS_CHILD OR %WS_VISIBLE, _
                          0, 0, _
                          10, _
                          10, _
                          hParent, _
                          %IDW_GRAPHIC, _
                          wc.hInstance, _
                          BYVAL %NULL)
              END FUNCTION
              Note: The actual size is handled in the callback procedure.
              "Show me a young Conservative and I'll show you someone with no heart. Show me an old Liberal and I'll show you someone with no brains." ― Winston Churchill
              "Socialism is the philosophy of failure, the creed of ignorance and the gospel of envy." ― Winston Churchill

              Comment


              • #8
                Hi Doug!
                Yes, I've successfully used controls/dialog as the device/render context - no sub-classing of the control required.

                I just wondered if I could use a portion of the dialog, ignoring/not interfering with any controls that I might place elsewhere. Essentially, a viewport onto the window DC where the viewport is smaller than the window and can be located where desired.

                Comment


                • #9
                  just render to an buffer and convert that to a GDI bitmap, put that on the dialog wherever you want it.

                  Comment


                  • #10
                    Originally posted by Gary Beene View Post
                    Hi Doug!
                    Yes, I've successfully used controls/dialog as the device/render context - no sub-classing of the control required.

                    I just wondered if I could use a portion of the dialog, ignoring/not interfering with any controls that I might place elsewhere. Essentially, a viewport onto the window DC where the viewport is smaller than the window and can be located where desired.
                    Subclass COULD be required was my point. A "control" is a window. Period. The difference is as "control" is a window that is a predifined class, and therefore a predefined callback with some standard/documented behavioir. It also handles painting. These things could INTERFERE with your use as a rendering DC.

                    A DDT GRAPHIC "control" is a window. It is also persistent, so it must be buffering the graphics and automatically repainting for you. It is also handling SOME mouse input...and who knows what else. It may work, but it is not the most efficient way to use OpenGL rendering. No buffering is needed.

                    A DC you get for a given window is it's client DC, not a partial section of a window. Therefore the "cleanest way" is to create a child window and size it in the client however you like. You have just created your own "control", with it's own callback proc, you can process painting and input however you like, in the DC of this child window.

                    OpenGL gets you close to if not directly using the GPU/Buffers...that's why it's fast. No need to have a bitmap buffer for repaints...just handle WM_Paint, and redraw the scene.

                    @Chris; Can be done? Yes. But it is inefficient compared to OpenGL rendering. You're just adding an unnecessary step (and a slow one compared to OGL).
                    "Show me a young Conservative and I'll show you someone with no heart. Show me an old Liberal and I'll show you someone with no brains." ― Winston Churchill
                    "Socialism is the philosophy of failure, the creed of ignorance and the gospel of envy." ― Winston Churchill

                    Comment


                    • #11
                      Originally posted by Doug Hitchens View Post
                      @Chris; Can be done? Yes. But it is inefficient compared to OpenGL rendering. You're just adding an unnecessary step (and a slow one compared to OGL).
                      Yes, and incidentally, doing what Gary asked for instead of telling him that he was starting in the wrong place!

                      But you are right, and there is a temptation** to think of windows as each coming with a lot of baggage, which may be so, but the baggage is handled with little effort by the OS.

                      ** perish the thought that Gary may have been tempted!

                      Comment


                      • #12
                        Originally posted by Chris Holbrook View Post
                        Yes, and incidentally, doing what Gary asked for instead of telling him that he was starting in the wrong place!
                        I was answering the question both Frank and Gary were asking, as best I knew how. How is that telling Gary he is starting in the wrong place?

                        But you are right, and there is a temptation** to think of windows as each coming with a lot of baggage, which may be so, but the baggage is handled with little effort by the OS.

                        ** perish the thought that Gary may have been tempted!
                        I don't understand this at all. Care to explain?
                        "Show me a young Conservative and I'll show you someone with no heart. Show me an old Liberal and I'll show you someone with no brains." ― Winston Churchill
                        "Socialism is the philosophy of failure, the creed of ignorance and the gospel of envy." ― Winston Churchill

                        Comment


                        • #13
                          Originally posted by Doug Hitchens View Post
                          I was answering the question both Frank and Gary were asking, as best I knew how. How is that telling Gary he is starting in the wrong place?

                          I don't understand this at all. Care to explain?
                          No thanks, life is too short.

                          Comment


                          • #14
                            Doug,

                            A DC you get for a given window is it's client DC, not a partial section of a window
                            Yes, but as I mentioned, I was hoping that there was a write-within-a-bounds feature of OpenGL that I might have missed.

                            I've seen such drawing options elsewhere, even with PowerBASIC statements, where the results of drawing statements can be limited to a specified rectangle within the drawing canvas.

                            If there were such a feature, then it would be as "clean" as your suggestion to create a window and use it - more minimal actually since it doesn't require an additional window.

                            But I take your answer to be that you're not aware of any such features - which directly answers the question I asked. In my reading of OpenGL and from searching on the web, I found no references that suggests otherwise.

                            So I'll just stick with the extra window approach that I've been using.

                            Comment


                            • #15
                              Hey Chris(H),
                              I'm continually amazed at how darn fast the statements like BitBlt are to copy content. In my recent gbSTL I did speed tests on the code and the final BitBlt was simply not a factor in the overall rendering cycle time. The speed is so fast that even when using the much faster (than my custom code) OpenGL, BitBlt is still a non-issue regarding speed.

                              Your suggestion of using OpenGL on a rendering context then BitBlting the result over to a specified location on the dialog DC would give no practical performance hit, and would still have the advantage of not needing a separate window.

                              I'll give it a try in parallel with the dedicated window approach, just to try it out! I'm always easy to distract with something new to learn or try out!

                              Comment


                              • #16
                                Originally posted by Gary Beene View Post
                                Doug,

                                Yes, but as I mentioned, I was hoping that there was a write-within-a-bounds feature of OpenGL that I might have missed.

                                I've seen such drawing options elsewhere, even with PowerBASIC statements, where the results of drawing statements can be limited to a specified rectangle within the drawing canvas.

                                If there were such a feature, then it would be as "clean" as your suggestion to create a window and use it - more minimal actually since it doesn't require an additional window.

                                But I take your answer to be that you're not aware of any such features - which directly answers the question I asked. In my reading of OpenGL and from searching on the web, I found no references that suggests otherwise.

                                So I'll just stick with the extra window approach that I've been using.
                                Gary,

                                First of all, there are no bounds in OpenGL. There is only a center of the universe 0,0,0 in Cartesian coordinates. You place things in your world with this in mind. It is actually a PIA in openGL to ever figure out what the current viewport rectange is, in terms of window coordinates. The only thing you tell OpenGL, is your window's aspect ratio, when resizing. I know, you now this.

                                You're thinking in terms of GDI drawing. This is a different animal. And as you get further along, I think you better understand what I'm saying.

                                There are no "features" as you term it, like you suggest. You can set up an Render Context to a window DC, and there is also the ability to render to a bitmap...however, I never got that to work, and you'll find it not even necessary.

                                >>Extra window approach

                                Isn't that what I suggested?
                                "Show me a young Conservative and I'll show you someone with no heart. Show me an old Liberal and I'll show you someone with no brains." ― Winston Churchill
                                "Socialism is the philosophy of failure, the creed of ignorance and the gospel of envy." ― Winston Churchill

                                Comment


                                • #17
                                  Doug,
                                  We're clearly not communicating here.

                                  ... there are no bounds in OpenGL. You're thinking in terms of GDI drawing. This is a different animal.
                                  No, this is simply not true. GDI has no bounds either. You can draw something out to infinity but only display the portion of the image that is contained with a viewport (the size of the DC). Likewise, with OpenGL, you can limit the portion of the drawing world that is shown, to be displayed on the rendering context. The two are similar in that regard, not different as you want to insist.

                                  The mechanisms are certainly different, but not the results.

                                  I appreciate your comments and they're part of a good general discussion on OpenGL but they don't really address the question I've asked. In the OP my question was whether the rendering could be limited to a rectangle within the rendering context.

                                  It's easy enough to imagine code that would emulate the concept - draw the entire rendering context with the object centered at the rectangle of interest and scaled to the rectangle size, then draw over (with the background color) anything outside the rectangle of interest. But who would want to do that? Not me!! That's why I asked the question of whether OpenGL had a way to do it without having to brute force the solution.

                                  Another approach to consider is to do the part about moving the object where I want it, then making the background of the rendering context transparent outside the desired rectangle. I've read threads on the web where folks can make the background transparent, but I've not seen where they can do that selectively.

                                  My point is that your comments only suggest that you're not aware of any OpenGL statements which make the task easy. They don't close the door on the possibility.

                                  >>Extra window approach ... Isn't that what I suggested?
                                  Well, if you mean did you re-iterate what I suggested as the alternative in post #2, then yes.

                                  And, lastly, please remember that I was just asking a question. That's one of the fun things about programming, is to test the boundaries of what can be done. Just because there's perhaps an easier way to get something done doesn't mean I'm not interested in pursuing the alternatives. Sometimes, "better" changes over time as solutions are found for once-difficult concepts.

                                  I'd still like to figure out how to do what I asked for in the OP. I'll continue the search ...

                                  Comment


                                  • #18
                                    So, just this OpenGL statement ...

                                    Code:
                                    glViewport w/2, h/2, w/2, h
                                    does part of what I want ... puts the rendering in the upper-right area (location/size can be adjusted) ...



                                    But what it also does is render the entire window (dialog in this case), including the area of the rendering context outside of that defined by glViewPort.

                                    If it only painted the area specified by glViewPort, then I'd be home free.
                                    Last edited by Gary Beene; 23 Oct 2015, 11:15 PM.

                                    Comment


                                    • #19
                                      And, I also ran across glScissor - which clips pixel drawing on the rendering context if outside the "scissor box". Like this ...

                                      Code:
                                      glScissor w/2, h/2, w/2, h/2
                                      does this ...



                                      But, it has the same problem I mentioned in the last post - it still renders the entire surface of the rendering context with the background color.

                                      Comment


                                      • #20
                                        Originally posted by Gary Beene View Post
                                        Hey Chris(H),
                                        I'm continually amazed at how darn fast the statements like BitBlt are to copy content.
                                        Yes, and it makes a huge difference to the speed of an app if you can conserve drawing by copying more bitmaps! Or so it seems to me, working with GDI. ISTR reading that some of it is done by the GPU, so places little load on the PC's processor. But I'm not an expert, having little work with OpenGL other than drawing lines, rects and text!

                                        There is a lot of traffic on Stackoverflow concerning OpenGL and GPU use, BTW.

                                        Comment

                                        Working...
                                        X