| PNG Support | |
| Ingredients | |
| To start with you need to get hold of the following files. You can get them from The GnuWin32 project at SourceForge | |
libpng.dll png.h pngconf.h libpng.lib zlib.h zconf.h zlib.dll | |
|
You can put the .h files in your project space, or in your compiler's include directory Put the .lib files in your project space, or in your compiler's lib directory Put the .dll files in your system directory, or in the quake2 directory. I noticed that when I downloaded the binaries for zlib, that zlib.dll was called zlib-1.dll. Just rename it. | |
| Code changes | |
| In g_image.c make the following changes: | |
| Near the top add in | |
#include <png.h> | |
| Now add the following functions, it makes sense to add them between LoadPCX and LoadTGA | |
/*
=========================================================
PNG LOADING
=========================================================
*/
typedef struct {
BYTE *Buffer;
int Pos;
} TPngFileBuffer;
void __cdecl PngReadFunc(png_struct *Png, png_bytep buf, png_size_t size)
{
TPngFileBuffer *PngFileBuffer=(TPngFileBuffer*)png_get_io_ptr(Png);
memcpy(buf,PngFileBuffer->Buffer+PngFileBuffer->Pos,size);
PngFileBuffer->Pos+=size;
}
void LoadPNG (char *name, byte **pic, int *width, int *height)
{
int i, rowptr;
png_structp png_ptr;
png_infop info_ptr;
png_infop end_info;
unsigned char **row_pointers;
TPngFileBuffer PngFileBuffer = {NULL,0};
*pic = NULL;
ri.FS_LoadFile (name, &PngFileBuffer.Buffer);
if (!PngFileBuffer.Buffer)
return;
if ((png_check_sig(PngFileBuffer.Buffer, 8)) == 0) {
ri.FS_FreeFile (PngFileBuffer.Buffer);
Com_Printf (PRINT_ALL, "Not a PNG file: %s\n", name);
return;
}
PngFileBuffer.Pos=0;
png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr) {
ri.FS_FreeFile (PngFileBuffer.Buffer);
Com_Printf (PRINT_ALL, "Bad PNG file: %s\n", name);
return;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
ri.FS_FreeFile (PngFileBuffer.Buffer);
Com_Printf (PRINT_ALL, "Bad PNG file: %s\n", name);
return;
}
end_info = png_create_info_struct(png_ptr);
if (!end_info) {
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
ri.FS_FreeFile (PngFileBuffer.Buffer);
Com_Printf (PRINT_ALL, "Bad PNG file: %s\n", name);
return;
}
png_set_read_fn (png_ptr,(png_voidp)&PngFileBuffer,(png_rw_ptr)PngReadFunc);
png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
row_pointers = png_get_rows(png_ptr, info_ptr);
rowptr = 0;
*pic = malloc (info_ptr->width * info_ptr->height * sizeof(int));
if (info_ptr->channels == 4) {
for (i = 0; i < info_ptr->height; i++) {
memcpy (*pic + rowptr, row_pointers[i], info_ptr->rowbytes);
rowptr += info_ptr->rowbytes;
}
} else {
int j, x;
memset (*pic, 255, info_ptr->width * info_ptr->height * sizeof(int));
x = 0;
for (i = 0; i < info_ptr->height; i++) {
for (j = 0; j < info_ptr->rowbytes; j+=info_ptr->channels) {
memcpy (*pic + x, row_pointers[i] + j, info_ptr->channels);
x+= sizeof(int);
}
rowptr += info_ptr->rowbytes;
}
}
*width = info_ptr->width;
*height = info_ptr->height;
png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
ri.FS_FreeFile (PngFileBuffer.Buffer);
}
| |
| In GL_FindImage change this: | |
//
// load the pic from disk
//
pic = NULL;
palette = NULL;
if (!strcmp(name+len-4, ".pcx"))
{
LoadPCX (name, &pic, &palette, &width, &height);
if (!pic)
return NULL; // ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name);
image = GL_LoadPic (name, pic, width, height, type, 8);
}
else if (!strcmp(name+len-4, ".wal"))
{
image = GL_LoadWal (name);
}
else if (!strcmp(name+len-4, ".tga"))
{
LoadTGA (name, &pic, &width, &height);
if (!pic)
return NULL; // ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name);
image = GL_LoadPic (name, pic, width, height, type, 32);
}
else
return NULL; // ri.Sys_Error (ERR_DROP, "GL_FindImage: bad extension on: %s", name);
| |
| to this: | |
//
// load the pic from disk
//
pic = NULL;
palette = NULL;
if (!strcmp(name+len-4, ".pcx"))
{
LoadPCX (name, &pic, &palette, &width, &height);
if (!pic)
return NULL; // ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name);
image = GL_LoadPic (name, pic, width, height, type, 8);
}
else if (!strcmp(name+len-4, ".wal"))
{
image = GL_LoadWal (name);
}
else if (!strcmp(name+len-4, ".png"))
{
LoadPNG (name, &pic, &width, &height);
if (!pic)
return NULL; // ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name);
image = GL_LoadPic (name, pic, width, height, type, 32);
}
else if (!strcmp(name+len-4, ".tga"))
{
LoadTGA (name, &pic, &width, &height);
if (!pic)
return NULL; // ri.Sys_Error (ERR_DROP, "GL_FindImage: can't load %s", name);
image = GL_LoadPic (name, pic, width, height, type, 32);
}
else
return NULL; // ri.Sys_Error (ERR_DROP, "GL_FindImage: bad extension on: %s", name);
| |
| In Mod_LoadTexInfo in the file gl_model.c change this: | |
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<8 ; j++)
out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
out->flags = LittleLong (in->flags);
next = LittleLong (in->nexttexinfo);
if (next > 0)
out->next = loadmodel->texinfo + next;
else
out->next = NULL;
Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);
out->image = GL_FindImage (name, it_wall);
if (!out->image)
{
ri.Con_Printf (PRINT_ALL, "Couldn't load %s\n", name);
out->image = r_notexture;
}
}
| |
| to this: | |
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<8 ; j++)
out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
out->flags = LittleLong (in->flags);
next = LittleLong (in->nexttexinfo);
if (next > 0)
out->next = loadmodel->texinfo + next;
else
out->next = NULL;
Com_sprintf (name, sizeof(name), "textures/%s.png", in->texture);
out->image = GL_FindImage (name, it_wall);
Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);
out->image = GL_FindImage (name, it_wall);
if (!out->image)
{
ri.Con_Printf (PRINT_ALL, "Couldn't load %s\n", name);
out->image = r_notexture;
}
}
}
| |
| Compiling | |
|
You'll need to tell your compiler to include libpng.lib when it links your ref_gl. Then compile, and away you go. With this code, you should now be able to load .png files as textures for maps, and models. If you want to add .png files for the hud and console, then you should follow this tutorial and where it says .tga put .png instead. |