UINT LoadTexturePNG(LPSTR pszFilename){ UINT uTexture = 0; INT iWidth, iHeight, iBitDepth, iColorType, iRowBytes, i; BOOL bHasAlpha; FILE *hTexture; UCHAR sig[8]; LPBYTE pbData; LPBYTE *pbRowPointers; png_structp png_ptr; png_infop info_ptr; hTexture = fopen(pszFilename, "rb"); fread(&sig, 1, 8, hTexture); if(!png_check_sig(sig, 8)){ //Not a png file fclose(hTexture); return 0; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); if(setjmp(png_ptr->jmpbuf)){ png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(hTexture); return 0; } png_init_io(png_ptr, hTexture); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, (LPUINT)&iWidth, (LPUINT)&iHeight, &iBitDepth, &iColorType, NULL, NULL, NULL); if(iColorType == PNG_COLOR_TYPE_PALETTE){ png_set_expand(png_ptr); } if(iColorType == PNG_COLOR_TYPE_GRAY || iColorType == PNG_COLOR_TYPE_GRAY_ALPHA){ png_set_gray_to_rgb(png_ptr); } if(info_ptr->color_type & PNG_COLOR_MASK_ALPHA || png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)){ bHasAlpha = TRUE; }else{ bHasAlpha = FALSE; } if(iBitDepth == 16){ png_set_strip_16(png_ptr); } png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER); png_read_update_info(png_ptr, info_ptr); iRowBytes = png_get_rowbytes(png_ptr, info_ptr); pbData = (LPBYTE)GlobalAlloc(GPTR, iRowBytes * iHeight); pbRowPointers = (LPBYTE)GlobalAlloc(GPTR, iHeight * sizeof(LPBYTE)); for(i = 0; i < iHeight; i++){ pbRowPointers[i] = pbData + i * iRowBytes; } png_read_image(png_ptr, pbRowPointers); png_read_end(png_ptr, NULL); //Make a texture (finally) glGenTextures(1, &uTexture); glBindTexture(GL_TEXTURE_2D, uTexture); glTexImage2D(GL_TEXTURE_2D, 0, (bHasAlpha? 4 : 3), iWidth, iHeight, 0, (bHasAlpha? GL_RGB : GL_RGBA), GL_UNSIGNED_BYTE, pbData); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); GlobalFree(pbRowPointers); GlobalFree(pbData); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(hTexture); return uTexture; }