PDA

View Full Version : SDL & 2d particles



code_glitch
18-08-2010, 01:04 PM
I dont know if this is possible, but here goes anyway. I'm using sdl for a 2d game engine, I was wondering if it is possible to make a decently performing 2d particle engine (or at least particle effects) on a 2d surface that performs reasonably. I've run a few preliminary benchmarks and found that things are quite slow already due to the use of rotozoomsurface...

I've looked around on the internet and all the examples of a simple engine are for opengl written in c/c++. Although, I have a baisc understanding of c/c++ when you add my very elementary understanding of opengl on top of that, it spells disaster.

I was wondering if any of you out there have done this and wouldnt mind sharing a pascal example with the community?

Cheers,
code_glitch

ps. sorry about the absence, just got back from holiday. XD

code_glitch
21-08-2010, 05:53 PM
uhh, this is awkward to hear silence on a site that had the buzz of an active community meeting deadlines in the real world and sparing that extra minute to help others...

case Awkward_Silence of
Everyone_Abducted_By_Aliens: OhNo( :();
This_Doesnt_Exist: 404?;
Other_Cause: Uhh_Does_Not_Compile; :D

JSoftware
21-08-2010, 06:55 PM
Rotation in SDL is done in software(rotozoom). So it's inherently slow

I would recommend either using precalculated rotated surfaces, no rotation :) or OpenGL

code_glitch
21-08-2010, 07:42 PM
Rotation in SDL is done in software(rotozoom). So it's inherently slow

I would recommend either using precalculated rotated surfaces, no rotation :) or OpenGL


So, just use an alpha layer (semi-transparent) layer with the particles drawn on it and blit that straight to the screen?

WILL
21-08-2010, 08:16 PM
You forgot the end; your code won't run. ;)

Well a particle system really just a bunch of objects playing the part of a single sprite or image that will go a pre-determined path and last only so long, usually termed 'life' or 'time-to-live.' As it's life fades or comes near it's end, so will it's visibility or alpha value. A single sprite, or 'particle' shows this effect well, but isn't really all that attractive, however when done in a big or small group together can make up many effects which can look quite nice and sometimes life-like. The higher the amount of particles the more effective or interesting the effect, however the more processing power it requires.

Essentially what you are doing in your code is making an object class or record type to track a single particle. You then make make an array or list of these so that you can keep track of as many of these as you require. Usually this will be the main part of your particle engine's code.

Your particle class will look something like this...


type
TParticle = record
X, Y: Real; // Location
VelX, VelY: Real; // Movement
Life: Cardinal; // Time to Live
rr, gg, bb, aa: glUint; // Color information with initial Alpha value
end;

Now I used the gluint type from OpenGL which is just an unsigned integer type. You'd usually have some kind of color information if you are using white sprite textures or if you are just using pixels, but it's more common these days to have even just a simple small texture that you can color as you need. Also I used a record type to simplify the structure a little. You can use class(TObject) if you wish to make yours object oriented if you prefer.

You'd then make your array or list, also called emitter, that will contain all of the particles that you would need and the stuff to make it all display, time out, etc. For example...


type
TEmitter = class(TObject)
NumberOfParticles: Cardinal; // Keep track of how many particles you are using!
Particles: Array[0 .. 255] of TParticle; // You're lovely little particles
Sprites: TTexture; // stores texture or reference to the texture you're using

constructor Init; // may include code to init your particles
destructor Deinit; // will include code to free your list to prevent memory leaks

procedure Update; // performs movement and time to live countdown on particles
end;

Now this part really will be what controls all your effects and how each particle will behave. You can make it as complex or as simple as you feel you need. I've left out a bunch of other possible functions, such as particle list/array management, detection of dead particles and so on. I won't go that deep in my explanation here.

Update; would be the main function of your emitter. It changes the position of ALL of your particles by using their X,Y and VelX,VelY values and reduces your life value by it's increment (would be 1 in this example) and would also reduce your particle's alpha value based on it's time to live. (However you choose to translate this from your life value to your alpha.) You want to run this procedure once per iteration of your main game loop.

That's a very basic intro to particles as I know them. Others will be able to help you more and even show you much more complex systems that you can try. I'd recommend not getting too carried away unless you plan on only higher-end systems being able to run your programs visual effects. Otherwise particle systems can be kinda fun to play with. I've made a somewhat simple one myself for one of my games before and it really did add to the visuals.

code_glitch
22-08-2010, 05:48 PM
Thanks, that has helped me a lot towards my particle engine. However, I may have to postpone that a while, since I've hit a brick wall: performance.

My engine heavily uses sdl_blitsurface, anti-aliasing and rotozoomsurface. This is problematic. My aim is to stay within 1GHZ, and to stay within that limit, I have tried 24bpp, limited size, no AA, SW and HW surfaces with no luck. Is there anything faster than sdl_blitsurface and rotozoomsurface? My engine is heavily engineered to have its own script environment to run everything. The problem I have is that I can only run up to 4 simultaneous rotations and blit a background in the 1GHZ window. That isnt much for a game...

My first test of particles raised the bar to 1.8GHZ for not too-stunning and basic results. Any ideas?

User137
22-08-2010, 05:58 PM
If your engine have to use rotating, alphablending or even nicer effects i'd switch to OpenGL or DirectX. rotozoomsurface is very slow like mentioned earlier. As for optimizing particles you haven't given any code samples or screenshot/video of what they look like.

code_glitch
22-08-2010, 11:19 PM
If your engine have to use rotating, alphablending or even nicer effects i'd switch to OpenGL or DirectX. rotozoomsurface is very slow like mentioned earlier. As for optimizing particles you haven't given any code samples or screenshot/video of what they look like.


The reason I havent given any screenshots is that I dont believe that taking screenshots of trying to get a layer of particles on screen and failing is very constructive, especially when all y9u can see is a garbled mess. I have fixing to do there. But if I switch to opengl, could you recommend a good tutorial? My coding is haphazard, and I dont know how much ease of use would be lost when I switch over to opengl... Basically, Sdl is quite new to me still, and opengl is something I have never done... ???

WILL
25-08-2010, 10:01 PM
You could try video and post it on YouTube. Lots of developers are doing this so it's not like you'd be the only one. You can also make it private or just not public so that you have to specifically go to the youtube link to access it so that only those interested in the video would see it.

If you do want to do a particle engine using SDL's graphics I'd recommend staying away from any alpha, rotation or scaling. Basically anything that makes a particle engine do what it does. :P You could use only pixels and alter the color of them from it's base color to the background color of your screen to give the illusion of fading out. You then will have to sort your particles drawing order by life remaining to prevent the majority of a distorted effect. That's considering you are just using a single background color, which might not be the case. Still, OpenGL or D3D are your best bets. OpenGL is my personal favorite so I would of course recommend it, especially since SDL games and programs are more easily adapted to use OpenGL instead of DirectX. (You can keep using your existing window management, input and audio code for example.)

For OpenGL you are best to go to the NeHe website at http://nehe.gamedev.net/ their tutorials are awesome.

code_glitch
26-08-2010, 08:11 AM
Thanks will. I think I will look at the NeHe tutorial which seems quite good and give opengl a shot. I plan to re-write my engine to work with OpenGl (thank god its not as long as some other programs I have written) and then see if I can get to my 1Ghz target a bit more comfortably.

If I had to give a tip to people in optimizing sdl it would be 24 bit swsurface and set the colour mode with setcolourmode_alpha or whatever your going for. For me it lowered cpu by almost 40% from around 2Ghz but that was the minimum and I want 1Ghz to be at 50% load not minimum so I will move to OpenGl.

code_glitch
27-08-2010, 10:50 PM
A quick word about my last (successful) attempt at optimizing sdl.

adding the following flags as arguements to making a new window improved performance by over 50% in my case:


Sdl_HwSurface Or Sdl_HwAccel Or Sdl_RleAccel Or Sdl_Doublebuf Or Sdl_Resizable

This has finally made my goal of under 1Ghz cpu for my rotations, and a bit of code to improve when elements are re-drawn has brought my engine down from 950mhz to around 175mhz. It took long, but with enough tweaking I now believe that sdl really is as flexible as people claim it is. I think it will be another while yet before I make the permanent move to OpenGl, my enemy in terms of complexity.

Code out.