Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Question about TBGL_DrawFrame

  1. #1

    Question Question about TBGL_DrawFrame

    For the past week I've been porting a simple Java program over to thinBasic. It's nothing impressive, it just draws an image on the screen. The pseudo code for the drawing routine looks much like the following.

    For x = 1 To %winWidth
      
      For y = 1 To %winHeight
      
      Next
      
      TBGL_DrawFrame
    
    Next
    
    I've placed TBGL_DrawFrame between the two Next commands so that the User can see the image being drawn on the screen, however as it's being drawn it flickers quite badly. The ways that I've found to overcome this are to use glDrawBuffer(%GL_FRONT_AND_BACK) or use glDrawBuffer(%GL_FRONT) and glFlush().

    Is there a TBGL way of overcoming the flickering without resorting to native OpenGL commands?
    Operating System: Windows 10 Home 64-bit
    CPU: Intel Celeron N4000 CPU @ 1.10GHz
    Memory: 4.00GB RAM
    Graphics: Intel UHD Graphics 600

  2. #2
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Hi Matthew,

    always so pleasant to see you here Please, if you can, share the code and I can check for the possible root cause of flicker.
    If you prefer to not share here at the moment, just send it at petrschreiber@thinbasic.com.


    Petr
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  3. #3
    Hi Petr don't worry the program I'm writing isn't Top Secret, I'm happy to share. :-)

    Prepare yourself for a lot of links. After reading this thread on the BASIC programming forum I was interested in finding out more about Voronoi diagrams. I ended up finding this Java program on Rosetta Code, so I thought I'd port it to different dialects of BASIC. So-far I've ported it to FreeBASIC and Basic4GL. I should add that both versions flickered just the same until I started using glDrawBuffer(%GL_FRONT_AND_BACK).

    The program is a bit slow (and uncommented) at the moment but I hope in the future to make it a bit faster by using GBuffers and Oxygen.

    Uses "TBGL"
    #INCLUDE "%app_includepath%\thinbasic_gl.inc"
    
    Randomize
    
    Dim hWnd As DWord
    
    %winWidth  = 640
    %winHeight = 480
    %winDepth  = 32
      
    hWnd = TBGL_CreateWindowEx("Voronoi diagram", %winWidth, %winHeight, %winDepth, %TBGL_WS_WINDOWED | %TBGL_WS_DONTSIZE | %TBGL_WS_CLOSEBOX)
    TBGL_ShowWindow
    
    TBGL_RenderMatrix2D ( 0, %winHeight, %winWidth, 0)  
    TBGL_BackColor 0, 0, 0, 0
    ' glDrawBuffer(%GL_FRONT_AND_BACK)
    ' glDrawBuffer(%GL_FRONT)
    
    Long sites = 10
    Long townX(sites), townY(sites)
    Long colR(sites), colG(sites), colB(sites)
    Long i, n, x, y
    Long appRunning = %FALSE
                   
    
    For i = 1 To sites
      townX(i) = Rnd(0, %winWidth)
      townY(i) = Rnd(0, %winHeight)
      colR (i) = Rnd(0, 255)
      colG (i) = Rnd(0, 255)
      colB (i) = Rnd(0, 255)
    Next
    
    
    TBGL_ResetKeyState()
    
    While TBGL_IsWindow(hWnd)
    
      TBGL_ClearFrame
            
      For x = 1 To %winWidth
      
        For y = 1 To %winHeight
          
          n = 1
          
          For i = 1 To sites
            
            If VoronoiDistance(townX(i), x, townY(i), y) < VoronoiDistance(townX(n), x, townY(n), y) Then
              n = i
            EndIf
            
          Next
          
        TBGL_BeginPoly(%GL_POINTS)
          TBGL_Color(colR(n), colG(n), colB(n))
          TBGL_Point(x, y)
        TBGL_EndPoly
        
        Next
            
      DoEvents
      
      If TBGL_GetWindowKeyOnce(hWnd, %VK_ESCAPE) Then Exit For
      TBGL_DrawFrame
      ' glFlush()
          
      Next
      
    If appRunning = %FALSE Then Exit While 
          
    Wend 
    
    TBGL_DestroyWindow
    
    Function VoronoiDistance(x1, x2, y1, y2 As Long) As Double
      Dim distance As Double
        distance = Sqr(((x1 - x2) * (x1 - x2)) + ((y1 - y2) * (y1 - y2)))
      Return distance
    End Function
    
    Operating System: Windows 10 Home 64-bit
    CPU: Intel Celeron N4000 CPU @ 1.10GHz
    Memory: 4.00GB RAM
    Graphics: Intel UHD Graphics 600

  4. #4
    not your demo matthew but the first example in http://forum.basicprogramming.org/in...ic,5127.0.html
    it produced the same shape almost instantly. its 2D inside 3D so we can rotate it (uncomment line 40)
    not optimized , i just filled Petr code about using oxygen for the math hard task and Gbuffers to store the arrays here http://www.thinbasic.com/community/s...2365#post92365
    the most important lines is:
    Dim oVertexA() At #VertexA As TBGL_TVECTOR3F
    Dim oColorA() At #ColorA As TBGL_TRGB


    since it connects the arrays oVertexA to arrays VertexA, it seems oVertexA dimensioned as necessary.
    the arrays is linear but we project the 2D point in the above page to 1D like this:
    ind = (yy-1)*640 + xx
    oVertexA(ind).x = xx

    voronoi.PNG

    Uses "TBGL", "math", "Oxygen"
     
    Function TBMain()
      Local hWnd      As DWord
      Local FrameRate As Double
        
      ' -- Create and show window
      hWnd = TBGL_CreateWindowEx("Plotting 3D Data in an array using GBuffers- Calculate with Oxygen JIT ..Esc to quit", 600, 600, 32, %TBGL_WS_WINDOWED Or %TBGL_WS_CLOSEBOX) 
      TBGL_ShowWindow 
        
      TBGL_BackColor 255,255,255 
    
      ' -- Create 3D points buffer
      DWord gbPoints = TBGL_GBufferCreate(%TBGL_POINTS, %TBGL_3D)
        
      Global Nb As DWord = 1000000
     
      ' -- Define data for it
      Global VertexA(Nb) As TBGL_TVECTOR3F ' single
      Global ColorA(Nb)  As TBGL_TRGB      ' Byte
      
      FillArrays()
      
      ' -- Create buffer dynamically linked to the arrays above
      TBGL_GBufferDefineFromArray(gbPoints, %TBGL_DYNAMIC, CountOf(VertexA), VertexA(1), ColorA(1))
       
      ' -- Resets status of all keys 
      TBGL_ResetKeyState()
      'TBGL_PointSize 2
       
      ' -- Main loop
      While TBGL_IsWindow(hWnd)
      'init 
        FrameRate = TBGL_GetFrameRate
         
        TBGL_ClearFrame
          TBGL_Camera(0, 0, 40, 0, 0, 0)
            
          ' -- Turn triangle
          'TBGL_Rotate GetTickCount/50, 0, 1, 0
          TBGL_Scale 0.045, 0.045, 1
          TBGL_Translate -320, -320
                                          
          ' -- Render it                              
          TBGL_GBufferRender(gbPoints)   
             
        TBGL_DrawFrame
      
        ' -- ESCAPE key to exit application
        If TBGL_GetWindowKeyState(hWnd, %VK_ESCAPE) Then Exit While
      
      Wend       
      ' -- Destroying the buffer is not necessary,
      ' -- the garbage collector will take care of it
      
      ' -- Destroy window
      TBGL_DestroyWindow
    End Function  
     
    Function FillArrays()
     
      String src = "
      basic
       
      ' -- Re-declare types
      Type TBGL_TRGB
        r As Byte
        g As Byte
        b As Byte
      End Type
       
      Type TBGL_TVECTOR3F
        x As Single
        y As Single
        z As Single
      End Type
      
      
      'RANDOMISER
      '==========
      '
      Dim seed As Long=0x12345678
      '
      Function Rnd() As Single  'this is from oxygen examples in thinbasic folder
        '
        Static As Single f, d=1/0x7fffffff
        mov eax,seed
        rol eax,7
        imul eax,eax,13
        mov seed,eax
        push eax
        fild DWord [esp]
        ADD esp,4
        fmul DWord d
        fstp DWord f
        Function=f
      End Function
         
      ' -- Link variables  
      Dim oVertexA() At #VertexA As TBGL_TVECTOR3F
      Dim oColorA() At #ColorA As TBGL_TRGB
    Single g
    Long i
    
    Integer sq=640: Single s2 = sq/2  
    
    #def points 240 
    Dim x(points) as single
    Dim y(points) as single
    dim kl(points) as TBGL_TRGB
    
    For i = 1 To points
      x(i)=abs(Rnd()*sq): y(i)=abs(Rnd()*sq)
      g=127-127*(Abs(s2-x(i))/s2)+127-127*(Abs(s2-y(i))/s2)
      kl(i).r=255-x(i)/sq*255
      kl(i).g = g
      kl(i).b = y(i)/(sq*255)
    Next
      
    
      Single a, b, q
      Long xx, yy, d , kkl, i
      For xx = 1 To sq
       For yy = 1 To sq
          d = 307201
          For i = 1 To points
             a=x(i)-xx: b=y(i)-yy
             q=a*a+b*b
             If q < d Then d = q: kkl = i
          Next i
          ind = (yy-1)*640 + xx
          oVertexA(ind).x = xx
          oVertexA(ind).y = yy
          oVertexA(ind).z = 0
          oColorA(ind).r = kl(kkl).r
          oColorA(ind).g = kl(kkl).g
          oColorA(ind).b = kl(kkl).b
          'oColorA(i).r = 255:oColorA(i).g=0: oColorA(i).b=0
          'pset xx,yy,kl(kkl)
       Next yy
    Next xx 
         
      terminate    
      "        
       
      ' -- Pass the source
      O2_Asmo src
       
      ' -- Check for errors
      If Len(o2_error) Then
        MsgBox 0, o2_error : Stop
      End If              
       
      ' -- Execute
      o2_exec
     
    End Function
    
    Last edited by primo; 29-11-2015 at 20:51. Reason: correcting code, and adding picture

  5. #5
    Very impressive. :-)
    Operating System: Windows 10 Home 64-bit
    CPU: Intel Celeron N4000 CPU @ 1.10GHz
    Memory: 4.00GB RAM
    Graphics: Intel UHD Graphics 600

  6. #6
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Matthew,

    as I understand it, your original example basically needed something like single buffer, something to have image visible immediately. I... I am sorry, but I do not think single buffering should still exist in 21st century *
    But of course, I want you to enable you to do what you need. So... what about thinking about the problem differentely? What about having a canvas under your control?

    It is an approach I learned to use, and maybe you will like it too. For canvas, you can use memory bitmap. That is persistent. And then map it on quad.
    And yes, one more tip. You don't need to define VoronoiDistance, thinBasic has it covered with optimized Dist function!:
    Uses "TBGL"
     
    Randomize
     
    %winWidth  = 640
    %winHeight = 480
    %winDepth  = 32
       
    DWord hWnd = TBGL_CreateWindowEx("Voronoi diagram", %winWidth, %winHeight, %winDepth, %TBGL_WS_WINDOWED | %TBGL_WS_DONTSIZE | %TBGL_WS_CLOSEBOX)
    TBGL_ShowWindow
     
    TBGL_RenderMatrix2D ( 0, %winHeight, %winWidth, 0)  
    TBGL_BackColor 0, 0, 0, 0
              
    Long sites = 10
    Long townX(sites), townY(sites)
    Long colR(sites), colG(sites), colB(sites)
    Long i, n, x, y
             
    For i = 1 To sites
      townX(i) = Rnd(0, %winWidth)
      townY(i) = Rnd(0, %winHeight)
      colR (i) = Rnd(0, 255)
      colG (i) = Rnd(0, 255)
      colB (i) = Rnd(0, 255)
    Next        
     
    TBGL_ResetKeyState()       
    
    ' -- Canvas built as black
    String drawingCanvas = Repeat$(%winWidth*%winHeight, Chr$(0, 0, 0, 255))
    
    ' -- Now we overlay a easy to handle array over
    Dim pixelOverlay(%winWidth, %winHeight) As TBGL_TRGBA At StrPtr(drawingCanvas)
    
    Long xStep = 5 ' -- How much lines at time?
    Long lastX = 1 ' -- Memory for x
     
    While TBGL_IsWindow(hWnd)
     
      TBGL_ClearFrame
    
        For x = lastX To Min(lastX+xStep, %winWidth)
          
          For y = 1 To %winHeight       
            n = 1                       
            For i = 1 To sites            
              If Dist(townX(i), townY(i), x, y) < Dist(townX(n), townY(n), x, y) Then
                n = i
              EndIf                       
            Next
    
            ' -- Writing bitmap like a thinBasic boss        
            With pixelOverlay(x, y)
              .r = colR(n)
              .g = colG(n)
              .b = colB(n)
            End With  
           
          Next
          
          If TBGL_GetWindowKeyOnce(hWnd, %VK_ESCAPE) Then Exit While
          TBGL_MakeTexture drawingCanvas, %TBGL_DATA_RGBA, %winWidth, %winHeight, 1, %TBGL_TEX_NEAREST
        Next
        lastX = x          
                 
        TBGL_PushState %TBGL_TEXTURING
          TBGL_BindTexture 1
          TBGL_BeginPoly %GL_QUADS
            TBGL_TexCoord2D 0, 0 : TBGL_Vertex         0, 0
            TBGL_TexCoord2D 1, 0 : TBGL_Vertex %winWidth, 0
            TBGL_TexCoord2D 1, 1 : TBGL_Vertex %winWidth, %winHeight
            TBGL_TexCoord2D 0, 1 : TBGL_Vertex         0, %winHeight
          TBGL_EndPoly
        TBGL_PopState
        
        If TBGL_GetWindowKeyOnce(hWnd, %VK_ESCAPE) Then Exit While
        
      TBGL_DrawFrame
           
    Wend
     
    TBGL_DestroyWindow
    
    Of course, this example does not reach the performance of Primo's Oxy accelerated solution, as it uses pure parsing, but it could be further combined with oxygen to reach optimum performance.


    Petr

    * I will give a thought to enabling single buffering in TBGL
    Last edited by Petr Schreiber; 30-11-2015 at 21:57.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  7. #7
    I still do a lot of my programming in Basic4GL which isn't too fast when it comes to creating Fractals and similar mathematical drawing so I usually just draw straight to the front buffer using glDrawBuffer(GL_FRONT) and glFlush() as it's a little faster than swapping buffers which I feel is a waste when nothing's actually moving on the screen.

    Your method of drawing onto a Quad is something else I was thinking of doing in Basic4GL using glTexSubImage2D, I didn't even know that thinBasic had a Dist function built-in so thanks for that.

    Why don't you like single-buffering? :-) I've always found it useful for getting quick results for some programs.
    Operating System: Windows 10 Home 64-bit
    CPU: Intel Celeron N4000 CPU @ 1.10GHz
    Memory: 4.00GB RAM
    Graphics: Intel UHD Graphics 600

  8. #8
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Hehe,

    good question. Maybe I think that single buffer and GPU graphics don't go much together, as the main benefit -performance- is usually lost and/or you are using it for per pixel operations, while GPU graphics are shining most when working at vector level.

    See this GPU-less example
    (And guess what, Canvas can be used in double buffer mode too)
    Uses "UI"
       
    Randomize
       
    %winWidth  = 640
    %winHeight = 480
    %winDepth  = 32
         
    DWord hWnd = Canvas_Window("Voronoi diagram", 100, 100,%winWidth, %winHeight)
    Canvas_Attach(hWnd, 0)
                
    Long sites = 10
    Long townX(sites), townY(sites)
    Long colR(sites), colG(sites), colB(sites)
    Long i, n, x, y
               
    For i = 1 To sites
      townX(i) = Rnd(0, %winWidth)
      townY(i) = Rnd(0, %winHeight)
      colR (i) = Rnd(0, 255)
      colG (i) = Rnd(0, 255)
      colB (i) = Rnd(0, 255)
    Next      
       
    While IsWindow(hWnd)
       
        For x = 0 To %winWidth
            
          For y = 0 To %winHeight       
            n = 1                       
            For i = 1 To sites            
              If Dist(townX(i), townY(i), x, y) < Dist(townX(n), townY(n), x, y) Then
                n = i
              EndIf                     
            Next
     
            Canvas_SetPixel(x, y, Rgb(colR(n), colG(n), colB(n)))
             
          Next
            
          If Asc(Canvas_Inkey) = 27 Then Exit While
           
        Next
             
        If Asc(Canvas_Inkey) = 27 Then Exit While
             
    Wend
    

    Petr
    Last edited by Petr Schreiber; 06-12-2015 at 10:42.
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

  9. #9
    thinBasic author ErosOlmi's Avatar
    Join Date
    Sep 2004
    Location
    Milan - Italy
    Age
    57
    Posts
    8,777
    Rep Power
    10
    Please do not use infinite loops otherwise script will continue to run (as a process) even if the main window is closed.

    Correct loop would be something like:
    While IsWindow(hWnd)
    ...
    Wend
    
    In this way, when the hWnd window will be closed the script will stop execution.

    Ciao
    Eros
    Last edited by ErosOlmi; 06-12-2015 at 10:44.
    www.thinbasic.com | www.thinbasic.com/community/ | help.thinbasic.com
    Windows 10 Pro for Workstations 64bit - 32 GB - Intel(R) Xeon(R) W-10855M CPU @ 2.80GHz - NVIDIA Quadro RTX 3000

  10. #10
    Super Moderator Petr Schreiber's Avatar
    Join Date
    Aug 2005
    Location
    Brno - Czech Republic
    Posts
    7,128
    Rep Power
    732
    Fixed, nice catch
    Learn 3D graphics with ThinBASIC, learn TBGL!
    Windows 10 64bit - Intel Core i5-3350P @ 3.1GHz - 16 GB RAM - NVIDIA GeForce GTX 1050 Ti 4GB

Page 1 of 2 12 LastLast

Similar Threads

  1. Question of the day ;)
    By Petr Schreiber in forum thinBasic General
    Replies: 8
    Last Post: 23-08-2010, 19:58
  2. C to TB question
    By Michael Clease in forum Other languages
    Replies: 2
    Last Post: 03-06-2010, 12:11
  3. gdi question
    By Lionheart008 in forum UI (User Interface)
    Replies: 6
    Last Post: 07-12-2009, 19:31
  4. UDT question
    By sandyrepope in forum thinBasic General
    Replies: 3
    Last Post: 18-02-2008, 22:33
  5. m15 question
    By kryton9 in forum M15 file format
    Replies: 4
    Last Post: 20-06-2007, 20:18

Members who have read this thread: 0

There are no members to list at the moment.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •