Surface, Texture and Scaling

Dear All,

I have a couple of question:

  1. What’s the difference between Texture and Surface? It seems that most of the time I have to create Surface and then creating a Texture with SDL_CreateTextureFromSurface

  2. When I copy the Texture to the Rendere with SDL_RenderCopy I can use both srcrect and dstrect. If I understood correctly srcrect is used for “sprite” so that I can crop the image, but dstrect is used both for positioning and streching. How can I set position by avoiding streching ? It’s kind of hard avoiding the streching when rendering text (I don’t know how to calculate the width)

Thank you again!

Surface is stored in RAM and drawing is performed on the CPU. Texture is stored in Video RAM (GPU RAM) and drawing is performed by the GPU. If you need best performance, use textures only, because GPU can render things million times faster than the CPU.

No, you don’t need to use surfaces at all. You can create texture using the SDL_CreateTexture function and render anything on it. If you need to load image e.g. from file and store it in the form of texture, you can do it via IMG_LoadTexture function — SDL will do everything for you internally.

Correct.

Write some more what stretching you are talking about. Do you want to render the texture with original size or using stretching but keeping correct aspect ratio?

Is there any sort TTF_CreateText_Solid that I can use instead of TTF_RenderText_Solid ?

I have two issue about streching:

  1. Related TTF I would like set the Text to a specific position but I don’t know the width of the text that I’m generating, how can I achive that?
  2. Related to image I would like to strech image without changing aspect ratio

Thank you in advance :slight_smile:

Here’s how you would get the sizes out of a ttf delivered surface (or any surface really):

	SDL_Texture * banner = NULL;
	SDL_Rect bRect = {10, 10, 100, 100};
	SDL_Surface * temp = TTF_RenderText_Solid(ptr_myFont, "THIS IS A BANNER!!!", color);
	if(temp)
	{
		bRect.w = temp->w;
		bRect.h = temp->h;
		banner = SDL_CreateTextureFromSurface(renderer, temp);
        SDL_FreeSurface(temp);
	}

// later, in the drawing section:

	SDL_RenderCopy(renderer, banner, NULL, &bRect);

If you would like to scale an image while maintaining the same aspect ratio, then multiply the rectangle w and h by any scalar value:

// just don't let the scalar be a negative number
// SDL_RenderCopy doesn't like it's rectangles to be size-negative.
void scaleRect(SDL_Rect &pos, float scalar)
{
  pos.w = ((float) pos.w) * scalar;
  pos.h = ((float) pos.h) * scalar;
}

Here’s some other “helpful hints”

void setRectPosition(SDL_Rect &pos, int x, int y)
{
  pos.x = x;
  pos.y = y;
}
void moveRect(SDL_Rect &pos, int x, int y)
{
  pos.x += x;
  pos.y += y;
}
// again: error checking to avoid negative width and height could be used
void resizeRect(SDL_Rect &pos, int w, int h)
{
  pos.w = w;
  pos.h = h;
}

Hope that helps.

You can also query the texture to get it’s original size, which is the size of the surface that it was created from: → SDL2/SDL_QueryTexture - SDL Wiki

Or you can use SDL_SetRenderTarget(renderer, texture); and then use SDL_GetRendererOutputSize(renderer, &width, &height);SDL2/SDL_GetRendererOutputSize - SDL Wiki
(Please note that in SDL3 this function has changed names to → SDL3/SDL_GetCurrentRenderOutputSize - SDL Wiki
(Even though I’m kind of joking, I have used this version in a pinch for some reason or other that I don’t remember.)

TTF_SizeUTF8() or TTF_SizeUnicode() or TTF_SizeText() (as appropriate) will tell you the size of the text without actually rendering it.