[Gambas-user] gb3 (rev. 3641) and SDL surfaces

Laurent Carlier lordheavym at ...626...
Wed Mar 16 14:32:55 CET 2011


Le lundi 14 mars 2011 08:38:15, Kevin Fishburne a écrit :
> On 03/10/2011 05:09 AM, Benoît Minisini wrote:
> >> I've been experimenting with gb.sdl and found that I could achieve frame
> >> rates higher than 380 fps at 1920x1080, including alpha channel. This
> >> involves writing directly to the SDL window/surface with a 1920x1080
> >> image loaded from a file, for example:
> >> 
> >> Public Screen As New Window As "Screen"
> >> Public SomeImage As Image = Image.Load("someimage.png")
> >> 
> >> Public Sub Main()
> >> 
> >>     ' Create screen.
> >>     With Screen
> >>     
> >>       .Width = 1920
> >>       .Height = 1080
> >>       .Framerate = 1000
> >>       .FullScreen = True
> >>       .Show()
> >>     
> >>     End With
> >> 
> >> End
> >> 
> >> Public Sub Screen_Draw()
> >> 
> >>     Draw.Image(SomeImage, 0, 0)
> >>     Draw.Text(Screen.Framerate&  " FPS", 0, 0)
> >> 
> >> End
> >> 
> >> While this is awesome, there is a problem if images need to be
> >> composited before being written to the SDL surface. For example, if I
> >> wanted to do something like this:
> >> 
> >> Water.Draw(WaterRipples, 0, 0)
> >> Water.Draw(SkyReflection, 0, 0)
> >> Water.DrawAlpha(WaterDepth, 0, 0)
> >> 
> >> and then draw Water to the SDL window, not only is the imlib2 component
> >> required (otherwise it states the .Draw method is unknown), it kills the
> >> frame rate because the Draw method is done in software (imlib2) and only
> >> the writes done directly to the SDL window are hardware accelerated.
> >> 
> >> Attempting to circumvent this I created a second SDL window, hoping I
> >> could write the contents of window B to window A. The idea was to create
> >> multiple secondary SDL windows, using them as image buffers, then write
> >> the buffers as necessary to the main SDL window when its Draw event was
> >> called. This didn't work at all and I don't think it's supported.
> >> 
> >> Is there a way to use the Draw method, or an equivalent, so that
> >> image-to-image writes can be done entirely in SDL? I've already
> >> converted my app to use the SDL component but too much of it currently
> >> uses the .Draw and .DrawAlpha methods which bring the framerate to 21
> >> fps at 1280x720. The framerate is only going to get worse from here, as
> >> I'm just getting started.
> > 
> > I think (only Laurent can confirm) that SDL uses internally OpenGL to do
> > its stuff. So the speed of the SDL component depends on the graphics
> > driver (which is a very sensible thing on Linux).
> > 
> > Then, if you want to compose images, I think only doing direct OpenGL
> > call will help you, by stacking textured rectangles. But I don't know if
> > OpenGL can do the equivalent of Draw.Alpha().
> 
> That makes sense, as SDL uses OpenGL when available for hardware
> acceleration. I think it's basically a wrapper for OpenGL (or DirectX
> though that is irrelevant obviously). While DrawAlpha is a blessing, the
> main problem is the regular Draw method not being supported by the SDL
> component. As I said drawing directly to the SDL surface is super fast
> but image-to-image drawing is super slow. I have no issue with DrawAlpha
> being maintained in software only, but basic image blitting should
> definitely be supported by the SDL (and by proxy OpenGL) component. I
> wonder if this has something to do with how the images are loaded into
> RAM/VRAM. Without understanding the SDL implementation, it's hard for me
> to imagine why blitting an image to the SDL surface is fast but blitting
> image A to image B is slow. Maybe there's a good reason for that, but it
> seems counter-intuitive to me (story of my life, right?).

SDL 1.2.x library itself isn't hardware accelerated under linux. The SDL 
component use only the SDL library to keep window/images  in RAM, but all 
drawing in the window is done with OpenGL (using texturing), so image are 
cached (send only one time in the VRAM). If you modify the Image continuously, 
the Image will need to be load in VRAM before displaying continously also.

Currently blitting image to image is slow because done in software, but i've 
plans to do this with OpenGL (so in VRAM directly) through the Framebuffer 
Object extension.

Perhaps an accelerated DrawAlpha() method should be possible, i'm currently 
digging the net about such a possibility.

++




More information about the User mailing list