Sign in to follow this  
XTAL256

Problem loading image (using SOIL)

Recommended Posts

Hi, i am trying to load an image using SOIL but i am having problems. I'm not sure if this is a problem with the SOIL or my code. If i load using SOIL_load_OGL_texture it works fine, no problem. But i need to get the image's original width & height, i.e. before it is scaled to a power-of-two size for OpenGL. So i want to do this:
// Member variables:
    int width, height;
    int origWidth, origHeight;
    GLuint id;
void Image::load(String filename, int type) {
    unsigned char* img;         // Temporary image data
    int ch;                     // Number of channels the original image had

    img = SOIL_load_image(filename.c_str(), &origWidth, &origHeight, &ch, type);
    if (img == NULL)            // Throw error if load fails
        throw ImageError("Could not load image \""+filename+"\"\n"+SOIL_last_result());

    this->id = SOIL_load_OGL_texture_from_memory(img, 
                    origWidth*origHeight*sizeof(char), type,
                    SOIL_CREATE_NEW_ID, SOIL_FLAG_MULTIPLY_ALPHA);
    getTexWidth(width);         // Get new (power of two) size
    getTexHeight(height);
    SOIL_free_image_data(img);  // Delete temporary data

    if (this->id == 0)          // Throw error if load fails
        throw ImageError("Could not create image \""+filename+"\"\n"+SOIL_last_result());

When i debug, img has the value 0x01ea0040 after SOIL_load_image. But after SOIL_load_OGL_texture_from_memory, id is 0. It seems that it loads ok but can't create the texture. The error result from SOIL_last_result() is "Image not of any known type, or corrupt". If anyone could help me that would be great, the full source code can be downloaded here thanks

Share this post


Link to post
Share on other sites
Hello XTAL256,

From a quick look at the SOIL documentation I don't think you can use SOIL_load_OGL_texture_from_memory on the image returned by SOIL_load_image. As SOIL_load_image returns a pointer to an array of pixels (after decoding the image file format). And SOIL_load_OGL_texture_from_memory is expecting its buffer to contain the data in one of the file image formats ( TGA, PNG, BMP, etc. ) - an image before it has been decoded.

From the SOIL documentation:

/**
Loads an image from RAM into an OpenGL texture.
\param buffer the image data in RAM just as if it were still in a file
...snip...
**/
unsigned int
SOIL_load_OGL_texture_from_memory
(
const unsigned char *const buffer,
int buffer_length,
int force_channels,
unsigned int reuse_texture_ID,
unsigned int flags
);



I suggest you try using SOIL_create_OGL_texture instead of SOIL_load_OGL_texture_from_memory which appears to create a texture from raw image data.

Again a snippet from the SOIL documentation:

/**
Creates a 2D OpenGL texture from raw image data. Note that the raw data is
_NOT_ freed after the upload (so the user can load various versions).
\param data the raw data to be uploaded as an OpenGL texture
\param width the width of the image in pixels
\param height the height of the image in pixels
\param channels the number of channels: 1-luminous, 2-luminous/alpha, 3-RGB, 4-RGBA
\param reuse_texture_ID 0-generate a new texture ID, otherwise reuse the texture ID (overwriting the old texture)
\param flags can be any of SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_MIPMAPS |
SOIL_FLAG_TEXTURE_REPEATS | SOIL_FLAG_MULTIPLY_ALPHA | SOIL_FLAG_INVERT_Y |
SOIL_FLAG_COMPRESS_TO_DXT
\return 0-failed, otherwise returns the OpenGL texture handle
**/
unsigned int
SOIL_create_OGL_texture
(
const unsigned char *const data,
int width, int height, int channels,
unsigned int reuse_texture_ID,
unsigned int flags
);


As an aside the "this->" pointer is optional* when accessing member data and it's a matter of personal preference whether to write it or not, but I would suggest you are consistent and use it everywhere or not at all (i.e. on width, height, origWidth, origHeight and id)

I should also point out that most people omit a "this" pointer and name their data members to indicate that they belong to a class instance, typical prefixes are things like "m_" and "my" (m_Id or myId).

*Sometimes it might be necessary to qualify data member access with a "this" pointer, for instance if local variables are using the same name as the member data (and possibly when working with templates, but I wouldn't worry about that)

Cheers,

Tom

Share this post


Link to post
Share on other sites
Quote:
Original post by TomH
I suggest you try using SOIL_create_OGL_texture instead of SOIL_load_OGL_texture_from_memory which appears to create a texture from raw image data.

Ah, of course. When i changed my code (from using SOIL_load_OGL_texture) i was thinking that i needed to load the image then create OGL texture from it, but the SOIL_create_OGL_texture function must have slipped my mind.
thanks

Quote:
Original post by TomH
As an aside the "this->" pointer is optional* when accessing member data and it's a matter of personal preference whether to write it or not, but I would suggest you are consistent and use it everywhere or not at all (i.e. on width, height, origWidth, origHeight and id)

I should also point out that most people omit a "this" pointer and name their data members to indicate that they belong to a class instance, typical prefixes are things like "m_" and "my" (m_Id or myId).

I don't like Hungarian Notation, i think it goes against the idea of scope. It's ok for C but in C++ names should not carry and extra information, that's what "this->" is for. I guess i should be consistent, i just can't be bothered writing "this->" everywhere.

Share this post


Link to post
Share on other sites
I'm happy to be of help.

Quote:

I don't like Hungarian Notation, i think it goes against the idea of scope. It's ok for C but in C++ names should not carry and extra information, that's what "this->" is for. I guess i should be consistent, i just can't be bothered writing "this->" everywhere.


Technically this is not Hungarian Notation which deals with type information not scope information* ( variable is int, rather than variable is member data ) Personally I find a naming convension that help distingish between: member (instance) data, class (static) data and function scoped variables very useful. However (flame) wars have been fought over much less than discussions on variable naming so time for me to shutup :)

*Actually some variants Hungarian Notation also include scope information, but I'd argue that if you remove type information you are no longer using Hungarian Notation.

Cheers,

Tom

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this