StartSpecialFX() Enhancement

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
Revolver
User
User
Posts: 22
Joined: Tue Apr 29, 2003 9:20 pm

StartSpecialFX() Enhancement

Post by Revolver »

I was messing around with the special effects commands today, and noticed something. The documentation for StartSpecialFX() states that any normal sprite drawing commands(such as DisplaySprite()) should be used after StopSpecialEffects(). I figured it meant that you should use them outside the special effects environment, which meant you could also do it before StartSpecialFX(). I was wrong! Upon looking closer to the documentation, it states that StartSpecialFX() creates a new memory buffer in the main system ram to perform the special effects operations with. Well this is fine, but it also means that any normal sprite commands you used to draw to the buffer in the video memory are now wiped away! Take for example, the following code:

Code: Select all

InitSprite()
InitMouse()
InitKeyboard()
OpenScreen(640, 480, 32, "Sprite Test")
LoadSprite(0, "Data\Background.bmp", 0)
LoadSprite(1, "Data\PureBasic.bmp", #PB_Sprite_Memory)

Repeat
  
  FlipBuffers()
  ExamineMouse()
  
  DisplaySprite(0, 0, 0)
  
  StartSpecialFX()
    DisplayTranslucideSprite(1, MouseX(), MouseY(), 128)
  StopSpecialFX()
  
  StartDrawing(ScreenOutput())
    DrawingMode(1)
    Locate(10,10) : DrawText("Testing text")
  StopDrawing()
  
  ExamineKeyboard()

Until KeyboardPushed(#PB_Key_Escape)

End
You'd think this would display the background, then an alpha blended pb logo wherever the mouse is, and then some plain text on it, right? Wrong! That first DisplaySprite(0, 0, 0) command is nullified, because when you call StartSpecialFX(), it uses a new, blank buffer in the system ram to draw on, not the one you drew the background sprite on in video memory. Now, check out this following code, that actually works(this is how it is done in the examples):

Code: Select all

InitSprite()
InitMouse()
InitKeyboard()
OpenScreen(640, 480, 32, "Sprite Test")
LoadSprite(0, "Data\Background.bmp", #PB_Sprite_Memory)
LoadSprite(1, "Data\PureBasic.bmp", #PB_Sprite_Memory)

Repeat
  
  FlipBuffers()
  ExamineMouse()
  
  StartSpecialFX()
    DisplaySprite(0, 0, 0)
    DisplayTranslucideSprite(1, MouseX(), MouseY(), 128)
  StopSpecialFX()
  
  StartDrawing(ScreenOutput())
    DrawingMode(1)
    Locate(10,10) : DrawText("Testing text")
  StopDrawing()
  
  ExamineKeyboard()

Until KeyboardPushed(#PB_Key_Escape)

End
This works because I loaded the background sprite into the system ram, and displayed it after StartSpecialFX(), onto the buffer that was being used for the special effects. Why am I complaining? This is slow! The PB docs say specifically that commands used in the special effects mode are slower than they are outside it, and that all normal sprite commands should be used outside the special effects mode when possible. Well, if you're going to be using the special effects mode at all, then you can forget using any normal sprite commands before you use the special effects commands, unless you want them to all be done inside the special effects mode, which is slower than the video card's memory and processing. This is a bad thing, because you're always going to have something under the graphics you're displaying with special effects, be it just a background, or your entire 2D world(if only your HUD was using alpha effects, you'd draw the entire world in normal commands first, then draw the HUD with special effects commands). The way things are set up now, you'd have to render the entire 2D world inside the special effects mode, and have all of the sprites for the world loaded into system ram! This would be horrible for a game developer!

Enough of this complaining, what would I recommend be done about this? Well, the documentation states that StopSpecialFX() copies the graphics buffer that was used for special effects mode from the system ram to the video card's ram. This is why you can use normal sprite commands after you're done using the special effects mode. Why not do something similar for StartSpecialFX()? When this command is called, it should copy the current drawing buffer from video card ram to the system ram, so that any normal sprite commands used before the special effects mode was needed will be retained in the current drawing buffer. That way, I could load my background sprite into the normal video memory, use the video card to draw it to the buffer very quickly, then draw the alpha logo on top of it with the system processor and memory.

Please correct me if I have gotten something wrong, or if you would like me to explain something more, but I believe I am correct in what is happening with these commands. Thanks for your time!
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1282
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Post by Paul »

Why am I complaining? This is slow! The PB docs say specifically that commands used in the special effects mode are slower than they are outside it
If you want speed (much faster than SpecialFX) then use commands from the Sprite3D Library.
Revolver
User
User
Posts: 22
Joined: Tue Apr 29, 2003 9:20 pm

Post by Revolver »

I'd rather not have all of my sprites be one of the following dimensions: 16x16, 32x32, 64x64, 128x128 or 256x256... Plus look at how robust the sprite command set is compared to the relatively sparse 3d sprite command set.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Ok, let's clarify a bit. We will try to do these operations with the StartFX():

1) Have a nice background
2) Blend some sprites on the background

If you use the regular DisplaySprite() command, the sprite is copied directly by the video card chipset to the VideoRam. Ok, so we have our background in the video ram, keep this in mind. So if I want to blend it at fast speed, I need to copy the whole videoram content into the system memory and then do all the blends ops. This is the bottleneck, and doing this is awfully slow. And you still have to copy back the whole buffer to the videoram once the blending is done.

So the SpecialFX() mode skip the first Video->System copy as it is much faster to copy a sprite from SystemMem->System than Video->System (you can easily understand why, the processor has to go trough the PCI/AGP bus).

The second way you used is of course the right one.

Note: you can use all the special fx command directly on the video screen (without Start/StopFX). For small op it will be faster I guess but it will slower very quickly if you do a lot of blending ops.

What can we do ? I can add a flag to StartFX() to copy the current video buffer. Please be careful about performance as I stated above. And I think it could have a clever way with this stuff: doing a clipping area:

StartFX(x,y,Width,Height) to only work on a small part of the screen instead of the whole screen.

Any comments are welcome.
Revolver
User
User
Posts: 22
Joined: Tue Apr 29, 2003 9:20 pm

Post by Revolver »

Fred wrote:StartFX(x,y,Width,Height)
I like this idea a lot! Let's say I drew my game world with normal sprite commands, and then wanted to use some alpha effects for the HUD. Well, the HUD doesn't take up the entire screen, just little portions of some corners and maybe sides. It would not make any sense at all to transfer the entire screen buffer to system memory to only do effects on one small piece of the screen. However, if you had, let's say, 1 icon in each corner of the screen, if you wanted to do them all in the same SpecialFX() mode, you'd have to copy nearly the whole screen buffer to system memory. Or, you could call the StartSpecialFX() and StopSpecialFX() four times, 1 for each small part of the screen you wanted to do alpha effects on. Do these 2 commands have any additional overhead that would slow them down if you called them 4 times per game loop? Or is the only really slow thing thats happening being the screen buffers being copied? If that's true, then copying 32x32 pixels (the icons in the corners) 2 times per SpecialFX() mode(from video memory to system memory first, then system memory back to video memory when done), 4 times per game loop(8,192 total pixels) would still be faster than 2 copies of 640x480 (or whatever resolution you're using), 1 time per game loop(614,400 total pixels).
Revolver
User
User
Posts: 22
Joined: Tue Apr 29, 2003 9:20 pm

Post by Revolver »

Just to clarify you'd have to make sure that StopSpecialFX() only copied back the same clipped dimensions specified in StartSpecialFX(), not the entire screen. I guess this would seem obvious, but I just wanted to get my point across better
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Yes, that's exaclty the way I would like for StopSpecialFX(). So, I will implement this soon.
THCM
Enthusiast
Enthusiast
Posts: 276
Joined: Fri Apr 25, 2003 5:06 pm
Location: Gummersbach - Germany
Contact:

Post by THCM »

Did I miss something here? Fred do you still plan to implement this?
The Human Code Machine / Masters' Design Group
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

Hi Revolver
Why you don't use simply system memory Sprites ? :?
regards
Stefan
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

S.M. wrote:Hi Revolver
Why you don't use simply system memory Sprites ? :?
regards
Stefan
Don't expect an answer. His posting is from may 2003, his post count ist 22 ;)
<°)))o><²³
S.M.
Enthusiast
Enthusiast
Posts: 118
Joined: Sat Apr 24, 2004 1:11 pm
Contact:

Post by S.M. »

freedimension wrote: Don't expect an answer. His posting is from may 2003, his post count ist 22
Oops :oops:

:lol:
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Post by blueznl »

iirc fred was going to do something with a copy option... i think...
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
THCM
Enthusiast
Enthusiast
Posts: 276
Joined: Fri Apr 25, 2003 5:06 pm
Location: Gummersbach - Germany
Contact:

Post by THCM »

Very nice Guide blueznl! Any chance to get your tutorial for offline browsing?
The Human Code Machine / Masters' Design Group
Post Reply