Question

I need to move surfaces around the screen based on certain horizontal and vertical velocities. I need those velocities to be completely random. My idea was to generate random float numbers (in which I succeeded) and use them as the velocities. This way I could have many different velocities, never being too fast or too slow. The problem is: SDL_BlitSurface will only accept a SDL_Rect as the parameter to determine the new rect with which the surface will be drawn, and SDL_Rect is a struct made of 4 ints: two for coordinates and two for dimensions;

Resuming: How to work with precision when blitting surfaces on SDL?

Était-ce utile?

La solution 2

SDL_BlitSurface is working with pixels, and unfortunately you cannot have "half pixels". You should still represent your objects' coordinates as float, but convert them to int when passing them to your SDL_Rect. Since your SDL_Surfaces will always land perfectly on screen pixels, your graphics should always remain crisp.

That being said, to have more precision, I guess you could switch to rendering quads in OpenGL. The hardware will be responsible for calculating the pixel color of your textures when they are not properly aligned with screen pixels, resulting in "fuzzy" textures, but at least you will have total control of their position.

Autres conseils

There is a solution to actually display a surface with a half-pixel precision. There is a performance cost but it renders quite nicely. This is basically how old-school anti-aliasing works: rendering at a higher resolution then downscaling.

win = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0); //create a new rendering window
renderer = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED); //create a new renderer
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");  // make the scaled rendering look smoother.
SDL_RenderSetLogicalSize(renderer, width*2, height*2); //tell the renderer to work internally with this size, it will be scaled back when displayed on your screen

You can find some explanation about the functions here or on the API page here and here.

Now you can use your window as if it was twice bigger but it still outputs at the same size. When you're doing your output, you put the same SDL_Rect in the blitting functions except everything is doubled. That way you can keep half pixel precision. You can get even cleaner output if your sprites have also the increased precision.

You could also do it with quarter pixel precision but the performance cost will be even bigger so it might not be possible in your application. There is also a memory cost because the surfaces are bigger (times four for half pixel precision, sixteen for quarter pixel).

It does not make sense to deal with sub-pixel precision when rendering, as pixels by definition are the smallest addressable element in raster graphics.

You could instead round the position to the nearest integer when rendering, e.g. (Sint16)(x+0.5). The rest of your application can still use coordinates with higher precision if you need it.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top