Testing SDL 1.3 API

I’m testing SDL 1.3 API to evaluate porting of some projects to this API,
I’m wondering if there is an easy way to port a game where every sprite has
a back buffer to SDL 1.3 (it’s a card game it doesn’t need to redraw the
whole screen every time you click a card).

At the moment to fill the backbuffer I’m trying this approach that I think
it’s quite slow (from what I’ve read on the SDL 1.3 headers at least):

char buffer[4 * rend_.card_size_.X() * rend_.card_size_.Y()];
SDL_RenderReadPixels(&r, buffer, 4);
SDL_UpdateTexture(it->second.Dirty(), NULL, buffer, 4);

I cannot test if this approach works because on linux (ubuntu 8.04) with the
latest SVN (as of today) I get the following error in link stage:

lowres_renderer.cpp|326| undefined reference to `SDL_RenderReadPixels’

Looking at the source and grepping the binary I’ve seen that function is
only defined on headers:

gabry at nevada:~/no-backup/SDL-1.3/test$ strings …/…/lib/libSDL-1.3.so.0.0.0
| grep Pixels
SDL_QueryTexturePixels
gabry at nevada:~/no-backup/SDL-1.3/test$

Anyway I understand that, also if implemented, calling
SDL_RenderReadPixels()/SDL_UpdateTexture, very often is not a good idea, but
at this point what I could do?

I have to rework the whole game logic moving the screen update code from
being event based to be frame based and redraw the whole cardset every
frame?

Actually only if you click something or drag something a partial screen
update is triggered, otherwise the game waits in a SDL_WaitEvent call, and I
think this is a good approach, expecially for mobile devices where keeping
the CPU in idle is very important.

It would be nice to be able to copy to a texture a part of the render
surface or to render a texture to another texture (using the RTT extensions
that most gfx chipset have). From what I’ve seen from the headers the only
operation you can do with a texture is to blit it to a render target (that
can be only a window) or to modify it with direct pixel access.

Speaking about textures I’ve also found another minor problem, it seems that
SDL_CreateTextureFrom() is unable to import 32bit BMP loaded from
SDL_LoadBMP (Unknown pixel format error), I worked around it with the
following code:

    if (SDL_Surface *dest = SDL_LoadBMP_RW(rw, 1)) { // rwops is closed

by loadbmp
if (SDL_Surface *temp = SDL_CreateRGBSurface( SDL_SWSURFACE,
dest->w, dest->h, 32,
0xff000000, 0xff0000, 0xff00, 0xff
)) {
SDL_BlitSurface(dest, NULL, temp, NULL);
SDL_TextureID id = SDL_CreateTextureFromSurface(0, temp);

            if (id == 0)
                std::cerr << "SDL Error: " << SDL_GetError() << '\n';

            SDL_FreeSurface(temp);
            SDL_FreeSurface(dest);
            return id;
        }
        SDL_FreeSurface(dest);
    }
    return 0;-- 

Bye,
Gabry

I’m testing SDL 1.3 API to evaluate porting of some projects to this API,
I’m wondering if there is an easy way to port a game where every sprite has
a back buffer to SDL 1.3 (it’s a card game it doesn’t need to redraw the
whole screen every time you click a card).

The new drawing API in SDL 1.3 is really designed for applications to redraw
the scene each frame. The theory being that your textures reside in video
memory and this ends up being much faster than SDL 1.2 drawing.

If you’re really only updating a small area each frame, then there’s nothing
wrong with continuing to use the old style API which will give you software
rendering at about the same speed as SDL 1.2.

lowres_renderer.cpp|326| undefined reference to `SDL_RenderReadPixels’

Looking at the source and grepping the binary I’ve seen that function is
only defined on headers:

Ah right, I added that to the TODO list. It’s really only intended for
screenshot support and hasn’t been implemented yet.

I have to rework the whole game logic moving the screen update code from
being event based to be frame based and redraw the whole cardset every
frame?

Honestly, I wouldn’t bother, unless you need the performance boost. I
went to great effort to make sure that the existing 1.2 API was as fast
as SDL 1.2.

Speaking about textures I’ve also found another minor problem, it seems that
SDL_CreateTextureFrom() is unable to import 32bit BMP loaded from
SDL_LoadBMP (Unknown pixel format error), I worked around it with the
following code:

Can you post a link to a sample BMP file?

Thanks!
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC

The new drawing API in SDL 1.3 is really designed for applications to redraw

the scene each frame. The theory being that your textures reside in video
memory and this ends up being much faster than SDL 1.2 drawing.

Yes, that was the confirmation I was searching for.

If you’re really only updating a small area each frame, then there’s
nothing
wrong with continuing to use the old style API which will give you software
rendering at about the same speed as SDL 1.2.

The problem is that that API is not available on all the supported
platforms, for instance iphone, and I’d like to have iphone as one of the
targets my app run.

Speaking about textures I’ve also found another minor problem, it seems
that
SDL_CreateTextureFrom() is unable to import 32bit BMP loaded from
SDL_LoadBMP (Unknown pixel format error), I worked around it with the
following code:

Can you post a link to a sample BMP file?

Here is a link to a sample SDL 1.3 app I wrote, the 3kb zip archive contains
a bmp that works (at least loads), a BMP that does not work (and give the
"Unhandled pixel format" error), and a program that load a BMP and draws it
multiple times on a window, the bitmap is the first parameter of the
program, at the moment I’ve tested the program only in linux.

Here is the link to the 3kb archive:
http://www.ggsoft.org/archives/sdl13test.zip

I posted the full program cause I’m not that sure to do the initialization
in the correct way, I’ve wrote the code inspecting testsprite2.c and
common.c and extracting the few lines that in may opinion where needed to
intialize SDL. As you will see from the sample I’ve put a preprocessor block
since I was not sure if the correct way to initialize a SDL 1.3 app was the
old style SDL_Init() or SDL_VideoInit/SDL_SelectVideoDisplay, it seems to
work both ways…

As previously stated also the “works.bmp”, that is nothing more than the
icon.bmp used by testsprite2 gives problems with my example, the texture is
loaded and correctly sized but when blitted on the window the pixels are
randomly placed… maybe the problem is the fact icon.bmp is 8bit depth and
the screen is 32bit depth? I’m using the default renderer on linux, with -1
option to SDL_SelectRenderer, that is X11 and not opengl…

Another consideration is about “common.h/c” framework. It’s quite messy to
understand the initialization steps required, since you have too many
application states to be configured:

  1. You have to initialize the various subsystems
  2. You have to select the video display
  3. You have to open one window
  4. You have to intialize a renderer
  5. You have to assign the renderer to a window
  6. You have to select the window where to render
  7. For each texture you have to declare a blend and scale mode

I think most of these passes could be avoided and initialized with a default
value, I’ve seen that SDL_SelectVideoDisplay is optional but I think that
without major drawbacks the api can also assign a default renderer (-1) to a
window and select it if the window has no renderer associated when it’s
selected as render target.

Also the texture may be created with SCALE == NONE and BLEND == NONE as
default, I’ve not looked inside the code if it works already this way but I
think it doesn’t since I’ve had a few problems until I added those lines to
my code.

So if 2, 4, 5, 7 are optional the app could keep the same “feel” of
semplicity of the SDL classical apis without reducing the extended
flexibility added by the new system!–
Bye,
Gabry

If you’re really only updating a small area each frame, then there’s
nothing
wrong with continuing to use the old style API which will give you software
rendering at about the same speed as SDL 1.2.

The problem is that that API is not available on all the supported
platforms, for instance iphone, and I’d like to have iphone as one of the
targets my app run.

It should work, albeit a bit slowly on iPhone…

Here is a link to a sample SDL 1.3 app I wrote, the 3kb zip archive contains
a bmp that works (at least loads), a BMP that does not work (and give the
"Unhandled pixel format" error), and a program that load a BMP and draws it
multiple times on a window, the bitmap is the first parameter of the
program, at the moment I’ve tested the program only in linux.

Here is the link to the 3kb archive:
http://www.ggsoft.org/archives/sdl13test.zip

Thanks, I’ll check it out!

since I was not sure if the correct way to initialize a SDL 1.3 app was the
old style SDL_Init() or SDL_VideoInit/SDL_SelectVideoDisplay, it seems to
work both ways…

Yes, it does.

Another consideration is about “common.h/c” framework. It’s quite messy to
understand the initialization steps required, since you have too many
application states to be configured:

  1. You have to initialize the various subsystems
  2. You have to select the video display
  3. You have to open one window
  4. You have to intialize a renderer
  5. You have to assign the renderer to a window
  6. You have to select the window where to render
  7. For each texture you have to declare a blend and scale mode

I think most of these passes could be avoided and initialized with a default
value, I’ve seen that SDL_SelectVideoDisplay is optional but I think that
without major drawbacks the api can also assign a default renderer (-1) to a
window and select it if the window has no renderer associated when it’s
selected as render target.

That’s not a bad idea, I’ll look into it.

Also the texture may be created with SCALE == NONE and BLEND == NONE as
default, I’ve not looked inside the code if it works already this way but I
think it doesn’t since I’ve had a few problems until I added those lines to
my code.

This should already work. Can you describe the problems you had?

So if 2, 4, 5, 7 are optional the app could keep the same “feel” of
semplicity of the SDL classical apis without reducing the extended
flexibility added by the new system!

I agree, great suggestions!

Thanks,
-Sam Lantinga, Founder and President, Galaxy Gameworks LLC