PDA

View Full Version : Loading a texture



Daniel Harrison
01-06-2011, 09:03 AM
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 (http://en.wikibooks.org/wiki/OpenGL_Programming/Intermediate/Textures#A_simple_libpng_example).

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, &amp;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(&amp;png_ptr, &amp;info_ptr, &amp;end_info);
delete[] image_data;
delete[] row_pointers;
//fclose(file);
return texture;
}
else
{
ReportAssetError((char*)"unsupported format", path, 0);
}
}
}

randall
01-06-2011, 10:45 AM
I recommend using stb_image lib for png loading it is much simpler. Follow link in my signature to see example code.

Daniel Harrison
01-06-2011, 11:18 AM
Alrighty, thank you. :D

mhagain
01-06-2011, 11:19 AM
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.)

Daniel Harrison
01-06-2011, 12:00 PM
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.