I am currently working on a game in SDL which has destructible terrain. At the moment the terrain is one large (5000*500, for testing) bitmap which is randomly generated.
Each frame the main surface is cleared and the terrain bitmap is blitted into it. The current resolution is 1200 * 700, so when I was testing 1200 * 500 pixels were visible at most of the points.
Now the problem is: The FPS are already dropping! I thought one simple bitmap shouldn't show any effect - but I am already falling down to ~24 FPS with this!
Why is blitting & drawing a bitmap of that size so slow?
Am I taking a false approach at destructible terrain?
How have games like Worms done this? The FPS seem really high although there's definitely a lot of pixels drawn in there
Whenever you initialize a surface, do it the following way:
SDL_Surface* mySurface;
SDL_Surface* tempSurface;
tempSurface = SDL_LoadIMG("./path/to/image/image.jpg_or_whatever");
/* SDL_LoadIMG() is correct name? Not sure now, I`m at work, so I can`t verify it. */
mySurface = SDL_DisplayFormat(tempSurface);
SDL_FreeSurface(tempSurface);
The SDL_DisplayFormat() method converts the pixel format of your surface to the format the video surface uses. If you don`t do it the way I described above, SDL does this each time the surface is blitted.
And always remember: just blit the necessary parts that really are visible to the player.
That`s my first guess, why you are having performance problems. Post your code or ask more specific questions, if you want more tipps. Good luck with your game.
If you redraw the whole screen at each frame your will always get a bad FPS. You have to redraw only part of the screen which have changed. You can also try to use SDL_HWSURFACE to use hardware but it won't work on every graphical card.
2d in SDL is pretty slow and there isn't much you can do to make it faster (on windows at least it uses GDI for drawing by default.) Your options are:
Go opengl and start using textured quads for sprites.
Try SFML. It provides a hardware accelerated 2d environment.
Use SDL 1.3 Get a source snapshot it is unstable and still under development but hardware accelerated 2d is supposed to be one of the main selling points.
Related
I'm getting the feeling this won't be possible, but worth asking anyway I guess.
I have a background sprite and a foreground sprite, both are the same size as the window/view.
As the player sprite moves across the screen I want to delete the pixels it touches to reveal the background sprite.
This is not just for display purposes, I want the gaps the player has drawn or "dug" out of the foreground layer to allow enemies to travel through, or objects to fall into. So hit detection will be needed with the foreground layer.
This is quite complex and maybe Cocos2D-JS is not the best platform to use, if not possible could you recommend another which would be easier to achieve this effect with?
I believe it's possible, but I'm not capable of giving you a proper answer.
All I can say is that you'll most likely have two choices:
a. Make a physics polygonal shape and deform it, then use it as a "filter" to display your terrain image (here's a proof of concept example in another language using box2d).
b. Directly manipulate pixels and use a mask for collision detection (here's pixel-perfect collision detection in cocos2d-js, sadly I've got no info in modifying pixels).
I'm locking the backbuffer in direct3D 9 and copying an image to it. I noticed on one computer that when the image is stretched to the screen, it becomes blurry. On another computer I tested on, it's completely unfiltered (pixelated). Is there a way to specify how the backbuffer is sampled to the screen, or is it controlled by something else?
I've tried
Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
However it had no effect; I think it only affects textures.
SetSamplerState does not affect how the backbuffer is drawn to the screen. AFAIK most drivers will use point sampling, which means pixels will be lost or doubled, resulting in bad quality. BTW, what was the GPU/driver on the machine where it looked fine (you can't/shouldn't depend on this behavior everywhere)?
The right way to do this is to copy the image to a texture and render a screen aligned quad so you can use hardware sampling to smooth the result for you.
If for whatever reason you cannot use a texture + rendering pass, you can use IDirect3DDevice9::StretchRect to filter the image when copying to the backbuffer. To actually load the image from system memory, you'll have to use another surface, either locking and copying it or using D3DXLoadSurfaceFromMemory.
I'm trying to learn SDL2. The main difference (as I can see) between the old SDL and SDL2 is that old SDL had window represented by it's surface, all pictures were surfaces and all image operations and blits were surface to surface. In SDL2 we have surfaces and textures. If I got it right, surfaces are in RAM, and textures are in graphics memory. Is that right?
My goal is to make object-oriented wrapper for SDL2 because I had a similar thing for SDL. I want to have class window and class picture (has private texture and surface). Window will have it's contents represented by an instance of the picture class, and all blits will be picture to picture object blits. How to organize these picture operations:
Pixel manipulation should be on surface level?
If I want to copy part of one picture to another without rendering it, it should be on surface level?
Should I blit surface to texture only when I want to render it on the screen?
Is it better to render it all to one surface and then render it to the window texture or to render each picture to the window texture separately?
Generally, when should I use surface and when should I use texture?
Thank you for your time and all help and suggestions are welcome :)
First I need to clarify some misconceptions: The texture based rendering does not work as the old surface rendering did. While you can use SDL_Surfaces as source or destination, SDL_Textures are meant to be used as source for rendering and the complimentary SDL_Renderer is used as destination. Generally you will have to choose between the old rendering framework that is done entirely on CPU and the new one that goes for GPU, but mixing is possible.
So for you questions:
Textures do not provide direct access to pixels, so it is better to do on surfaces.
Depends. It does not hurt to copy on textures if it is not very often and you want to render it accelerated later.
When talking about textures you will always render to SDL_Renderer, and is always better to pre-load surfaces on textures.
As I explained in first paragraph, there is no window texture. You can either use entirely surface based rendering or entirely texture based rendering. If you really need both (if you want to have direct pixel access and accelerated rendering) is better do as you said: blit everything to one surface and then upload to a texture.
Lastly you should use textures whenever you can. The surface use is a exception, use it when you either have to use intensive pixel manipulation or have to deal with legacy code.
This question is actually for Unity3D, but it can also be a more general question, so therefore I'm going to make this question as general possible.
Suppose I have a scene with a camera (near = 0.3, far = 1000, fov = 60) and I want to draw a skydome that is 10000 units in radius.
The object is not culled by the frustum of the camera, because I'm inside of the dome. But the vertices are culled by some shader somehow and the end-result looks like this:
Now my question is:
what setting for any engine can I change to make sure that the complete object is drawn and not clipped by the far plane of the camera?
What I don't want is:
Change the far plane to 10000, because it makes the frustum less accurate
Change the near plane, because my game is actually on a very low scale
Change the scale of the dome, because this setting looks very realistic
I do not know how to do this in Unity but in DirectX and in OpenGL you switch off the zbuffer (both checks and writing) and draw the skybox first.
Then you switch on the zbuffer and draw the rest of the scene.
My guess is that Unity can do all this for you.
I have two solutions for my own problem. The first one doesn't solve everything. The second does, but is against my own design principles.
There was no possibility for me to change the shader's z-writing, which is a great solution from #Erno, because the shaders used are 3rd party.
Option 1
Just before the object is rendered, set the far plane to 100,000 and set it back to 1000 after drawing the sky.
Problem: The depth buffer is still filled with values between very low and 100,000. This decreases the accuracy of the depth buffer and gives problems with z-fighting and post-effects that depend on the depth buffer.
Option 2
Create two cameras that are linked to each other. Camera 1 renders the skydome first with a setting of far = 100000, near = 100. Camera 2 clears the depth buffer and draws the rest of the scene with a setting of far = 1000, near = 0.3. The depth buffer doesn't contain big values now, so that solves the problems of inaccurate depth buffers.
Problem: The cameras have to be linked by some polling system, because there are no change events on the camera class (e.g. when FoV changes). I like the fact that there is only one camera, but this doesn't seem possible quite easily.
Ok, this might sound like a stupid question but i want to know if there is any recommendations on how to animate objects as smoothly and quickly as possible when you know you will have low framerate.
What my animation does is that i move approximately 10 2d-rectangles(containing a texture each) about 500 pixels in both x and y and i also scale them down to maybe 30% from about 1000*1000px. I want the animation to complete in around 200ms. I estimate the framerate to be maybe 20-30fps.
I have tried different timings and movement-velocities but they all look like crap. If you have high speed you barely see the animation and if you have slow speed it looks smooth but it takes way to much time.
Has there been any research done on how to do a quick animation that still looks like it's running smooth. I was thinking that you maybe could have acceleration that goes slow in the beginning and then jumpy at the end, or maybe the other way around? My own experiments all look both jumpy and slow :P
There has to be some limit in pixels/frame that we humans think look good. Where can i find guidelines like this?
Why do i want to know this?
I've made a window-switching app that does some cool animations but the problem is that when i'm not running any graphic-intense application my graphic-card goes down into some low power mode. This causes my application, that doesn't run for more than 3secs at a time, to perform very poorly because the gfx-card never has time to speed up.
(You can probably try this yourself if you have a laptop and vista: press win+tab and you will see that the animation is a bit choppy, then start a movie and press win+tab again, this time the animation is much more smooth).
You should be able to get reasonable looking animation at around 15fps, if the movements are small. Realise that there is a limit on fitting high-bandwith graphics information (lots of movement and shape/color change) into a low-bandwidth medium (low fps), but techniques like motion blur will help.
Also, look into double- or triple- buffering, ideally sync'd to the monitor's vertical refresh, which will all help to reduce flicker and tearing that can distract from the animation.
If your animations are purely two-dimensional (for example, rigid shifts of window content), then you can improve their smoothness by pixel-locking them to the video frame. A motion of exactly N pixels per frame looks smooth even at very low framerates, whereas if you have some left-over fraction of a pixel, you get aliases from the pixel sampling which can be noticeable.
Motion blur is in theory the way to make motions look smooth but proper motion blur is expensive, so if you're already having trouble with the framerate then motion blur is probably only going to make things worse. But there may be some way of reducing the cost, for example if the motion is in a constant direction and speed then you could render a single blurred image and use that. Or maybe overdraw partially-transparent copies of the moving image several times to get a "trail".