Discussion:
[SDL] Bug in SDL_CreateTextureFromSurface ?
zweifel
2016-11-21 08:06:24 UTC
Permalink
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;
}
Daniel Gibson
2016-11-21 14:27:25 UTC
Permalink
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
Post by 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.
#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)
{
{
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
Loading...