Loading a texture

I am tearing my hair out over something that originally appeared a simple task, displaying an image in OpenGL.

It’s not drawing the image on-screen that I find difficult, it’s loading the image in the first place.

My texture is stored in PNG format and I read it using libpng, loosely following the example here.

Before I post my code, I would greatly appreciate it if somebody could send me a working example of displaying a PNG image (cross platform too, please :D).

Segmentation error occurs near the bottom where the comment is:


GLuint LoadTexture(char * path)
{
    FILE * file = fopen(path, "rb");
    if (!file)
    {
        ReportAssetError((char*) "missing texture", path, 0);
    }
    else
    {
        unsigned char * header;
        header = (unsigned char *) malloc(8);
        fread(header, 1, 8, file);
        bool is_png = !png_sig_cmp(header, 0, 8);
        delete header;
        if (is_png)
        {
            png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
            png_infop info_ptr = png_create_info_struct(png_ptr);
            png_infop end_info = png_create_info_struct(png_ptr);
            png_init_io(png_ptr, file);
            png_set_sig_bytes(png_ptr, 8);
            png_read_info(png_ptr, info_ptr);
            int bit_depth, color_type;
            png_uint_32 width, height;
            png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL);
            png_read_update_info(png_ptr, info_ptr);
            int row_bytes = png_get_rowbytes(png_ptr, info_ptr);
            png_bytep * row_pointers = new png_bytep[height];
            png_byte * image_data = new png_byte[row_bytes * height];
            if(!image_data)
            {
                // error
                png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
                fclose(file);
                ReportAssetError((char*)"error reading file", path, 0);
            }
            for(int i = 0; i < height; i++)
            {
                row_pointers[height - 1 - i] = image_data + i * row_bytes;
            }
            png_read_image(png_ptr, row_pointers);
            GLuint texture;
            glGenTextures(1, &texture);
            glBindTexture(GL_TEXTURE_2D, texture);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)image_data); // Segmentation error
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
            png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
            delete[] image_data;
            delete[] row_pointers;
            //fclose(file);
            return texture;
        }
        else
        {
            ReportAssetError((char*)"unsupported format", path, 0);
        }
    }
}

I recommend using stb_image lib for png loading it is much simpler. Follow link in my signature to see example code.

Alrighty, thank you. :smiley:

What value are you getting for bit_depth? I’m not too familiar with libpng, but it sounds an awful lot like you’re loading a 24-bit image and overflowing a buffer. (Confirm by changing the format parameter of your glTexImage2D to GL_RGB.)

Oh, bit late now, sorry.

Got started on deciphering stb_image as I posted last, managed to load the image but when I try and display it I just get a white square.

I’ll take your advice into account for when I decide to re-write what I’ve already done which will probably be pretty soon.