Bug in SDL_CreateTextureFromSurface ?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Bug in SDL_CreateTextureFromSurface ?

zweifel
Hi,

I loaded an image which the pixel format is ABGR. However, it seems that when I create a texture from a surface SDL2 does not keep the format of the surface. And therefore, if I try to update it later with SDL_UpdateTexture() I get inverted red and blue channels (i.e., it seems to think the image is in ARGB format).
I had to use SDL_CreateTexture and explicitly set the format for it to work as expected.

If anybody can confirm this I will file a bug.

The code is as follows. By changing the way the texture is made, the final result changes.








Code:


#include"SDL2/SDL.h"
#include"SDL2/SDL_image.h"
#include

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

   SDL_Init(SDL_INIT_VIDEO);

   SDL_Surface* image= IMG_Load("image3.png");
   int image_height=image->h;
   int image_width=image->w;
   int bpp = (int) image->format->BytesPerPixel;
   std::cout << "Bpp " << bpp << "Size "<< image->w << image->h << std::endl;
   SDL_PixelFormat* pixel_format = image->format;
   Uint32 pixelFormatEnum = pixel_format->format;
   const char* surface_pixel_format = SDL_GetPixelFormatName(pixelFormatEnum);
   std::cout << "Format " << surface_pixel_format << std::endl;


   SDL_Window* window= SDL_CreateWindow("Convolution", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, image_width/2, image_height/2, 0);

   SDL_Renderer* renderer= SDL_CreateRenderer(window, -1, 0);

   
   
   SDL_Texture* texture= SDL_CreateTextureFromSurface(renderer, image);

   //SDL_Texture* texture= SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, image->w, image->h);
   
   
   SDL_UpdateTexture(texture, NULL, image->pixels, image->pitch);

   //SDL_LockTexture(texture, NULL, &image->pixels, &image->pitch);
   //SDL_UnlockTexture(texture);
      
   while(!quit)
   {
   

      SDL_WaitEvent(&event);

      switch(event.type)
      {
         case SDL_QUIT:
         {
            quit=true;
         }
         break;
      }

      SDL_RenderCopy(renderer, texture, NULL, NULL);
      SDL_RenderPresent(renderer);
   }

   SDL_DestroyTexture(texture);
   SDL_FreeSurface(image);
   SDL_DestroyRenderer(renderer);
   SDL_DestroyWindow(window);

   SDL_Quit();

   return 0;
}

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Reply | Threaded
Open this post in threaded view
|

Re: Bug in SDL_CreateTextureFromSurface ?

Daniel Gibson
Hi,

I don't think this is a bug: SDL_CreateTextureFromSurface() converts the
pixels to a format best suited for the renderer.

Also, note how SDL_UpdateTexture() does *not* take a SDL_Surface as
input, but a void pointer to "raw pixel data".
This means the function does not "know" how to convert image surface to
the internally used format.
Maybe use SDL_QueryTexture() to get the texture's raw format and convert
your surface to that?
(I don't think you can expect your currently commented out code to
always work, as the render is not guaranteed to support any specific
pixelformat you might set in SDL_CreateTexture())

Cheers,
Daniel

On 21.11.2016 09:06, zweifel wrote:

> Hi,
>
> I loaded an image which the pixel format is ABGR. However, it seems that
> when I create a texture from a surface SDL2 does not keep the format of
> the surface. And therefore, if I try to update it later with
> SDL_UpdateTexture() I get inverted red and blue channels (i.e., it seems
> to think the image is in ARGB format).
> I had to use SDL_CreateTexture and explicitly set the format for it to
> work as expected.
>
> If anybody can confirm this I will file a bug.
>
> The code is as follows. By changing the way the texture is made, the
> final result changes.
>
>
>
>
>
>
>
>
> Code:
>
>
> #include"SDL2/SDL.h"
> #include"SDL2/SDL_image.h"
> #include
>
> int main(int argc, char** argv)
> {
>    bool quit= false;
>    int filter_size=2;
>
>    SDL_Event event;
>
>    SDL_Init(SDL_INIT_VIDEO);
>
>    SDL_Surface* image= IMG_Load("image3.png");
>    int image_height=image->h;
>    int image_width=image->w;
>    int bpp = (int) image->format->BytesPerPixel;
>    std::cout << "Bpp " << bpp << "Size "<< image->w << image->h <<
> std::endl;
>    SDL_PixelFormat* pixel_format = image->format;
>    Uint32 pixelFormatEnum = pixel_format->format;
>    const char* surface_pixel_format =
> SDL_GetPixelFormatName(pixelFormatEnum);
>    std::cout << "Format " << surface_pixel_format << std::endl;
>
>
>    SDL_Window* window= SDL_CreateWindow("Convolution",
> SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, image_width/2,
> image_height/2, 0);
>
>    SDL_Renderer* renderer= SDL_CreateRenderer(window, -1, 0);
>
>
>
>    SDL_Texture* texture= SDL_CreateTextureFromSurface(renderer, image);
>
>    //SDL_Texture* texture= SDL_CreateTexture(renderer,
> SDL_PIXELFORMAT_ABGR8888, SDL_TEXTUREACCESS_STREAMING, image->w, image->h);
>
>
>    SDL_UpdateTexture(texture, NULL, image->pixels, image->pitch);
>
>    //SDL_LockTexture(texture, NULL, &image->pixels, &image->pitch);
>    //SDL_UnlockTexture(texture);
>
>    while(!quit)
>    {
>
>
>       SDL_WaitEvent(&event);
>
>       switch(event.type)
>       {
>          case SDL_QUIT:
>          {
>             quit=true;
>          }
>          break;
>       }
>
>       SDL_RenderCopy(renderer, texture, NULL, NULL);
>       SDL_RenderPresent(renderer);
>    }
>
>    SDL_DestroyTexture(texture);
>    SDL_FreeSurface(image);
>    SDL_DestroyRenderer(renderer);
>    SDL_DestroyWindow(window);
>
>    SDL_Quit();
>
>    return 0;
> }
>
>
>
> _______________________________________________
> SDL mailing list
> [hidden email]
> http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
>

_______________________________________________
SDL mailing list
[hidden email]
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org