Problem with SDL_UpdateTexture when altering surface pixels

Hi,

I’m having a bit of a problem with SDL_UpdateTexture() - I’m using SDL2 on Windows 7.

Basically I’m developing a simple image viewer to get used to the new API. I first load the image to a surface (IMG_Load()), and then use SDL_CreateTextureFromSurface(). So far so good.

The problem arises when I alter the SDL_Surface’s pixels directly and then call SDL_UpdateTexture(). The window is 640x480 but the image is 476x334 pixels. SDL automatically scales this. But with SDL_UpdateTexture(), I have two courses of action.

  1. If I set the second parameter (rect) to NULL, the image doesn’t scale, and looks a bit messed up. It still fills the area of the window, but it’s kind of tiled.

  2. If I set the second parameter to a rect with width 640 and height 480, the image in the window just doesn’t get updated at all.

Is there any way that I can alter pixels, update the texture, and get scaling for free as well?

Thanks,

Daniel

Here’s example code to replicate the problem. I removed the code that would mess with the pixels; just using SDL_UpdateTexture() is enough.

Code:

#include
#include

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

using std::stringstream;
using std::string;

string IntToString(int x)
{
stringstream ss;
ss << x;
return ss.str();
}

void ShowError(const char * title, SDL_Window * window)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, SDL_GetError(), window);
}

void ShowDebug(const char * title, int x, SDL_Window * window)
{
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, title, IntToString(x).c_str(), window);
}

int main(int argc, char ** argv)
{
if (argc == 2)
{
bool quit = false;
SDL_Event event;

	SDL_Init(SDL_INIT_VIDEO);

	SDL_Window * window = SDL_CreateWindow("Picaxo3", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, 0);
	if (window != NULL)
	{
		SDL_Renderer * renderer = SDL_CreateRenderer(window, -1, 0);
		if (renderer != NULL)
		{
			char * filename = argv[1];
			SDL_Surface * image = IMG_Load(filename);
			if (image != NULL)
			{
				SDL_Texture * texture = SDL_CreateTextureFromSurface(renderer, image);
				if (texture != NULL)
				{
					while (!quit)
					{
						SDL_WaitEvent(&event);

						switch(event.type)
						{
						case SDL_QUIT:
							quit = true;
							break;
						case SDL_KEYDOWN:
							switch(event.key.keysym.scancode)
							{
							case SDL_SCANCODE_ESCAPE:
								quit = true;
								break;
							}
							break;
						}

						if (SDL_UpdateTexture(texture, NULL, image->pixels, image->pitch) < 0)
							ShowError("Update texture failed", window);

						if (SDL_RenderClear(renderer) < 0)
							ShowError("Render clear failed", window);
						if (SDL_RenderCopy(renderer, texture, NULL, NULL) < 0)
							ShowError("Render copy failed", window);
						SDL_RenderPresent(renderer);
					}

					SDL_DestroyTexture(texture);
				}
				else
					ShowError("Create texture failed", window);

				SDL_FreeSurface(image);
			}
			else
				ShowError("Load image failed", window);

			SDL_DestroyWindow(window);
			SDL_Quit();
		}
		else
			ShowError("Create renderer failed", window);
	}
	else
		ShowError("Create window failed", window);
}
else
{
	// TODO printf usage
}

return 0;

}