Am I doing something wrong?

I’m using LodePNG (which has been proven to work for me) to load a 32x32 png image that I use to create an SDL_Texture, then render it to the screen.

I’m using the Direct3D render on Windows (it’s what SDL chooses for me, I only ask for hardware accelerated double buffered).

Code:

Graphic::Graphic(const char* fname, unsigned long format)
{
m_width = 0;
m_height = 0;
m_texture = NULL;

unsigned char* buffer;
unsigned char* image;
size_t buffersize, imagesize;
LodePNG_Decoder decoder;

LodePNG_loadFile(&buffer, &buffersize, fname); /*load the image file with given filename*/
LodePNG_Decoder_init(&decoder);
LodePNG_decode(&decoder, &image, &imagesize, buffer, buffersize); /*decode the png*/

/*load and decode*/
/*if there's an error, display it, otherwise display information about the image*/
if(decoder.error) printf("PNG Decoding error: %d\n", decoder.error);
else
{
    m_width = decoder.infoPng.width;
    m_height = decoder.infoPng.height;
    m_texture = SDL_CreateTexture(format, SDL_TEXTUREACCESS_STATIC, m_width, m_height);
    if(!m_width || !m_height || !m_texture){
        SDL_DestroyTexture(m_texture);
        printf("Error: SDL could not build texture: %s\n", SDL_GetError());
        m_width = m_height = -1;
        m_texture = NULL;
    }
    else {
        SDL_UpdateTexture(m_texture, NULL, image, 0);
    }
}
free(image);
free(buffer);
LodePNG_Decoder_cleanup(&decoder);

}


while(true){
SDL_Rect loc;
loc.x = loc.w = loc.y = loc.h = 32;
Graphic testSprite(“testimg.png”, info.texture_formats[0]);
SDL_RenderCopy(testSprite.getTexture(), &loc, NULL);
SDL_RenderPresent();
SDL_Delay(1);
}

The result is that the window contents get messed up, and nothing looking like the image is even rendered.

is there anything I’m doing wrong here?------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

You do not convert PNG colors to screen pixel format.

Code:

Graphic::Graphic(const char* fname, unsigned long format)
{
m_width = 0;
m_height = 0;
m_texture = NULL;

unsigned char* buffer;
unsigned char* image;
size_t buffersize, imagesize;
LodePNG_Decoder decoder;

LodePNG_loadFile(&buffer, &buffersize, fname); /*load the image file

with given filename*/
LodePNG_Decoder_init(&decoder);

LodePNG_decode(&decoder, &image, &imagesize, buffer, buffersize);

/decode the png/

/*load and decode*/
/*if there's an error, display it, otherwise display information about

the image*/
if(decoder.error) printf(“PNG Decoding error: %d\n”, decoder.error);
else
{
m_width = decoder.infoPng.width;
m_height = decoder.infoPng.height;

//Image is loaded as 32-bit RGBA, so specify it to SDL, so it will convert
it to display pixel format
m_texture = SDL_CreateTexture(SDL_PIXELFORMAT_RGBA8888,
SDL_TEXTUREACCESS_STATIC, m_width, m_height);> if(!m_width || !m_height || !m_texture){

        SDL_DestroyTexture(m_texture);
        printf("Error: SDL could not build texture: %s\n",

SDL_GetError());
m_width = m_height = -1;
m_texture = NULL;
}
else {
SDL_UpdateTexture(m_texture, NULL, image, 0);
}
}
free(image);
free(buffer);
LodePNG_Decoder_cleanup(&decoder);
}


while(true){
SDL_Rect loc;
loc.x = loc.w = loc.y = loc.h = 32;
Graphic testSprite(“testimg.png”, info.texture_formats[0]);
SDL_RenderCopy(testSprite.getTexture(), &loc, NULL);
SDL_RenderPresent();
SDL_Delay(1);
}

The result is that the window contents get messed up, and nothing looking
like the image is even rendered.

is there anything I’m doing wrong here?


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Oh.

But if I do that, I then get an error that it’s an invalid texture.------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Then you should call SDL_CreateRGBSurfaceFrom(image, m_width, m_height, 32,
0, 0xff, 0x00ff, 0x0000ff, 0x000000ff), then convert it to display format
using SDL_DisplayFormatAlpha(), and call SDL_CreateTextureFromSurface() on
converted surface.On Fri, May 28, 2010 at 3:17 PM, Nathaniel J Fries wrote:

Oh.

But if I do that, I then get an error that it’s an invalid texture.


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Okay, update:

I tried the OpenGL engine, it has the same result.

The software engine creates the texture just fine, but does not render it.

The GDI engine also creates the texture just fine, but renders nothing (not even a black background).

I’ll try other stuff.------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

So, trying other stuff:

  1. Lines and filled rects work on all renderers except for software. This is good, because at least I can begin working until I can get the issue fixed.

  2. I switched from trying a PNG image to a bitmap image, and am using a function for loading bitmaps that I wrote back in '07 and know to have worked perfectly with Direct3D, DirectDraw, and OpenGL. I’m having the same issues, so I know it’s not some unexpected flaw in LodePNG.

To reiterate: I’m getting “Invalid texture” errors for every renderer except for software using SDL_PIXELFORMAT_RGB24 (it’s a 24-bit bitmap I’m loading).
Software is still not rendering it (or even lines and rects for that matter), though.------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Try to use SDL_LoadBMP() - it will fill out all fields in SDL_Surface
properly, then you can try to convert it to the display pixel format.

Well, it did output some garbage instead of image with your first example -
that should mean you’re trying to output 32-bit RGBA as 24-bit RGB, and it
reads wrong pixels, or something like that.On Fri, May 28, 2010 at 8:59 PM, Nathaniel J Fries wrote:

So, trying other stuff:

  1. Lines and filled rects work on all renderers except for software. This
    is good, because at least I can begin working until I can get the issue
    fixed.

  2. I switched from trying a PNG image to a bitmap image, and am using a
    function for loading bitmaps that I wrote back in '07 and know to have
    worked perfectly with Direct3D, DirectDraw, and OpenGL. I’m having the same
    issues, so I know it’s not some unexpected flaw in LodePNG.

To reiterate: I’m getting “Invalid texture” errors for every renderer
except for software using SDL_PIXELFORMAT_RGB24 (it’s a 24-bit bitmap I’m
loading).
Software is still not rendering it (or even lines and rects for that
matter), though.


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

pelya wrote:

Try to use SDL_LoadBMP() - it will fill out all fields in SDL_Surface properly, then you can try to convert it to the display pixel format.

Well, it did output some garbage instead of image with your first example - that should mean you’re trying to output 32-bit RGBA as 24-bit RGB, and it reads wrong pixels, or something like that.

I tried both RGB8888 and RGBA8888 with LodePNG, which always converts the format to 32-bit PNG unless you specify otherwise (which I don’t). It also reports 8-bit color channel, so I know one of those two must’ve been right. I also tried RGB24 (which looked to me like 24 bbp) for PNG just-in-case as well as for the bitmap, and in all cases “Invalid texture” was the report for SDL_GetError().

I can try SDL_LoadBMP later today (I’m marching in a parade in about an hour), but I was really hoping I wouldn’t need to mess with surfaces for something this simple. If it works I guess I’ll build SDL_Image against SDL1.3 and try IMG_Load for PNGs, but I was really hoping for the SDL core to be the only dependency for this simple app I’m making…------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

After using SDL_LoadBMP with SDL_CreateTextureFromSurface, I’m getting varied results on different renderers.

  1. D3D and GDI engines return NULL from SDL_CreateTextureFromSurface with “Invalid texture” as before.
  2. OpenGL succeeds in SDL_CreateTextureFromSurface but still does not render the image.------------------------
    EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Now working on Linux.

OpenGL has the same effect as on Windows, but doesn’t render lines properly for some reason.
Software actually renders lines now! No change with the texture issues, though.
X11 renderer fails with error: “Invalid texture”, as the GDI and D3D renderers on Windows did. Also doesn’t render lines properly.

In case anyone’s wondering:

  1. Windows is Windows XP Pro SP3, on a laptop using an older onboard Intel GPU.
  2. Linux distro I’m using is Ubuntu 10.4, pretty much just installed last night. It’s on a refurbished desktop I bought for $250, dunno what the GPU is but it’s definitely on the motherboard (so probably an older Intel as well).------------------------
    EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Try using SDL_DisplayFormat() or SDL_DisplayFormatAlpha() and creating
a texture from the surface that produces. Otherwise, use
SDL_ConvertSurface() to convert it to a specific format.On 29/05/2010, Nathaniel J Fries wrote:

After using SDL_LoadBMP with SDL_CreateTextureFromSurface, I’m getting
varied results on different renderers.

  1. D3D and GDI engines return NULL from SDL_CreateTextureFromSurface with
    "Invalid texture" as before.
  2. OpenGL succeeds in SDL_CreateTextureFromSurface but still does not render
    the image.

Kenneth Bull wrote:> On 29/05/2010, Nathaniel J Fries <@Nathaniel_J_Fries> wrote:

After using SDL_LoadBMP with SDL_CreateTextureFromSurface, I’m getting
varied results on different renderers.

  1. D3D and GDI engines return NULL from SDL_CreateTextureFromSurface with
    "Invalid texture" as before.
  2. OpenGL succeeds in SDL_CreateTextureFromSurface but still does not render
    the image.

Try using SDL_DisplayFormat() or SDL_DisplayFormatAlpha() and creating
a texture from the surface that produces. Otherwise, use
SDL_ConvertSurface() to convert it to a specific format.


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

I guess you can’t tell from the mailing list 'cause I edited my post, but I had figured everything out.
There’s a few more things I’ve figured out, too, that might be useful to someone so I’ll state them.

  1. At least on Windows (maybe X11 renderer is different), each of the renderers support “SDL_PIXELFORMAT_ARGB8888”
  2. SDL_PIXELFORMAT_ARGB8888 is actually 8 bits of blue, 8 bits of green, 8 bits of red, and 8 bits of alpha; I found out when converting to that format from RGBA
  3. OpenGL engine works with a pitch of 0 when using SDL_UpdateTexture, for GDI and D3D however you need to specify that it’s the width of the image times the bitsperpixel of the image data in the proper format.
  4. When using SDL_CreateTextureFromSurface, specifying 0 (zero) as the texture format will cause the function to automatically choose the format for you.

Oh, and: The Texture API is honestly a little more confusing than it looked at first. Once you figure it out, though, it’s not that bad. One way to make it simpler would be to allow pixels to be added to the texture at creation using SDL_CreateTexture, and then auto-conversion from whatever format you specified when making the texture to one that the renderer wants. This would ease transition between renderers greatly and increase general consistency, which I at least value quite a bit from the libraries I use.


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

SDL_CreateTextureFromSurface does not respect the surface’s colorkey (using this with SDL_TTF to make a cached texture containing the text).

Currently working around by blitting to a 32-bit bitmap first, this is working well.------------------------
EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Good spot to use stencils…On 31/05/2010, Nathaniel J Fries wrote:

SDL_CreateTextureFromSurface does not respect the surface’s colorkey (using
this with SDL_TTF to make a cached texture containing the text).

Currently working around by blitting to a 32-bit bitmap first, this is
working well.

Kenneth Bull wrote:> On 31/05/2010, Nathaniel J Fries <@Nathaniel_J_Fries> wrote:

SDL_CreateTextureFromSurface does not respect the surface’s colorkey (using
this with SDL_TTF to make a cached texture containing the text).

Currently working around by blitting to a 32-bit bitmap first, this is
working well.

Good spot to use stencils…


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

Explain?


EM3 Nathaniel Fries, U.S. Navy

http://natefries.net/

Kenneth Bull wrote:

SDL_CreateTextureFromSurface does not respect the surface’s colorkey
(using
this with SDL_TTF to make a cached texture containing the text).

Currently working around by blitting to a 32-bit bitmap first, this is
working well.

Good spot to use stencils…

Explain?

Actually, nvm. What I was thinking wouldn’t work.

You could use a paletted texture, then set the alpha value for the
clear color to 0, but SDL only supports RGB palettes for textures, not
RGBA (palette entries are hard coded to 3 bytes each in
/src/video/SDL_renderer_gl.c). You’d have to use OpenGL directly. Or
write a patch to fix SDL, which wouldn’t be very hard.On 02/06/2010, Nathaniel J Fries wrote:

On 31/05/2010, Nathaniel J Fries wrote: