stretching image in sdl2 - c++

Is stretching image in sdl2 makes the program slower?
For example if my map tile's native resolution is 32x32 and I stretch it in sdl to and make it 64x64, will it affect the program's speed?
Here's how I load my image:
SDL_Surface *surface = NULL;
SDL_Texture *texture = NULL;
surface = IMG_Load("sample.png");//this is the 32x32 image
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_Rect dstRect = {0, 0, 64, 64};//and I will use this rect for that sample.png in SDL_RenderCopy();

Yes, if will be resized each time when repainting. If you need to have resized tile, you should create cache with resized tiles (resize it on start, and use the cached tile on repaint). SDL_BlitScaled for surface, or SDL_CreateTexture(surface, format, target, width, height) for texture can be used to do it.

Related

Set the pixel format AND create texture from surface in SDL

I am currently trying some things using pixel manipulation and I would like to set the pixel format of a SDL_Surface. The problem here is that I am loading up an image with the SDL_image.h. So I have to create a texture from a surface like this:
surface = IMG_Load(filePath);
texture = SDL_CreateTextureFromSurface(renderer, surface);
So I can't use the following function, which I would like to, or can I?:
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, 640, 480);
The thing is, that I want to set the SDL_PixelFormat to be able to mess around with the pixels. How can I both do this and create the texture based on a surface?
The SDL2 API provides the function SDL_ConvertSurface:
SDL_Surface* SDL_ConvertSurface(SDL_Surface* src,
const SDL_PixelFormat* fmt,
Uint32 flags)
You should be able to do
surface = IMG_Load(filePath);
// Call SDL_ConvertSurface to set the pixel format of the surface you have created.
texture = SDL_CreateTextureFromSurface(renderer, surface);
Reference: https://wiki.libsdl.org/SDL_ConvertSurface

SDL draws images blurred without scaling

I'm working on a project in C++ using SDL (Simple Directmedia Layer) but when I draw a SDL_Texture to the screen it's blurred eventhough it is not scaled.
How the image is loaded:
SDL_Surface* loadedSurface = IMG_Load("image.png");
SDL_Texture* gImage = SDL_CreateTextureFromSurface( gRenderer, loadedSurface);
How the image is drawn to the screen:
SDL_Rect renderQuad = { x, y, width, height };
SDL_RenderCopy(gRenderer, gImage , NULL, &renderQuad );
See image, left is in the program and right is the original:
Is there a parameter a forgot to set? And is it normal that SDL does this?
I'm using SDL 2.0 32-bit on a Windows 8.1 64-bit machine.
Ahead of your call to SDL_CreateTextureFromSurface try calling:
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
According to SDL Wiki this should affect how SDL_CreateTextureFromSurface calls interpolate the surface. "0" should result in nearest neighbour removing the blurring effect you are seeing.

SDL 2.0 sprite draws skewed (transformed) after OpenGL draws

I'm using SDL to create a window and draw OpenGL in it and after drawing OpenGL I use SDL to show sprites (UI). It worked for me on Windows, OSX and NDK but it doesn't work for me on iOS. This is how I draw the sprite:
I create the window:
int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
gWindow = SDL_CreateWindow("example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 800, flags);
I create the renderer:
gRenderer = SDL_CreateRenderer(gWindow, id, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
I load the texture:
SDL_Texture* newTexture = NULL;
SDL_Surface* loadedSurface = SDL_LoadBMP(path.c_str());
newTexture = SDL_CreateTextureFromSurface(gRenderer, loadedSurface);
SDL_FreeSurface(loadedSurface);
That's where I do OpenGL drawing. I load .3ds models, load textures, use blending etc.
And then
I draw the sprite:
dstRect.x = 0.0f;
dstRect.y = 0.0f;
dstRect.w = 128.0f;
dstRect.h = 64.0f;
SDL_RenderCopy(gRenderer, newTexture, NULL , &dstRect);
SDL_RenderPresent(gRenderer);
the result is strange. The sprite shows skewed instead of being drawn in a rectangle.
result http://vvcap.net/db/zHhZwoZa1ng7caeP1BG3.png
What could be the reason of the sprite being transformed like that ? How can I fix this ?
Has anybody had a similar problem ?
It almost looks to me as if the camera transform is rotated slightly around the y-axis and the perspective projection is making it looked skewed.
If the sprite is meant to be draw into the screen-space make sure that you have an orthographic projection enabled before the draw, with the width and height being the size of the physical screen (ie. 480x800).
I didn't find a solution but I just used SDL_RenderCopyEx instead of SDL_RenderCopy and it worked.

SDL (Simple MediaDirect Layer) trying to scale my sprite (character)

I am just trying to scale (make bigger proportionally) my character based on windows weight and height. How can I do that?
I tried SDL_BlitScaled(newsurface, NULL, screen, NULL); but it did not work.
My code:
SDL_Surface* screen = SDL_GetWindowSurface(win);
SDL_Surface* mySprite = IMG_Load( SPRITE_PNG_PATH);
SDL_Rect rcSprite;
rcSprite.x = 250;
rcSprite.y = 100;
SDL_BlitSurface(mySprite, NULL, screen, &rcSprite);
The best way to accomplish this is to have a middle surface, whose width and height are your game's native resolution. You then render the entire frame to this surface, and render that surface to the window using the SDL_BlitScaled function.
For example, if you want your native resolution to be 600x400, you would create a 600x400 surface, blit your character and whatever else to that surface, and then finally scaled blit that surface to the window. If you resize your window to 1200x800, everything will look twice as big.
SDL_Surface* screen = SDL_GetWindowSurface(win);
// Create a surface with our native resolution
int NATIVE_WIDTH = 600;
int NATIVE_HEIGHT = 400;
SDL_Surface* frame = SDL_CreateRGBSurface(0, NATIVE_WIDTH, NATIVE_HEIGHT,
screen->format->BitsPerPixel, screen->format->Rmask,
screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
assert(frameSurface);
SDL_Surface* mySprite = IMG_Load( SPRITE_PNG_PATH);
SDL_Rect rcSprite;
rcSprite.x = 250;
rcSprite.y = 100;
// Blit everything to the intermediate surface, instead of the screen.
SDL_BlitSurface(mySprite, NULL, frame, &rcSprite);
// Once we've drawn the entire frame, we blit the intermediate surface to
// the window, using BlitScaled to ensure it gets scaled to fit the window.
SDL_BlitScaled(frame, NULL, screen, NULL);

Can cairo use SDL_Texture as a render target?

Rendering to an SDL_Surface is possible with Cairo, but my application uses SDL_Renderer and SDL_Texture to take advantage of 2D accelerated rendering.
I am currently creating an SDL_Surface and copying it to a texture with SDL_CreateTextureFromSurface(), but this process is cumbersome and possibly slow (although it's not a bottleneck.) Is there a direct way to draw to a SDL_Texture?
I've figured it out. Streaming SDL_Textures can expose the raw pixels in the ARGB8888 format, which is a format Cairo surfaces can also handle. The Cairo API is low level enough to only require the pixel buffer and pitch.
SDL_Texture *texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
width, height);
void *pixels;
int pitch;
SDL_LockTexture(texture, NULL, &pixels, &pitch);
cairo_surface_t *cairo_surface = cairo_image_surface_create_for_data(
pixels,
CAIRO_FORMAT_ARGB32,
width, height, pitch);
paint(cairo_create(cairo_surface));
SDL_UnlockTexture(texture);
How convenient.