Sign in to follow this  
Kylotan

Wishlist for 2D SDL/OpenGL library?

Recommended Posts

Since I'm usually too lazy and uninspired to make complete games, I thought I might have a go at throwing together a tiny library for high-speed 2D rendering using OpenGL and SDL. It would be solely concerned with initialising video, loading sprites, drawing them, buffer flipping, and graceful shutdown. The emphasis will be on making usage as simple as normal SDL, portable, and requiring no or little OpenGL specific knowledge. Assuming this is a reasonable project - and I'm guessing it might be, considering how many people still ask about this despite relevant snippets being posted in the past - what features would you like to see in it?

Share this post


Link to post
Share on other sites
I've been waiting for something like this for a while.
Here is my wishlist.
-ability to manipulate RGBA values with out having to respect the surface. (No more damned SDL_MAPRBGA!)
-write to the surfaces w/out having to lock unlock the memory, and make all of the surfaces 32bit to begin with!
-color keying
-rotation about an arbitrarty point of the sprite.
-scaling.
-render to buffer. good for staging effects like shaking and transitions.
-straight up C implimentation, or minimialistic classes.

Kylotan, if you are serious about doing this, I could write up a tutorial and some documentation for it.

Share this post


Link to post
Share on other sites
it would be really cool, if you had the rendering aspect of it be slightly "independent". basically, have it so it uses SDL for blitting if theres no hardware available, and OpenGL if there is hardware available. this would be very nice, it would be compatible with almost all systems, and super fast on most systems. you could even disable rotations/alpha blending/scaling on software only mode.

a font system would be really nice.
a gui system would be even nicer.

i realize those last 2 are more suited for add on lib's, but i thought id try for the hell of it.

oh, oh!!! and a high resolution, cross platform timer. god, i would kill for one of these [smile].

Share this post


Link to post
Share on other sites
Pretty much what PnP Bios said but with a few modifications.

- scaling
- rotation
- color keying
- alpha blending
- use simple rects for blitting and hide all of the vertex crap
for 2d stuff but make it accessable for 3d uses.

I think that is it. Pretty much, I want to remain a 2d programmer without having to learn about verticies and planes and polygons if I don't have to but be able to use the hardware acceleration for alpha blending and rotation. Is this really too much to ask? :) Thanks Kylotan for taking the step video card manufacturers skipped (if this project gets underway that is).

Share this post


Link to post
Share on other sites
Regarding pixel manipulation, I wouldn't want to go too deeply into this since it's usually slow no matter what system you use, but some sort of SetPixel(r,g,b,a as floats from 0.0...1.0) might be on the cards.

Not sure about locking surfaces before writes - I believe it may only be DirectX that requires this on SDL so it might not be an issue, but I'd have to look more closely at it under OpenGL.

Colour keying - definitely going in. I had just planned on converting the keyed colour in the sprite to having 0.0 opacity at the start. Is there any common use case requiring an alternative approach, or can I safely use that in all cases?

Rotation, certainly. About an arbitrary point... I don't see why not as that would just involve a translation before the rotation.

Scaling is already done, since I saw a snippet for that here once before.

Render to buffer, I will have to research. Any links appreciated.

C implementation... I was considering a C implementation with some thin wrapper classes for C++ fans. I'll be writing a Python wrapper for it if all goes well, so the simpler the better.

SDL rendering fallback if no hardware was available would be nice but it's a little beyond the scope of what I want to do, since the idea here is to provide a lib that makes it practical to use full alpha-blending, scaling, rotation, bilinear filtering, and so on in your simple 2D apps.

Font library... I would like to implement very simple text support using sdl_ttf as the backbone. So basically, if you want font support, you'd need that library installed, but it would be used behind the scenes. Similarly for sdl_image - if you have it installed then the system can load more file formats but its use is largely transparent.

Alpha blending - yeah. I already have support for an opacity value from 0.0 (transparent) to 1.0 (opaque) with all values in between. I also want to include a utility function that blends 2 sprites together from one side to the other, or one corner to the other, to make tile transitions simple.

Share this post


Link to post
Share on other sites
Not sure about dynamic resizing and resolution changes. I'll see how difficult it is once other things are implemented.

Owl, what do you mean by tiles and layers? I think everyone might have different thoughts when they say that, so I'd like to know what you would need.

So far, I have the following implemented:
- Window opening in fullscreen or windowed mode at chosen resolution
- Sprite loading using SDL_LoadBMP or IMG_Load (from sdl_image), for power-of-two sized sprites
- Basic sprite rendering
- Scaled sprite rendering
- Rotated sprite rendering (currently around centre of sprite only)
- Translucent sprite rendering (from fully opaque to fully translucent)
- Alpha channel sprite rendering (from PNG)
- Coloured quad rendering with arbitrary opacity (useful if you need to darken or lighten part of the screen, for instance)

Next up I hope to handle the colour keying aspect, which will edit the alpha channel based on the specified key. Once that's done, I'll clean up the code and give out a test release for people.

Share this post


Link to post
Share on other sites
what about the Z axis? you should provide a blitting function which lets you specify the Z value, or something. that way it will be very easy to add layers to a game, by just specyfing the Z value (this is VERY nice).

be carefull, though. theres that screwy thing with geometry disapearing (failing the depth test) when 2 transaprent objects are rendered on top of one another with varying Z values. if you could get this to work though, it would be very very sweet. theres a GL state which says "throw away any pixels which are completely transparent", which should solve half the battle. then you just have to sort semi-transparent objects... (if you figure out a good way to do this, please let me know...)

also, will you library allow access to OpenGL and SDL directly, or will we have to go through your API only?

Share this post


Link to post
Share on other sites
Quote:
Original post by graveyard filla
what about the Z axis? you should provide a blitting function which lets you specify the Z value, or something. that way it will be very easy to add layers to a game, by just specyfing the Z value (this is VERY nice).

be carefull, though. theres that screwy thing with geometry disapearing (failing the depth test) when 2 transaprent objects are rendered on top of one another with varying Z values. if you could get this to work though, it would be very very sweet. theres a GL state which says "throw away any pixels which are completely transparent", which should solve half the battle. then you just have to sort semi-transparent objects... (if you figure out a good way to do this, please let me know...)

also, will you library allow access to OpenGL and SDL directly, or will we have to go through your API only?


having a depth buffer is really pushing it. It is way better to leave depth out of it when working with 2d. doing it by your self offers much more control.

Share this post


Link to post
Share on other sites
I don't really need anything I'm just brainstorming :)

I just thought it would be cool if it came with some sort of "generic" tile engine that could be used for various kinds of games (platform, RTS, etc).

When I said layers I meant layers like in Jazz Rabbit, for background. I don't remember the english word for that right now :P

Share this post


Link to post
Share on other sites
Quote:
Original post by PnP Bios
having a depth buffer is really pushing it. It is way better to leave depth out of it when working with 2d. doing it by your self offers much more control.


i dont know... i think having OpenGL "sort" your objects makes it much more flexible and easier to use. you can basically have thousands of different layers and easily stick objects at whatever layer you want by giving them a Z value... its easier to do then manually making a layered effect, you just use glVertex3f instead of glVertex2f . also its faster to render say a screen full of tiles in one single pass then in multiple passes. he could even encapsulate the whole thing, and make the user think hes only working in 2 dimensions by offering a blitting function which received a "layer" as a parameter. this layer could be between -10 and 10 and internally it would just be the Z value that the object was rendered to. this would give the user all the layers he could ever work and is something thats very convenient and that no other 2d API probably offers. didnt the SNES have a system like this? i think it would be very sweet.

Share this post


Link to post
Share on other sites
Quote:
Original post by graveyard filla
Quote:
Original post by PnP Bios
having a depth buffer is really pushing it. It is way better to leave depth out of it when working with 2d. doing it by your self offers much more control.


i dont know... i think having OpenGL "sort" your objects makes it much more flexible and easier to use. you can basically have thousands of different layers and easily stick objects at whatever layer you want by giving them a Z value... its easier to do then manually making a layered effect, you just use glVertex3f instead of glVertex2f . also its faster to render say a screen full of tiles in one single pass then in multiple passes. he could even encapsulate the whole thing, and make the user think hes only working in 2 dimensions by offering a blitting function which received a "layer" as a parameter. this layer could be between -10 and 10 and internally it would just be the Z value that the object was rendered to. this would give the user all the layers he could ever work and is something thats very convenient and that no other 2d API probably offers. didnt the SNES have a system like this? i think it would be very sweet.


the biggest problem is what happens when one object is drawn over another on the same layer. The triangles/rectangles clash with each other for rendering superiority. that's not an issue if you don't have a depth buffer.

Share this post


Link to post
Share on other sites
Quote:
Original post by PnP Bios
the biggest problem is what happens when one object is drawn over another on the same layer. The triangles/rectangles clash with each other for rendering superiority. that's not an issue if you don't have a depth buffer.


i dont understand.. what do you mean "they class with each other for rendering superiority"???

if 2 objects have the same Z value, and are drawn one on top of the other, then they will show up in the order in which they were drawn, IE the last guy drawn will be on top. this is the same effect that happends without a depth buffer... no?

Share this post


Link to post
Share on other sites
As best I can tell, everything you want to do can already be done by SDL, except for rotation. I assume (corrrect me if I'm wrong) that your intention is to insulate users from needing to know OpenGL to do simple 2D graphics (for which I applaud your efforts).

Instead of building a seperate library on top of SDL/OpenGL, why not build a new renderer under SDL? Complement the existing Windows DirectDraw/GDI renderer with a new, hardware accelerated OpenGL one. I believe some work has been done in this direction already, but I can't find any evidence of it.

Quote:
Original post by Kylotan
The emphasis will be on making usage as simple as normal SDL, portable, and requiring no or little OpenGL specific knowledge.
What could be simpler than the existing SDL library interface, especially if people already know SDL?

The downside (of course) is that you're restricted to the existing SDL interface (unless you add some special extensions, a la SDL_gfx) and anyone who wants to use it would need a special build of SDL - unless you can get it accepted into the mainline.

I don't know what might be involved - depending on the state of the SDL code, a seperate library might just be simpler and easier. The SDL20 branch hasn't been updated beyond the initial commit 18 months ago, and much of SDL12 is three years old.

Share this post


Link to post
Share on other sites
Quote:
Original post by jdhardy
As best I can tell, everything you want to do can already be done by SDL, except for rotation. I assume (corrrect me if I'm wrong) that your intention is to insulate users from needing to know OpenGL to do simple 2D graphics (for which I applaud your efforts).


Yes. The reason here is not really to provide anything new but to provide good performance. SDL for Windows is based on DirectDraw 5 or 6, which is slow by modern standards. I find myself with frame rates of between 30 and 50 when I'm barely doing anything except fill the screen with tiles. Try using any SDL alpha blitting and it gets unusable.

When people post here about this speed problem, the answer is often to 'use OpenGL'. Sadly this is generally quite daunting to someone who's just used to 2D. Using OpenGL for 2D does actually seem quite simple when you know how, but it's the knowing-how that's the problem.

Oh, and I do think rotation is a very useful thing, not to be written off as a mere bonus feature. It's great to not have to create and load 4 or 8 times the artwork, or to have to worry about the anti-aliasing of the edges. It's also good to not be limited to a discrete number of angles.

Quote:
Instead of building a seperate library on top of SDL/OpenGL, why not build a new renderer under SDL?


Because that would be an ambitious project, and I don't want an ambitious project. As you say, that has already begun, about 2 years ago now, and as far as I know is not finished yet.

Quote:
The SDL20 branch hasn't been updated beyond the initial commit 18 months ago, and much of SDL12 is three years old.


I'm very unhappy with the stagnation in SDL development, to say the least. Maybe one day they'll do all this stuff natively, as they should have a long time ago, but for now I hope I can write something useful to somebody.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
I'm very unhappy with the stagnation in SDL development, to say the least. Maybe one day they'll do all this stuff natively, as they should have a long time ago, but for now I hope I can write something useful to somebody.

yea the fact that SDL hasn't been updated in so long irks me continuously

Anyways, this is real cool of you Kylotan. I've been procrastinating for so long switching my rendering from straight up SDL to OpenGL. One of those things where I know once I learn it it'll be easy, but I just haven't taken the time to learn it yet :P I've managed to squeeze out decent framerates using bare SDL, but OGL support would be sooo much better.

How's it coming? I'd be happy to help too if you need it, tho it sounds like a pretty straightforward project

Share this post


Link to post
Share on other sites
Hardware accelerated alpha blending.

Ability to render tens of thousands of sprites at high frame rates. For examples of where this might lead game designwise, please see the results of Indie Game Jam 0.

Once you start worrying about 10K..100K sprites on the screen at once, you start worrying about 2 things:

- how am I going to keep all those sprites from simply overlapping each other?

- how the hell am I going to control all of those sprites?

For instance, several of the games in the Indie Game Jam 0 could just have easily been implemented with 1 great big sprite for some monsters, rather than tons and tons of little ones. As it stands, you often couldn't tell if you were being approached by a horde of 20 sprites or 20K sprites.

Share this post


Link to post
Share on other sites
Rendering to sprites / modifying sprite pixels can be done easily if you keep a copy of them in system memory and you upload this to the video memory (which is fast). So when creating a surface/sprite/etc. specify a flag which makes the API keep a copy in system memory.

Once you have a setpixel function you can draw lines, circles, rectangles. If you chose to do this in your own api, you can keep it simple by using just these basic primitives.

The other way of doing it would be to preprocess sprites that need modification before rendering the screen: render the sprite onscreen in a viewport with its size, then render queued primitives using opengl, then copy from the backbuffer to the sprite's memory range (glCopyTexImage2D i think).

Another thing that would be great, but a little harder to implement: non power of two sprites / surfaces. You can do these by dividing the surfaces into power of two subsurfaces and where these extend beyond the original surface's size, fill with alpha = 0 making them transparent. To render to these you could use either of the two techniques above just make sure you copy only the pixels within the orignal surface (non pow 2).

Also, don't use floating point colors for the SetPixel function, it will just slow things down as you have to convert to RGBA, use bytes.

Share this post


Link to post
Share on other sites
Here's what I think. There should be classes for things like sprites and bitmaps for easier manipulation. Or I could just make a pixel on the screen in 1 function. lets say something like, I could do this...


SDL_Sprite *sprite;
sprite = SDL_LoadBMP("MySprite.bmp");
sprite.transparentColor = {255,255,255};

SDL_Surface *screen
screen=SDL_SetVideoMode(640,480,32,SDL_HWSURFACE|SDL_DOUBLEBUF);

Slock();
sprite.loadToSurface(screen,
x1,y1,
x2,y2,
w , h)
Sulock();



Where x1 and y1 are the top left point, x2 and y2 are the bottom right, and w and h are the wisth and height if youw ant to stretch it. What I suggest is look the the DarkBasic functions. Try and make C++/SDL/OpenGL versions of those so it's really easy like make a SDL_SyncStart where it locks the screen and SDL_SyncEnd where it unlocks then flips. Only if it were that easy.

Share this post


Link to post
Share on other sites
My existing system looks quite similar to the one posted by Yamian. There is no locking though as this is pure OpenGL. I have no aspirations to make multiple rendering backends.

Development is ongoing, although it's slowed down by OpenGL tending to crash my system after a few runs of any program under Windows, and me not having the patience to get it compiling under Linux yet. I may have another go at the latter soon to finish off the test cases, then the first release will be forthcoming.

Share this post


Link to post
Share on other sites
Quote:
Original post by Anonymous Poster
There's glSDL which replaces SDL's blitting functions with OpenGL stuff. http://olofson.net/mixed.html
This is exactly what I was going to suggest you do.

Can you start with this codebase and b uild from there?

Share this post


Link to post
Share on other sites
Some random comments:
- *Don't* try and hide the fact that this is an OpenGL/DX accelerated system. Don't try and force it to look like a 2d blitting method 'cos that'll make it ultimatly slower and more complicated. Embrace the advantages that OpenGL gives you rather than hiding it.
- Probably a good idea to ignore the depth buffer. For really good quality 2d you'll be using plenty of blending for smoothing the edges of sprites and that rules out using depth testing.
- Tilemaps (2d arrays of sprites) should probably get special handling. I'm currently using a general purpose sprite handler for doing tilemaps and it gets pretty inefficient. You can do shedloads of optimisations for tilemaps that you can't do in a generic sprite renderer.
- Some sort of support for controlling draw order or layers is pretty much a must.
- Some kind of tool for packing a collection of sprite images in a single texture is a great help, especially 'cos you don't need power-of-two sprite sizes everywhere.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this