It is currently Sun Sep 27, 2020 10:20 am

All times are UTC + 1 hour




Post new topic Reply to topic  [ 48 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: Gaussian blur in real time?
PostPosted: Thu Oct 17, 2019 12:39 pm 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 403
Location: France
Confirm, GPU. Maybe it's just me then. Right now, I'm refactoring, I'll check that later (maybe it's the GrabSprite() part then?).


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Thu Oct 17, 2019 1:02 pm 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 727
Joubarbe wrote:
Wow man, how much do I owe you? :)

Impressive results.

Code:
      Static sprite_tmp.i,
             *buffer
      If IsSprite(sprite_tmp) : FreeSprite(sprite_tmp) : EndIf
      sprite_tmp = GrabSprite(#PB_Any, 100, 100, 800, 800)
      StartDrawing(SpriteOutput(sprite_tmp))
      *buffer = DrawingBuffer()
      DirectionalBlur::BlurPixelBuf32(*buffer, OutputWidth(), OutputHeight(), 10, DirectionalBlur::#Blur_Full)
      StopDrawing()
      DisplaySprite(sprite_tmp, 100, 100)


At 800x800, your DirectionalBlur costs me 2 FPS with #Blur_Full, which is great. However, GrabSprite() is a lot more expensive than I thought. 15 FPS in that case (800x800).

The strength option doesn't seem to cost more at 30.
I'm not sure how exactly the LineStride option works. Putting random values is fun :)

But yeah, again, the following is the most expensive:

Code:
      Static sprite_tmp.i,
             *buffer
      If IsSprite(sprite_tmp) : FreeSprite(sprite_tmp) : EndIf
      sprite_tmp = GrabSprite(#PB_Any, 100, 100, 800, 800)
      DisplaySprite(sprite_tmp, 100, 100)


I'm pretty sure that I should be doing something else :)


I dont get why you would use GrabSprite (in a loop) just to blur it - why cant you use the backbuffer directly?
Would be a lot faster.


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Thu Oct 17, 2019 1:18 pm 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 403
Location: France
https://www.purebasic.com/documentation ... uffer.html

Quote:
Once StopDrawing() has been called, the buffer is invalidated and can no more be used.

How do you mean? Am I not supposed to use a StartDrawing() block at some point? Meaning if I don't grab a sprite, I must use ScreenOutput(), and this is even slower.

EDIT: @wilbert: High GPU comes from GrabSprite(). My bad!


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Thu Oct 17, 2019 4:22 pm 
Offline
Addict
Addict

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 1251
Location: right here
I tried with threading.
Change mode by key 0-5.
Mode 0-4 only measures but doesn't blur. Mode 5 does blur by actually using the thread.
In proc() you can change manually what blur (or combination and repetition) is used.
GrabSprite() as well as CopyMemory() are very slow on my Windows 10 per default (DirectX9 I guess), ~160ms. But with subsystem OpenGL they are quite fast with ~8ms for GrabSprite() and ~1ms for 3 x CopyMemory().

The bottom line is that you have some overhead due to the screen drawing block and the CopyMemory but if you find a blur function that takes less time than you main loop (including the drawing block) then the thread won't drag the frame time any further. If the thread takes longer then the main loop has to wait, dragging the frame time to match the thread time.

The 2 semaphores manage that the main loop and the thread can run in parallel but don't overtake each other, i.e. they always alternate and wait for each other to finish. They also protect the data accessed by both main and thread.
Code:
CompilerIf #PB_Compiler_Debugger
  If MessageRequester("debugger?", "the debugger is enabled. run anyway?", #PB_MessageRequester_YesNo) = #PB_MessageRequester_No
    End
  EndIf
CompilerEndIf

CompilerIf Not #PB_Compiler_Thread
  CompilerError "please enable threadsafe compiler option."
CompilerEndIf


EnableExplicit

#ScreenWidth  = 800
#ScreenHeight = 600
;#ScreenWidth  = 1024
;#ScreenHeight = 768
;#ScreenWidth  = 1680
;#ScreenHeight = 1050

InitSprite()
InitKeyboard()
InitMouse()
ElapsedMilliseconds()

Structure Pixel
  r.a
  g.a
  b.a
EndStructure

Define win, quit, mode, mode$
Define spr, i
Define sprFR, FR, FRt, FR$
Define time, timeTmp

win = OpenWindow(#PB_Any, 0, 0, #ScreenWidth, #ScreenHeight, "window")
OpenWindowedScreen(WindowID(win), 0, 0, #ScreenWidth, #ScreenHeight, 0, 0, 0, #PB_Screen_NoSynchronization)
SetFrameRate(999)

UsePNGImageDecoder()
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  Define spr = LoadSprite(#PB_Any, #PB_Compiler_Home + "examples/3D/Data/PureBasic3DLogo.png") ; windows
CompilerElse
  Define spr = LoadSprite(#PB_Any, #PB_Compiler_Home + "examples/3d/Data/PureBasic3DLogo.png") ; linux
CompilerEndIf

CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  Define font = LoadFont(#PB_Any, "courier new", 10)
CompilerElse
  Define font = LoadFont(#PB_Any, "monospace", 10)
CompilerEndIf

; ------------------------------------------------------------

sprFR = CreateSprite(#PB_Any, 400, 80)

mode = 5

; ------------------------------------------------------------

Procedure blur_a(xStart, yStart, xEnd, yEnd, buffer, pitch, pixelSize, neighborDistance)
  Protected x, y
  Protected *pixel1.Pixel
  Protected *pixel2lef.Pixel
  Protected *pixel2rig.Pixel
  Protected *pixel2top.Pixel
  Protected *pixel2bot.Pixel
 
  For y = yStart To yEnd
    For x = xStart To xEnd
     
      *pixel1    = buffer + ((y                 ) * pitch) + ((x                 ) * pixelSize)
     
      *pixel2lef = buffer + ((y                 ) * pitch) + ((x-neighborDistance) * pixelSize)
      *pixel2rig = buffer + ((y                 ) * pitch) + ((x+neighborDistance) * pixelSize)
      *pixel2top = buffer + ((y-neighborDistance) * pitch) + ((x                 ) * pixelSize)
      *pixel2bot = buffer + ((y+neighborDistance) * pitch) + ((x                 ) * pixelSize)
     
      *pixel1\r = (*pixel1\r + *pixel2lef\r + *pixel2rig\r + *pixel2top\r + *pixel2bot\r) / 5.0
      *pixel1\g = (*pixel1\g + *pixel2lef\g + *pixel2rig\g + *pixel2top\g + *pixel2bot\g) / 5.0
      *pixel1\b = (*pixel1\b + *pixel2lef\b + *pixel2rig\b + *pixel2top\b + *pixel2bot\b) / 5.0
    Next
  Next
EndProcedure

Procedure blur_b(xStart, yStart, xEnd, yEnd, buffer, pitch, pixelSize)
  Protected x, y
  Protected *pixel1.Pixel
  Protected *pixel2_1.Pixel
  Protected *pixel2_2.Pixel
  Protected *pixel2_3.Pixel
  Protected *pixel2_4.Pixel
  Protected *pixel2_5.Pixel
  Protected *pixel2_6.Pixel
  Protected *pixel2_7.Pixel
  Protected *pixel2_8.Pixel
 
  For y = yStart To yEnd
    For x = xStart To xEnd
     
      *pixel1   = buffer + ((y  ) * pitch) + ((x  ) * pixelSize)
     
      *pixel2_1 = buffer + ((y-3) * pitch) + ((x+1) * pixelSize)
      *pixel2_2 = buffer + ((y-1) * pitch) + ((x+3) * pixelSize)
      *pixel2_3 = buffer + ((y+1) * pitch) + ((x+3) * pixelSize)
      *pixel2_4 = buffer + ((y+3) * pitch) + ((x+1) * pixelSize)
      *pixel2_5 = buffer + ((y+3) * pitch) + ((x-1) * pixelSize)
      *pixel2_6 = buffer + ((y+1) * pitch) + ((x-3) * pixelSize)
      *pixel2_7 = buffer + ((y-1) * pitch) + ((x-3) * pixelSize)
      *pixel2_8 = buffer + ((y-3) * pitch) + ((x-1) * pixelSize)
     
      *pixel1\r = (*pixel2_1\r + *pixel2_2\r + *pixel2_3\r + *pixel2_4\r + *pixel2_5\r + *pixel2_6\r + *pixel2_7\r + *pixel2_8\r) / 8.0
      *pixel1\g = (*pixel2_1\g + *pixel2_2\g + *pixel2_3\g + *pixel2_4\g + *pixel2_5\g + *pixel2_6\g + *pixel2_7\g + *pixel2_8\g) / 8.0
      *pixel1\b = (*pixel2_1\b + *pixel2_2\b + *pixel2_3\b + *pixel2_4\b + *pixel2_5\b + *pixel2_6\b + *pixel2_7\b + *pixel2_8\b) / 8.0
    Next
  Next
EndProcedure

Procedure blur_c(xStart, yStart, xEnd, yEnd, buffer, pitch, pixelSize);, buffer2)
  Protected x, y
  Protected *pixel1.Pixel
  Protected *pixel2lef.Pixel
  Protected *pixel2rig.Pixel
  Protected *pixel2top.Pixel
  Protected *pixel2bot.Pixel
 
  ;CopyMemory(buffer, buffer2, OutputHeight() * pitch)
  Protected buffer2
  buffer2 = buffer
 
  Define n
  For n = 1 To 4
    For y = yStart To yEnd
      For x = xStart To xEnd
       
        *pixel1    = buffer  + ((y  ) * pitch) + ((x  ) * pixelSize)
       
        *pixel2lef = buffer2 + ((y  ) * pitch) + ((x-n) * pixelSize)
        *pixel2rig = buffer2 + ((y  ) * pitch) + ((x+n) * pixelSize)
        *pixel2top = buffer2 + ((y-n) * pitch) + ((x  ) * pixelSize)
        *pixel2bot = buffer2 + ((y+n) * pitch) + ((x  ) * pixelSize)
       
        *pixel1\r = (*pixel2lef\r + *pixel2rig\r + *pixel2top\r + *pixel2bot\r) / 4.0
        *pixel1\g = (*pixel2lef\g + *pixel2rig\g + *pixel2top\g + *pixel2bot\g) / 4.0
        *pixel1\b = (*pixel2lef\b + *pixel2rig\b + *pixel2top\b + *pixel2bot\b) / 4.0
      Next
    Next
  Next
EndProcedure

Procedure blur_d(xStart, yStart, xEnd, yEnd, buffer, pitch, pixelSize, neighborDistance)
  Protected x, y
  Protected *pixel1.Pixel
  Protected *pixel2lef.Pixel
  Protected *pixel2rig.Pixel
 
  For y = yStart To yEnd
    For x = xStart To xEnd
     
      *pixel1    = buffer + ((y                 ) * pitch) + ((x                 ) * pixelSize)
     
      *pixel2lef = buffer + ((y                 ) * pitch) + ((x-neighborDistance) * pixelSize)
      *pixel2rig = buffer + ((y                 ) * pitch) + ((x+neighborDistance) * pixelSize)
     
;       *pixel1\r = (*pixel1\r + *pixel2lef\r + *pixel2rig\r) / 3.0
;       *pixel1\g = (*pixel1\g + *pixel2lef\g + *pixel2rig\g) / 3.0
;       *pixel1\b = (*pixel1\b + *pixel2lef\b + *pixel2rig\b) / 3.0
      *pixel1\r = (*pixel2lef\r + *pixel2rig\r) / 2.0
      *pixel1\g = (*pixel2lef\g + *pixel2rig\g) / 2.0
      *pixel1\b = (*pixel2lef\b + *pixel2rig\b) / 2.0
    Next
  Next
EndProcedure

; ------------------------------------------------------------

Define buffer2
Define bufferTmp

Define yStart
Define yEnd
Define xStart
Define xEnd

; ------------------------------------------------------------

Define semaphoreThread = CreateSemaphore()
Define semaphoreMain   = CreateSemaphore(1)

Enumeration #PB_Event_FirstCustomValue
  #eventThreadTimeNotify
EndEnumeration

Structure s_threadInfo
  buffer.i
  pitch.i
  pixelSize.i
  yStart.i
  yEnd.i
  xStart.i
  xEnd.i
  quitThread.i
EndStructure

Procedure proc(*threadInfo.s_threadInfo)
  Shared semaphoreThread
  Shared semaphoreMain
  Protected n
  Protected nMax
  Protected time
  Protected dist
  Protected quitThread
  Repeat
    WaitSemaphore(semaphoreThread) ;>
     
      time = ElapsedMilliseconds()
     
      If *threadInfo\buffer
       
        ; repeat
        nMax = 1
       
        For n=1 To nMax
         
          ; 4 neighbors of distance d
          dist = 2
          blur_a(*threadInfo\xStart, *threadInfo\yStart, *threadInfo\xEnd, *threadInfo\yEnd, *threadInfo\buffer, *threadInfo\pitch, *threadInfo\pixelSize, dist)
         
          ; 4 neighbors of distance d
          ;dist = 4
          ;blur_a(*threadInfo\xStart, *threadInfo\yStart, *threadInfo\xEnd, *threadInfo\yEnd, *threadInfo\buffer, *threadInfo\pitch, *threadInfo\pixelSize, dist)
         
          ; 8 neighbors
          ;blur_b(*threadInfo\xStart, *threadInfo\yStart, *threadInfo\xEnd, *threadInfo\yEnd, *threadInfo\buffer, *threadInfo\pitch, *threadInfo\pixelSize)
         
          ; 4 neighbors * multiple distance 1-4
          ;blur_c(*threadInfo\xStart, *threadInfo\yStart, *threadInfo\xEnd, *threadInfo\yEnd, *threadInfo\buffer, *threadInfo\pitch, *threadInfo\pixelSize)
         
          ; 2 neighbors of distance d
          ;dist = 3
          ;blur_d(*threadInfo\xStart, *threadInfo\yStart, *threadInfo\xEnd, *threadInfo\yEnd, *threadInfo\buffer, *threadInfo\pitch, *threadInfo\pixelSize, dist)         
        Next
       
      EndIf
     
      time = ElapsedMilliseconds() - time
      PostEvent(#eventThreadTimeNotify, 0, 0, 0, time)
     
      If *threadInfo\quitThread
        quitThread = #True
      EndIf
    SignalSemaphore(semaphoreMain) ;<
   
  Until quitThread
EndProcedure

Define threadInfo.s_threadInfo
Define thread = CreateThread(@proc(), @ threadInfo)
Define threadTime

; ------------------------------------------------------------


Repeat
  ExamineMouse()
  ExamineKeyboard()
 
  If KeyboardPushed(#PB_Key_Escape) : quit = #True : EndIf
  If KeyboardPushed(#PB_Key_0) : mode = 0 : EndIf
  If KeyboardPushed(#PB_Key_1) : mode = 1 : EndIf
  If KeyboardPushed(#PB_Key_2) : mode = 2 : EndIf
  If KeyboardPushed(#PB_Key_3) : mode = 3 : EndIf
  If KeyboardPushed(#PB_Key_4) : mode = 4 : EndIf
  If KeyboardPushed(#PB_Key_5) : mode = 5 : EndIf
 
  While WindowEvent()
    Select Event()
      Case #PB_Event_CloseWindow
        quit = #True
      Case #eventThreadTimeNotify
        threadTime = EventData()
    EndSelect
  Wend
 
  FR + 1
  If ElapsedMilliseconds() > FRt
    time / FR
   
    Select mode
      Case 0 : mode$ = "no screen drawing block"
      Case 1 : mode$ = "only GrabSprite()"
      Case 2 : mode$ = "empty screen drawing block"
      Case 3 : mode$ = "base"
      Case 4 : mode$ = "base + copy"
      Case 5 : mode$ = "base + copy / thread"
    EndSelect
   
    FRt = ElapsedMilliseconds() + 500
    FR$ = "fps:" + Str(FR * 2)
    FR = 0
    StartDrawing(SpriteOutput(sprFR))
      DrawingMode(#PB_2DDrawing_Transparent)
      Box(0, 0, OutputWidth(), OutputHeight(), $0)
      DrawingFont(FontID(font))
      DrawText(0, 0, FR$)
      DrawText(0, 20, "mode: " + mode + " (" + mode$ + ")")
      DrawText(0, 40, "frame time: " + time + "ms")
      If mode >= 5
        DrawText(0, 60, "thread time: " + threadTime + "ms")
      EndIf
    StopDrawing()
  EndIf
 
  ClearScreen($333333)
 
  DisplayTransparentSprite(spr, MouseX(), MouseY())
 
 
  If mode = 0
   
    ; no screen drawing block
   
  ElseIf mode = 1
   
    ; test GrabSprite()
   
    Define sprScreen
    If sprScreen
      FreeSprite(sprScreen)
      sprScreen = 0
    EndIf
    sprScreen = GrabSprite(#PB_Any, 0, 0, #ScreenWidth, #ScreenHeight, #PB_Sprite_AlphaBlending)
    ;GrabSprite(0, 0, 0, #ScreenWidth, #ScreenHeight, #PB_Sprite_AlphaBlending)
   
  ElseIf mode >= 2
   
    ; empty screen drawing block
   
    If StartDrawing(ScreenOutput())
     
      If mode >= 3
       
        ; base
       
        Define buffer      = DrawingBuffer()
        Define pitch       = DrawingBufferPitch()
        Define pixelFormat = DrawingBufferPixelFormat()
        Define pixelSize
  ;       Debug pixelFormat
  ;       Debug pixelFormat!#PB_PixelFormat_ReversedY
  ;       Debug #PB_PixelFormat_24Bits_RGB
  ;       Debug #PB_PixelFormat_32Bits_BGR
  ;       End
        If pixelFormat & (#PB_PixelFormat_24Bits_BGR | #PB_PixelFormat_24Bits_RGB)
          pixelSize = 3
        ElseIf pixelFormat & (#PB_PixelFormat_32Bits_BGR | #PB_PixelFormat_32Bits_RGB)
          pixelSize = 4
        Else
          WaitSemaphore(semaphoreMain) ;>
            threadInfo\quitThread = #True
          SignalSemaphore(semaphoreThread) ;<
          WaitThread(thread)
          CloseScreen()
          CloseWindow(win)
          MessageRequester("error", "pixel format not supported")
          End
        EndIf
        If pixelSize
         
          ;yStart = #ScreenHeight * 0.25
          ;yEnd   = #ScreenHeight * 0.75
          ;xStart = #ScreenWidth  * 0.25
          ;xEnd   = #ScreenWidth  * 0.75
          yStart = #ScreenHeight * 0.1
          yEnd   = #ScreenHeight * 0.9
          xStart = #ScreenWidth  * 0.1
          xEnd   = #ScreenWidth  * 0.9
         
          DrawingMode(#PB_2DDrawing_Outlined)
          Box(xStart - 20, yStart - 20, xEnd - xStart + 40, yEnd - yStart + 40, $ff00ff00)
         
          If Not buffer2
            buffer2 = AllocateMemory(pitch * OutputHeight())
          EndIf
          If Not bufferTmp
            bufferTmp = AllocateMemory(pitch * OutputHeight())
          EndIf
         
          If mode >= 4
           
            ; copy / thread
           
            WaitSemaphore(semaphoreMain) ;>
             
              CopyMemory(buffer, bufferTmp, OutputHeight() * pitch)
             
              CopyMemory(buffer2, buffer, OutputHeight() * pitch)
             
              CopyMemory(bufferTmp, buffer2, OutputHeight() * pitch)
             
              threadInfo\buffer = buffer2
              threadInfo\pitch = pitch
              threadInfo\pixelSize = pixelSize
              threadInfo\yStart = yStart
              threadInfo\yEnd   = yEnd
              threadInfo\xStart = xStart
              threadInfo\xEnd   = xEnd
             
            If mode >= 5
            SignalSemaphore(semaphoreThread) ;<
            Else
            SignalSemaphore(semaphoreMain) ;<
            EndIf
           
            ;Delay(6)
           
          EndIf
         
        EndIf
      EndIf
     
      StopDrawing()
    EndIf
  EndIf
 
  time = time + (ElapsedMilliseconds() - timeTmp)
  timeTmp = ElapsedMilliseconds()
 
  DisplaySprite(sprFR, MouseX(), MouseY() + 80)
 
  FlipBuffers()
 
Until quit

WaitSemaphore(semaphoreMain) ;>
  threadInfo\quitThread = #True
SignalSemaphore(semaphoreThread) ;<
WaitThread(thread)



Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Fri Oct 18, 2019 9:13 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 727
Drawing to the backbuffer is not slow (just access it once)!

I did some testing and used the excellent DirectionalBlur (BlurRect) from wilbert (i only modified it to have it as single function).
With a full hd screen blurring 3-4 areas (800x800) or the whole screen costs only 1-2 ms.

Thats rly fast imho.


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Fri Oct 18, 2019 11:29 am 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 403
Location: France
Could you post your part of the code where you draw to the backbuffer? I'm not sure to follow. (Don't need the directional blur functions)


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Fri Oct 18, 2019 12:34 pm 
Offline
User
User

Joined: Thu Jan 31, 2019 12:59 am
Posts: 91
Image

https://www.dropbox.com/s/fjizfurnprr70a3/BLUREXAMPLE_DEMO.zip?dl=0


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Fri Oct 18, 2019 1:02 pm 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 403
Location: France
Image

That's a blur :)
Your technique gives "fuzzy", not blur. And displaying multiple sprites is generally a thing you don't want to do if you need interaction with it.


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Fri Oct 18, 2019 8:33 pm 
Offline
User
User

Joined: Thu Jan 31, 2019 12:59 am
Posts: 91
:mrgreen: :mrgreen: :mrgreen: :mrgreen:

I see :oops:


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Mon Oct 21, 2019 6:49 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 727
Joubarbe wrote:
Could you post your part of the code where you draw to the backbuffer? I'm not sure to follow. (Don't need the directional blur functions)


I posted one of the functions in wilberts directional blur thread.


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Mon Oct 21, 2019 7:58 am 
Offline
Addict
Addict

Joined: Thu Aug 30, 2007 11:54 pm
Posts: 1251
Location: right here
To my knowledge you always operate on the back buffer. DisplaySprite and screen drawing etc. always work on the back buffer. Flipbuffer() makes it the front buffer and the previous front buffer becomes the back buffer to work on.


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Mon Oct 21, 2019 8:38 am 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 403
Location: France
To explain a bit better my question, I would have thought that in PB, it was possible to catch the buffer before the main loop:

Code:
StartDrawing(ScreenOutput())
DrawingBuffer()
*screen_buffer = AllocateMemory(DrawingBufferPitch() * OutputHeight())
CopyMemory(DrawingBuffer(), *screen_buffer, DrawingBufferPitch() * OutputHeight())
StopDrawing()
; ... Or just "*screen_buffer = DrawingBuffer()", I guess.

Then, use the Blur function:

Code:
Repeat
...
DirectionalBlur::BlurPixelBuf32(*screen_buffer, 200, 200, 10, DirectionalBlur::#Blur_Full)
...
FlipBuffer()
ForEver

But there must be something I don't get, because this obviously doesn't work. Nothing get blurred, even though the CPU is working.
And again, both StartDrawing(ScreenOutput()) and GrabSprite() are slow in real time. And the goal is to have an animated background blurred as a GUI background.

EDIT: The best I have right now is to blur a small part of the screen with GrabSprite() (inside the main loop):
Code:
      If IsSprite(sprite_tmp) : FreeSprite(sprite_tmp) : EndIf
      sprite_tmp = GrabSprite(#PB_Any, 100, 100, 200, 200, #PB_Sprite_AlphaBlending)
      StartDrawing(SpriteOutput(sprite_tmp))
      DirectionalBlur::BlurPixelBuf32(DrawingBuffer(), OutputWidth(), OutputHeight(), 10, DirectionalBlur::#Blur_Full)
      StopDrawing()
      DisplayTransparentSprite(sprite_tmp, 100, 100)

At this size, GrabSprite() is not expensive.

EDIT2: Same with your code @Mijikai, why does the following doesn't work?

Code:
DirectionalBlur::BlurSurface(*screen_buffer, *screen_buffer_pitch, 0, 0, 800, 800)

(main loop)


Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Mon Oct 21, 2019 9:00 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 727
Aquire access to the backbuffer once every frame and then do all the work you need.

Code:
;...
    If StartDrawing(ScreenOutput())
     
      *pixel = DrawingBuffer()
      pitch = DrawingBufferPitch()
     
      ;       BlurSurface(*pixel,pitch,100,100,800,800,20)
      ;       BlurSurface(*pixel,pitch,300,300,800,800,20)
      ;       BlurSurface(*pixel,pitch,500,400,800,800,20)
      ;       BlurSurface(*pixel,pitch,000,000,800,800,20)
     
     
      BlurSurface(*pixel,pitch,0,0,1920,1080,10)
      StopDrawing()
    EndIf
;...


Last edited by Mijikai on Mon Oct 21, 2019 9:05 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Mon Oct 21, 2019 9:04 am 
Offline
Enthusiast
Enthusiast

Joined: Wed Sep 18, 2013 11:54 am
Posts: 403
Location: France
Then I need StartDrawing(ScreenOutput())?! That's my question, how do you "access the backbuffer" (which should be called "buffer" only, because as #NULL mentions, you can't draw to the front buffer anyway). DrawingBuffer() requires a StartDrawing() block!

EDIT: Yeah, well... It's extremely slow to do that, it costs me 25 FPS.

EDIT2: Again, to be clear:
Code:
Repeat
...
StartDrawing(ScreenOutput())
DrawingBuffer()
StopDrawing()
...
ForEver

That is the expensive part. 25FPS for me. Just "doing nothing" :)

EDIT3: As I thought, the buffer is not "moving" at every frame, so I don't get why catching the buffer only once doesn't work. Would love to know why.


Last edited by Joubarbe on Mon Oct 21, 2019 9:19 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject: Re: Gaussian blur in real time?
PostPosted: Mon Oct 21, 2019 9:19 am 
Offline
Enthusiast
Enthusiast
User avatar

Joined: Sun Sep 11, 2016 2:17 pm
Posts: 727
Joubarbe wrote:
Then I need StartDrawing(ScreenOutput())?!

Yes

Joubarbe wrote:
EDIT: Yeah, well... It's extremely slow to do that, it costs me 25 FPS.

No, seems like something is going wrong.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 48 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye