The SDL forums have moved to discourse.libsdl.org.
This is just a read-only archive of the previous forums, to keep old links working.


SDL Forum Index
SDL
Simple Directmedia Layer Forums
Problem with SDL_UpdateTexture when altering surface pixels
dandago


Joined: 30 Aug 2013
Posts: 34
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
dandago


Joined: 30 Aug 2013
Posts: 34
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 <iostream>
#include <sstream>

#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;
}