From 5d68470c95e1857780b68a8bcb8b00755a2c2821 Mon Sep 17 00:00:00 2001 From: curt Date: Wed, 12 May 1999 04:24:55 +0000 Subject: [PATCH] Major shuffling to push basic material management out into FlightGear/Lib/ so it can be accessible from the scenery tools. Also implimented JIT texture loading to save start time and memory. --- Lib/Misc/Makefile.am | 2 + Lib/Misc/colours.h | 289 ++++++++++++++++++++++++++++++++ Lib/Misc/material.cxx | 247 +++++++++++++++++++++++++++ Lib/Misc/material.hxx | 100 +++++++++++ Lib/Misc/texload.c | 382 ++++++++++++++++++++++++++++++++++++++++++ Lib/Misc/texload.h | 32 ++++ 6 files changed, 1052 insertions(+) create mode 100644 Lib/Misc/colours.h create mode 100644 Lib/Misc/material.cxx create mode 100644 Lib/Misc/material.hxx create mode 100644 Lib/Misc/texload.c create mode 100644 Lib/Misc/texload.h diff --git a/Lib/Misc/Makefile.am b/Lib/Misc/Makefile.am index 8cab48b3..de3ff96e 100644 --- a/Lib/Misc/Makefile.am +++ b/Lib/Misc/Makefile.am @@ -5,8 +5,10 @@ noinst_LIBRARIES = libMisc.a libMisc_a_SOURCES = \ fgpath.cxx fgpath.hxx \ fgstream.cxx fgstream.hxx \ + material.cxx material.hxx \ stopwatch.hxx \ strutils.cxx strutils.hxx \ + texload.c texload.h colours.h \ zfstream.cxx zfstream.hxx INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib diff --git a/Lib/Misc/colours.h b/Lib/Misc/colours.h new file mode 100644 index 00000000..ba3b8914 --- /dev/null +++ b/Lib/Misc/colours.h @@ -0,0 +1,289 @@ +// colours.h -- This header file contains colour definitions in the +// same way as MS FS5 does +// +// Contributed by "Christian Mayer" , started April 1999. +// +// Copyright (C) 1998 Christian Mayer - Vader@t-online.de +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef COLOURS_H +#define COLOURS_H + +unsigned char msfs_colour[256][3]= +{ + { 0, 0, 0}, + { 8, 8, 8}, + { 16, 16, 16}, + { 24, 24, 24}, + { 32, 32, 32}, + { 40, 40, 40}, + { 48, 48, 48}, + { 56, 56, 56}, + { 65, 65, 65}, + { 73, 73, 73}, + { 81, 81, 81}, + { 89, 89, 89}, + { 97, 97, 97}, + {105, 105, 105}, + {113, 113, 113}, + {121, 121, 121}, + {130, 130, 130}, + {138, 138, 138}, + {146, 146, 146}, + {154, 154, 154}, + {162, 162, 162}, + {170, 170, 170}, + {178, 178, 178}, + {186, 186, 186}, + {195, 195, 195}, + {203, 203, 203}, + {211, 211, 211}, + {219, 219, 219}, + {227, 227, 227}, + {235, 235, 235}, + {247, 247, 247}, + {255, 255, 255}, + { 21, 5, 5}, + { 42, 10, 10}, + { 63, 15, 15}, + { 84, 20, 20}, + {105, 25, 25}, + {126, 30, 30}, + {147, 35, 35}, + {168, 40, 40}, + {189, 45, 45}, + {210, 50, 50}, + {231, 55, 55}, + {252, 60, 60}, + { 5, 21, 5}, + { 10, 42, 10}, + { 15, 63, 15}, + { 20, 84, 20}, + { 25, 105, 25}, + { 30, 126, 30}, + { 35, 147, 35}, + { 40, 168, 40}, + { 45, 189, 45}, + { 50, 210, 50}, + { 55, 231, 55}, + { 60, 252, 60}, + { 0, 7, 23}, + { 0, 15, 40}, + { 0, 23, 58}, + { 0, 40, 84}, + { 0, 64, 104}, + { 0, 71, 122}, + { 0, 87, 143}, + { 0, 99, 156}, + { 0, 112, 179}, + { 0, 128, 199}, + { 0, 143, 215}, + { 0, 153, 230}, + { 28, 14, 0}, + { 56, 28, 0}, + { 84, 42, 0}, + {112, 56, 0}, + {140, 70, 0}, + {168, 84, 0}, + {196, 98, 0}, + {224, 112, 0}, + {252, 126, 0}, + { 28, 28, 0}, + { 56, 56, 0}, + { 84, 84, 0}, + {112, 112, 0}, + {140, 140, 0}, + {168, 168, 0}, + {196, 196, 0}, + {224, 224, 0}, + {252, 252, 0}, + { 25, 21, 16}, + { 50, 42, 32}, + { 75, 63, 48}, + {100, 84, 64}, + {125, 105, 80}, + {150, 126, 96}, + {175, 147, 112}, + {200, 168, 128}, + {225, 189, 144}, + { 28, 11, 7}, + { 56, 22, 14}, + { 84, 33, 21}, + {112, 44, 28}, + {140, 55, 35}, + {168, 66, 42}, + {196, 77, 49}, + {224, 88, 56}, + {252, 99, 63}, + { 17, 22, 9}, + { 34, 44, 18}, + { 51, 66, 27}, + { 68, 88, 36}, + { 85, 110, 45}, + {102, 132, 54}, + {119, 154, 63}, + {136, 176, 72}, + {153, 198, 81}, + { 0, 58, 104}, + { 0, 87, 112}, + { 43, 112, 128}, + {255, 0, 0}, + { 64, 255, 64}, + { 0, 0, 192}, + { 0, 105, 105}, + {255, 128, 0}, + {255, 255, 0}, + { 81, 81, 81}, + {121, 121, 121}, + {146, 146, 146}, + {170, 170, 170}, + {195, 195, 195}, + {227, 227, 227}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + { 0, 0, 0}, + {192, 192, 255}, + {200, 200, 255}, + {208, 208, 255}, + {216, 216, 255}, + {224, 224, 255}, + {232, 232, 255}, + {240, 240, 255}, + {248, 248, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + {255, 255, 255}, + { 16, 72, 16}, + { 32, 80, 32}, + { 48, 88, 48}, + { 64, 96, 64}, + { 80, 104, 80}, + { 96, 112, 96}, + {112, 120, 112}, + {120, 124, 120}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + {128, 128, 128}, + { 33, 140, 189}, + { 57, 132, 165}, + {189, 66, 66}, + {156, 66, 66}, + {132, 74, 74}, + { 33, 82, 107}, + {214, 90, 82}, + {189, 90, 82}, + {165, 90, 82}, + {123, 57, 49}, + { 99, 57, 49}, + {107, 74, 66}, + {123, 90, 82}, + {181, 90, 66}, + { 74, 49, 41}, + {189, 115, 90}, + {140, 90, 49}, + { 33, 49, 74}, + {181, 115, 49}, + { 99, 66, 33}, + {165, 115, 66}, + { 49, 41, 33}, + {165, 140, 115}, + {189, 165, 140}, + { 57, 99, 123}, + {181, 107, 24}, + {206, 123, 33}, + {156, 99, 33}, + {148, 107, 49}, + {107, 82, 49}, + { 33, 33, 57}, + { 33, 115, 165}, + {214, 214, 33}, + {173, 173, 33}, + {198, 198, 41}, + {140, 140, 33}, + {115, 115, 33}, + {189, 189, 57}, + {156, 156, 49}, + {173, 173, 57}, + {123, 123, 49}, + {123, 123, 66}, + { 74, 74, 49}, + {123, 123, 90}, + { 41, 41, 33}, + { 90, 99, 57}, + {107, 115, 74}, + {123, 148, 82}, + {140, 173, 99}, + {132, 156, 99}, + { 49, 66, 41}, + { 99, 165, 90}, + { 74, 214, 74}, + { 57, 140, 57}, + { 74, 181, 74}, + { 90, 198, 90}, + { 57, 123, 57}, + { 49, 99, 49}, + { 90, 165, 90}, + { 82, 148, 82}, + { 74, 99, 74}, + { 57, 115, 132}, + { 33, 99, 123}, + { 74, 115, 132} +}; + + +#endif diff --git a/Lib/Misc/material.cxx b/Lib/Misc/material.cxx new file mode 100644 index 00000000..0f1a2e0a --- /dev/null +++ b/Lib/Misc/material.cxx @@ -0,0 +1,247 @@ +// material.cxx -- class to handle material properties +// +// Written by Curtis Olson, started May 1998. +// +// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef FG_MATH_EXCEPTION_CLASH +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include +#include + +#include STL_STRING + +#include +#include +#include + +#include "material.hxx" +#include "texload.h" + +FG_USING_STD(string); + + +// Constructor +FGMaterial::FGMaterial ( void ) + : loaded(false), + texture_name(""), + alpha(0) + // , list_size(0) +{ + ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0; + diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0; + specular[0] = specular[1] = specular[2] = specular[3] = 0.0; + emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0; +} + + +istream& +operator >> ( istream& in, FGMaterial& m ) +{ + string token; + + for (;;) { + in >> token; + if ( token == "texture" ) { + in >> token >> m.texture_name; + } else if ( token == "xsize" ) { + in >> token >> m.xsize; + } else if ( token == "ysize" ) { + in >> token >> m.ysize; + } else if ( token == "ambient" ) { + in >> token >> m.ambient[0] >> m.ambient[1] + >> m.ambient[2] >> m.ambient[3]; + } else if ( token == "diffuse" ) { + in >> token >> m.diffuse[0] >> m.diffuse[1] + >> m.diffuse[2] >> m.diffuse[3]; + } else if ( token == "specular" ) { + in >> token >> m.specular[0] >> m.specular[1] + >> m.specular[2] >> m.specular[3]; + } else if ( token == "emissive" ) { + in >> token >> m.emissive[0] >> m.emissive[1] + >> m.emissive[2] >> m.emissive[3]; + } else if ( token == "alpha" ) { + in >> token >> token; + if ( token == "yes" ) { + m.alpha = 1; + } else if ( token == "no" ) { + m.alpha = 0; + } else { + FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token ); + } + } else if ( token[0] == '}' ) { + break; + } + } + + return in; +} + +void +FGMaterial::load_texture( const string& root ) +{ + GLubyte *texbuf; + int width, height; + + FG_LOG( FG_TERRAIN, FG_INFO, + " Loading texture for material " << texture_name ); + + // create the texture object and bind it +#ifdef GL_VERSION_1_1 + xglGenTextures(1, &texture_id ); + xglBindTexture(GL_TEXTURE_2D, texture_id ); +#elif GL_EXT_texture_object + xglGenTexturesEXT(1, &texture_id ); + xglBindTextureEXT(GL_TEXTURE_2D, texture_id ); +#else +# error port me +#endif + + // set the texture parameters for this texture + xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ; + xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ; + xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_LINEAR ); + // xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + // GL_NEAREST_MIPMAP_NEAREST ); + xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + /* GL_LINEAR */ + /* GL_NEAREST_MIPMAP_LINEAR */ + GL_LINEAR_MIPMAP_LINEAR ) ; + + // load in the texture data + FGPath base_path( root ); + base_path.append( "Textures" ); + base_path.append( texture_name ); + + FGPath tpath = base_path; + tpath.concat( ".rgb" ); + + FGPath fg_tpath = tpath; + fg_tpath.concat( ".gz" ); + + FGPath fg_raw_tpath = base_path; + fg_raw_tpath.concat( ".raw" ); + + // create string names for msfs compatible textures + FGPath fg_r8_tpath = base_path; + fg_r8_tpath.concat( ".r8" ); + + FGPath fg_tex_tpath = base_path; + fg_tex_tpath.concat( ".txt" ); + + FGPath fg_pat_tpath = base_path; + fg_pat_tpath.concat( ".pat" ); + + FGPath fg_oav_tpath = base_path; + fg_oav_tpath.concat( ".oav" ); + + if ( alpha == 0 ) { + // load rgb texture + + // Try uncompressed + if ( (texbuf = + read_rgb_texture(tpath.c_str(), &width, &height)) != + NULL ) + ; + // Try compressed + else if ( (texbuf = + read_rgb_texture(fg_tpath.c_str(), &width, &height)) + != NULL ) + ; + // Try raw + else if ( (texbuf = + read_raw_texture(fg_raw_tpath.c_str(), &width, &height)) + != NULL ) + ; + // Try r8 + else if ( (texbuf = + read_r8_texture(fg_r8_tpath.c_str(), &width, &height)) + != NULL ) + ; + // Try tex + else if ( (texbuf = + read_r8_texture(fg_tex_tpath.c_str(), &width, &height)) + != NULL ) + ; + // Try pat + else if ( (texbuf = + read_r8_texture(fg_pat_tpath.c_str(), &width, &height)) + != NULL ) + ; + // Try oav + else if ( (texbuf = + read_r8_texture(fg_oav_tpath.c_str(), &width, &height)) + != NULL ) + ; + else + { + FG_LOG( FG_GENERAL, FG_ALERT, + "Error in loading texture " << tpath.str() ); + exit(-1); + } + + /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, texbuf); */ + + gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, + GL_RGB, GL_UNSIGNED_BYTE, texbuf ); + } else if ( alpha == 1 ) { + // load rgba (alpha) texture + + // Try uncompressed + if ( (texbuf = + read_alpha_texture(tpath.c_str(), &width, &height)) + == NULL ) + { + // Try compressed + if ((texbuf = + read_alpha_texture(fg_tpath.c_str(), &width, &height)) + == NULL ) + { + FG_LOG( FG_GENERAL, FG_ALERT, + "Error in loading texture " << tpath.str() ); + exit(-1); + } + } + + xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texbuf); + } + + loaded = true; +} + + +// Destructor +FGMaterial::~FGMaterial ( void ) { +} diff --git a/Lib/Misc/material.hxx b/Lib/Misc/material.hxx new file mode 100644 index 00000000..f973e395 --- /dev/null +++ b/Lib/Misc/material.hxx @@ -0,0 +1,100 @@ +// material.hxx -- class to handle material properties +// +// Written by Curtis Olson, started May 1998. +// +// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _MATERIAL_HXX +#define _MATERIAL_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include "Include/compiler.h" + +#include +#include + +#include STL_STRING // Standard C++ string library + +FG_USING_STD(string); + + +// MSVC++ 6.0 kuldge - Need forward declaration of friends. +class fgMATERIAL; +istream& operator >> ( istream& in, fgMATERIAL& m ); + +// Material property class +class FGMaterial { + +private: + // texture loaded + bool loaded; + + // OpenGL texture name + GLuint texture_id; + + // file name of texture + string texture_name; + + // alpha texture? + int alpha; + + // texture size + double xsize, ysize; + + // material properties + GLfloat ambient[4], diffuse[4], specular[4], emissive[4]; + GLint texture_ptr; + +public: + + // Constructor + FGMaterial ( void ); + + // Destructor + ~FGMaterial ( void ); + + void load_texture( const string& root ); + + friend istream& operator >> ( istream& in, FGMaterial& m ); + + inline bool is_loaded() const { return loaded; } + inline GLuint get_texture_id() const { return texture_id; } + inline GLfloat *get_ambient() { return ambient; } + inline GLfloat *get_diffuse() { return diffuse; } + inline GLfloat *get_specular() { return specular; } + inline GLfloat *get_emissive() { return emissive; } +}; + + +#endif // _MATERIAL_HXX + + diff --git a/Lib/Misc/texload.c b/Lib/Misc/texload.c new file mode 100644 index 00000000..69701af3 --- /dev/null +++ b/Lib/Misc/texload.c @@ -0,0 +1,382 @@ + +/* texture.c - by David Blythe, SGI */ + +/* texload is a simplistic routine for reading an SGI .rgb image file. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include +#include +#include + +#include + +#include "texload.h" +#include "colours.h" + +typedef struct _ImageRec { + unsigned short imagic; + unsigned short type; + unsigned short dim; + unsigned short xsize, ysize, zsize; + unsigned int min, max; + unsigned int wasteBytes; + char name[80]; + unsigned long colorMap; + fgFile file; + unsigned char *tmp; + unsigned long rleEnd; + unsigned int *rowStart; + int *rowSize; +} ImageRec; + +void +rgbtorgb(unsigned char *r,unsigned char *g,unsigned char *b,unsigned char *l,int n) { + while(n--) { + l[0] = r[0]; + l[1] = g[0]; + l[2] = b[0]; + l += 3; r++; g++; b++; + } +} + +static void +ConvertShort(unsigned short *array, unsigned int length) { + unsigned short b1, b2; + unsigned char *ptr; + + ptr = (unsigned char *)array; + while (length--) { + b1 = *ptr++; + b2 = *ptr++; + *array++ = (b1 << 8) | (b2); + } +} + +static void +ConvertUint(unsigned *array, unsigned int length) { + unsigned int b1, b2, b3, b4; + unsigned char *ptr; + + ptr = (unsigned char *)array; + while (length--) { + b1 = *ptr++; + b2 = *ptr++; + b3 = *ptr++; + b4 = *ptr++; + *array++ = (b1 << 24) | (b2 << 16) | (b3 << 8) | (b4); + } +} + +static ImageRec *ImageOpen(const char *fileName) +{ + union { + int testWord; + char testByte[4]; + } endianTest; + + ImageRec *image; + int swapFlag; + int x; + + endianTest.testWord = 1; + if (endianTest.testByte[0] == 1) { + swapFlag = 1; + } else { + swapFlag = 0; + } + + image = (ImageRec *)malloc(sizeof(ImageRec)); + if (image == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + if ((image->file = fgopen(fileName, "rb")) == NULL) { + return NULL; + } + + // fread(image, 1, 12, image->file); + fgread(image->file, image, 12); + + if (swapFlag) { + ConvertShort(&image->imagic, 6); + } + + image->tmp = (unsigned char *)malloc(image->xsize*256); + if (image->tmp == NULL) { + fprintf(stderr, "\nOut of memory!\n"); + exit(1); + } + + if ((image->type & 0xFF00) == 0x0100) { + x = image->ysize * image->zsize * (int) sizeof(unsigned); + image->rowStart = (unsigned *)malloc(x); + image->rowSize = (int *)malloc(x); + if (image->rowStart == NULL || image->rowSize == NULL) { + fprintf(stderr, "\nOut of memory!\n"); + exit(1); + } + image->rleEnd = 512 + (2 * x); + fgseek(image->file, 512, SEEK_SET); + // fread(image->rowStart, 1, x, image->file); + fgread(image->file, image->rowStart, x); + // fread(image->rowSize, 1, x, image->file); + fgread(image->file, image->rowSize, x); + if (swapFlag) { + ConvertUint(image->rowStart, x/(int) sizeof(unsigned)); + ConvertUint((unsigned *)image->rowSize, x/(int) sizeof(int)); + } + } + return image; +} + +static void +ImageClose(ImageRec *image) { + fgclose(image->file); + free(image->tmp); + free(image); +} + +static void +ImageGetRow(ImageRec *image, unsigned char *buf, int y, int z) { + unsigned char *iPtr, *oPtr, pixel; + int count; + + if ((image->type & 0xFF00) == 0x0100) { + fgseek(image->file, (long) image->rowStart[y+z*image->ysize], SEEK_SET); + // fread(image->tmp, 1, (unsigned int)image->rowSize[y+z*image->ysize], + // image->file); + fgread(image->file, image->tmp, + (unsigned int)image->rowSize[y+z*image->ysize]); + + iPtr = image->tmp; + oPtr = buf; + for (;;) { + pixel = *iPtr++; + count = (int)(pixel & 0x7F); + if (!count) { + return; + } + if (pixel & 0x80) { + while (count--) { + *oPtr++ = *iPtr++; + } + } else { + pixel = *iPtr++; + while (count--) { + *oPtr++ = pixel; + } + } + } + } else { + fgseek(image->file, 512+(y*image->xsize)+(z*image->xsize*image->ysize), + SEEK_SET); + // fread(buf, 1, image->xsize, image->file); + fgread(image->file, buf, image->xsize); + } +} + +GLubyte * +read_alpha_texture(const char *name, int *width, int *height) +{ + unsigned char *base, *lptr; + ImageRec *image; + int y; + + image = ImageOpen(name); + if(!image) { + return NULL; + } + + (*width)=image->xsize; + (*height)=image->ysize; + + printf("image->zsize = %d\n", image->zsize); + + if (image->zsize != 1) { + ImageClose(image); + return NULL; + } + + base = (unsigned char *)malloc(image->xsize*image->ysize*sizeof(unsigned char)); + lptr = base; + for(y=0; yysize; y++) { + ImageGetRow(image,lptr,y,0); + lptr += image->xsize; + } + ImageClose(image); + + return (unsigned char *) base; +} + +GLubyte * +read_rgb_texture(const char *name, int *width, int *height) +{ + unsigned char *base, *ptr; + unsigned char *rbuf, *gbuf, *bbuf, *abuf; + ImageRec *image; + int y; + + image = ImageOpen(name); + + if(!image) + return NULL; + (*width)=image->xsize; + (*height)=image->ysize; + if (image->zsize != 3 && image->zsize != 4) { + ImageClose(image); + return NULL; + } + + base = (unsigned char*)malloc(image->xsize*image->ysize*sizeof(unsigned int)*3); + rbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + gbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + bbuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + abuf = (unsigned char *)malloc(image->xsize*sizeof(unsigned char)); + if(!base || !rbuf || !gbuf || !bbuf || !abuf) { + if (base) free(base); + if (rbuf) free(rbuf); + if (gbuf) free(gbuf); + if (bbuf) free(bbuf); + if (abuf) free(abuf); + return NULL; + } + ptr = base; + for(y=0; yysize; y++) { + if(image->zsize == 4) { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,gbuf,y,1); + ImageGetRow(image,bbuf,y,2); + ImageGetRow(image,abuf,y,3); /* Discard. */ + rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); + ptr += (image->xsize * 3); + } else { + ImageGetRow(image,rbuf,y,0); + ImageGetRow(image,gbuf,y,1); + ImageGetRow(image,bbuf,y,2); + rgbtorgb(rbuf,gbuf,bbuf,ptr,image->xsize); + ptr += (image->xsize * 3); + } + } + ImageClose(image); + free(rbuf); + free(gbuf); + free(bbuf); + free(abuf); + + return (GLubyte *) base; +} + + +static ImageRec *RawImageOpen(const char *fileName) +{ + union { + int testWord; + char testByte[4]; + } endianTest; + + ImageRec *image; + int swapFlag; + + endianTest.testWord = 1; + if (endianTest.testByte[0] == 1) { + swapFlag = 1; + } else { + swapFlag = 0; + } + + image = (ImageRec *)malloc(sizeof(ImageRec)); + if (image == NULL) { + fprintf(stderr, "Out of memory!\n"); + exit(1); + } + if ((image->file = fgopen(fileName, "rb")) == NULL) { + return NULL; + } + + fgread(image->file, image, 12); + + if (swapFlag) { + ConvertShort(&image->imagic, 6); + } + + + image->tmp = (unsigned char *)malloc(1); //just allocate a pseudo value as I'm too lazy to change ImageClose()... + if (image->tmp == NULL) { + fprintf(stderr, "\nOut of memory!\n"); + exit(1); + } + + return image; +} + + +GLubyte * +read_raw_texture(const char *name, int *width, int *height) +{ + unsigned char *base, *ptr; + ImageRec *image; + int y; + + image = RawImageOpen(name); + + if(!image) + return NULL; + (*width)=256; + (*height)=256; + + base = (unsigned char*)malloc(256*256*sizeof(unsigned char)*3); + if(!base) { + if (base) free(base); + return NULL; + } + ptr = base; + for(y=0; y<256; y++) { + fgread(image->file, ptr, 256*3); + ptr+=256*3; + } + ImageClose(image); + + return (GLubyte *) base; +} + + +GLubyte * +read_r8_texture(const char *name, int *width, int *height) +{ + unsigned char *base, *ptr; + ImageRec *image; + int xy; + unsigned char c[1]; + + image = RawImageOpen(name); //it wouldn't make sense to write a new function... + + if(!image) + return NULL; + (*width)=256; + (*height)=256; + + base = (unsigned char*)malloc(256*256*sizeof(unsigned char)*3); + if(!base) { + if (base) free(base); + return NULL; + } + ptr = base; + for(xy=0; xy<(256*256); xy++) { + fgread(image->file,c,1); + ptr[0]=msfs_colour[c[0]][0]; //look in the table for the right colours + ptr[1]=msfs_colour[c[0]][1]; + ptr[2]=msfs_colour[c[0]][2]; + + ptr+=3; + } + ImageClose(image); + + return (GLubyte *) base; +} diff --git a/Lib/Misc/texload.h b/Lib/Misc/texload.h new file mode 100644 index 00000000..29df85cf --- /dev/null +++ b/Lib/Misc/texload.h @@ -0,0 +1,32 @@ + +/* Copyright (c) Mark J. Kilgard, 1997. */ + +/* This program is freely distributable without licensing fees + and is provided without guarantee or warrantee expressed or + implied. This program is -not- in the public domain. */ + + +#ifndef _TEXLOAD_H +#define _TEXLOAD_H + + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + + +extern GLubyte *read_alpha_texture(const char *name, int *width, int *height); +extern GLubyte *read_rgb_texture(const char *name, int *width, int *height); +extern GLubyte *read_raw_texture(const char *name, int *width, int *height); +extern GLubyte *read_r8_texture(const char *name, int *width, int *height); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _TEXLOAD_H */ -- 2.39.5