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!