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
Bug in SDL_CreateTextureFromSurface ?
zweifel


Joined: 17 Nov 2016
Posts: 3
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<iostream>

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;
}
Bug in SDL_CreateTextureFromSurface ?
Daniel Gibson
Guest

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:
Quote:
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

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org


_______________________________________________
SDL mailing list

http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org