arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

simTexture.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------
00002 //
00003 //   Joe Kniss
00004 //     3-20-03
00005 //                   ________    ____   ___ 
00006 //                  |        \  /    | /  /
00007 //                  +---+     \/     |/  /
00008 //                  +--+|  |\    /|     < 
00009 //                  |  ||  | \  / |  |\  \ 
00010 //                  |      |  \/  |  | \  \ 
00011 //                   \_____|      |__|  \__\
00012 //                       Copyright  2003 
00013 //                      Joe Michael Kniss
00014 //                   <<< jmk@cs.utah.edu >>>
00015 //               "All Your Base are Belong to Us"
00016 //-------------------------------------------------------------------------
00017 
00018 /// simTexture.cpp
00019 
00020 /// Simian Texture utilities.
00021 
00022 #include <GL/glew.h>
00023 #include "simTexture.h"
00024 #include <nrro/nrro.h>
00025 #include <GL/glUtil.h>
00026 #include <iostream>
00027 
00028 using namespace glift;
00029 using namespace gutz;
00030 using namespace std;
00031 
00032 enum SIM_TEX_FORMATS{
00033    SIMTL_HILO,
00034    SIMTL_NV3_FLOAT,
00035    SIMTL_NV3_HFLOAT,
00036    SIMTL_ATI97_16,
00037    SIMTL_ATI97_HFLOAT,
00038    SIMTL_ATI97_FLOAT,
00039    SIMTL_8BIT
00040 };
00041 
00042 inline void derr(char *when, char *where = 0)
00043 {
00044 #if _DEBUG
00045    cerr << "simTexture::" << when;
00046    if(where)
00047       cerr << " - " << where;
00048    cerr << endl;
00049 #endif
00050 }
00051 
00052 ///////////////////////////////////////////////////////////////////////////
00053 // Load a single nrrd texture
00054 ///////////////////////////////////////////////////////////////////////////
00055 glift::SingleTex *loadNrrdTexture(char *nrrdTexName, int texType)
00056 {
00057    derr("loading nrrd from file name", nrrdTexName);
00058 
00059    NrroSP n(new Nrro(nrrdTexName));
00060 
00061    if(n.isNull())
00062    {
00063       derr("falied to load nrrd texture");
00064       return 0;
00065    }
00066 
00067    if(n->dim() != 4)
00068    {
00069       if(n->forceMultiChannel())
00070       {
00071          derr("incorrect texture dimensions");
00072       }
00073    }
00074 
00075    return loadNrroTexture(n,texType);
00076 
00077    return 0;
00078 }
00079 
00080 ///////////////////////////////////////////////////////////////////////////
00081 // Load a single Nrro texture
00082 ///////////////////////////////////////////////////////////////////////////
00083 glift::SingleTexSP loadNrroTexture(const NrroSP n, int texType)
00084 {
00085    int ntype = n->getType();
00086 
00087    if(ntype == Nrro::CHAR || ntype == Nrro::UCHAR)
00088    {
00089       derr("Loading char Nrro texture");
00090       SingleTexSP ret = 
00091          loadTexture3D((char*) n->getData(), 
00092          n->dim(1), n->dim(2), n->dim(3), n->dim(0),
00093          getSimtType(n,texType));
00094       if(!ret)
00095          derr("loadNrroTexture failed");
00096 
00097       return ret;
00098    }
00099    return SingleTexSP();
00100 }
00101 
00102 ///////////////////////////////////////////////////////////////////////////
00103 // find the type that best fits a Nrro
00104 ///////////////////////////////////////////////////////////////////////////
00105 int getSimtType(const NrroSP n, int texType)
00106 {
00107    int ntype = n->getType();
00108 
00109    if(ntype == nrrdTypeUChar || ntype == nrrdTypeChar)
00110    {
00111       derr(" nrrd texture = uchar ");
00112       return SIMT_8BIT;
00113    }
00114 
00115    return SIMT_UNKNOWN;
00116 }
00117 
00118 
00119 ///////////////////////////////////////////////////////////////////////////
00120 /// Load Texture, explicit, standard texture object state:
00121 ///     Linear, clamp to boarder (if applicable) or clamp
00122 ///    BEST FITS:
00123 /// \code
00124 ///   Comps               Type General           Type nv123x      Type ATI 9700+
00125 ///     1                   Lumanance               HILO16           Fixed16 Lum
00126 ///     2                   Lumanance Alpha         HILO16           Fixed16 Lum Alpha
00127 ///     3                   RGB8                    RGB8             RGB16  (FIXED)
00128 ///     4                   RGBA8                   RGBA8            RGBA16 (FIXED)
00129 /// \endcode
00130 ///////////////////////////////////////////////////////////////////////////
00131 
00132 ///////////////////////////////////////////////////////////////////////////
00133 /// 3D texture, float data
00134 ///////////////////////////////////////////////////////////////////////////
00135 glift::SingleTexSP loadTexture3D(float *data, int sx, int sy, int sz, int comp, int texType)
00136 {       
00137    //////////////////////////////
00138    /// create the tex data object
00139 
00140    GLenum inFmt = getInternalFormat(comp,texType);
00141    GLenum exFmt = getExternalFormat(comp,inFmt);
00142 
00143    TexData *tdata = new TexData(GL_TEXTURE_3D,                    //texture type 
00144       vec3i(0,0,0),                     //origin
00145       vec3i(sx, sy, sz),                //size
00146       0,                                //border
00147       inFmt,                            //internal format
00148       exFmt,                            //external format
00149       GL_FLOAT,                         //type
00150       data);                            //data pointer
00151 
00152    //////////////////////////////
00153    /// create texture object
00154    if(tdata)
00155    {
00156       MultiTexOState tstate;
00157       tstate << TS_S_CLAMP_TO_EDGE << TS_T_CLAMP_TO_EDGE << TS_LINEAR; //<< new MipMapTex(GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR, true);
00158 
00159       SingleTex* tout = new Tex3D(tstate, tdata);
00160 
00161       glErr(cerr,"SimTexture", "loadTexture3D - float");
00162 
00163       return SingleTexSP(tout);
00164    }
00165    else
00166    {
00167       cerr << " Simian Texture Utillities :: Error, failed to create 3D texture " << endl;
00168       return SingleTexSP();
00169    }
00170 
00171 
00172    return SingleTexSP(); ///< should be unreachable
00173 }
00174 
00175 ///////////////////////////////////////////////////////////////////////////
00176 // 3D texture, char data
00177 ///////////////////////////////////////////////////////////////////////////
00178 glift::SingleTexSP loadTexture3D(char  *data, int sx, int sy, int sz, int comp, int texType)
00179 {
00180    derr("Loading 3D byte texture");
00181    //////////////////////////////
00182    /// create the tex data object
00183 
00184    GLenum inFmt = getInternalFormat(comp,texType);
00185    GLenum exFmt = getExternalFormat(comp,inFmt);
00186 
00187    TexData *tdata = new TexData(GL_TEXTURE_3D,                    //texture type 
00188       vec3i(0,0,0),                     //origin
00189       vec3i(sx, sy, sz),                //size
00190       0,                                //border
00191       inFmt,                            //internal format
00192       exFmt,                            //external format
00193       GL_UNSIGNED_BYTE,                 //type
00194       data);                            //data pointer
00195 
00196    //////////////////////////////
00197    /// create texture object
00198    if(tdata)
00199    {
00200       MultiTexOState tstate;
00201       tstate << TS_S_CLAMP_TO_EDGE << TS_T_CLAMP_TO_EDGE << TS_LINEAR; //<< new MipMapTex(GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR, true);
00202 
00203       SingleTex* tout = new Tex3D(tstate, tdata);
00204 
00205       derr("Texture created");
00206 
00207       glErr(cerr,"SimTexture", "loadTexture3D - char");
00208 
00209       return SingleTexSP(tout);
00210    }
00211    else
00212    {
00213       cerr << " Simian Texture Utillities :: Error, failed to create 3D texture " << endl;
00214       return SingleTexSP();
00215    }
00216 
00217 
00218    return SingleTexSP(); ///< should be unreachable
00219 }
00220 
00221 
00222 ///////////////////////////////////////////////////////////////////////////
00223 // 1D
00224 ///////////////////////////////////////////////////////////////////////////
00225 
00226 glift::SingleTex *loadTexture1D(float *data, int sx, int comp, int texType)
00227 {
00228    //////////////////////////////
00229    /// create the tex data object
00230 
00231    GLenum inFmt = getInternalFormat(comp,texType);
00232    GLenum exFmt = getExternalFormat(comp,inFmt);
00233 
00234    TexData *tdata = new TexData(GL_TEXTURE_1D,                    //texture type 
00235       vec3i(0,0,0),                     //origin
00236       vec3i(sx, 0, 0),                  //size
00237       0,                                //border
00238       inFmt,                            //internal format
00239       exFmt,                            //external format
00240       GL_FLOAT,                         //type
00241       data);                            //data pointer
00242 
00243    //////////////////////////////
00244    /// create texture object
00245    if(tdata)
00246    {
00247       MultiTexOState tstate;
00248       tstate << TS_S_CLAMP_TO_EDGE << TS_T_CLAMP_TO_EDGE << TS_LINEAR; //<< new MipMapTex(GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR, true);
00249 
00250       SingleTex* tout = new Tex1D(tstate, tdata);
00251 
00252       glErr(cerr,"SimTexture", "loadTexture1D - float");
00253 
00254       return tout;
00255    }
00256    else
00257    {
00258       cerr << " Simian Texture Utillities :: Error, failed to create 1D texture " << endl;
00259       return 0;
00260    }
00261 
00262 
00263    return 0; ///< should be unreachable
00264 }
00265 
00266 ///////////////////////////////////////////////////////////////////////////
00267 // 2D texture, float data
00268 ///////////////////////////////////////////////////////////////////////////
00269 glift::SingleTex *loadTexture2D(float *data, int sx, int sy, int comp, int texType)
00270 {
00271    //////////////////////////////
00272    /// create the tex data object
00273 
00274    GLenum inFmt = getInternalFormat(comp,texType);
00275    GLenum exFmt = getExternalFormat(comp,inFmt);
00276 
00277    TexData *tdata = new TexData(GL_TEXTURE_2D,                    //texture type 
00278       vec3i(0,0,0),                     //origin
00279       vec3i(sx, sy, 0),                 //size
00280       0,                                //border
00281       inFmt,                            //internal format
00282       exFmt,                            //external format
00283       GL_FLOAT,                         //type
00284       data);                            //data pointer
00285 
00286    //////////////////////////////
00287    /// create texture object
00288    if(tdata)
00289    {
00290       MultiTexOState tstate;
00291       tstate << TS_S_CLAMP_TO_EDGE << TS_T_CLAMP_TO_EDGE << TS_LINEAR; //<< new MipMapTex(GL_NEAREST_MIPMAP_LINEAR, GL_LINEAR, true);
00292 
00293       SingleTex* tout = new Tex2D(tstate, tdata);
00294 
00295       glErr(cerr,"SimTexture", "loadTexture2D - float");
00296 
00297       return tout;
00298    }
00299    else
00300    {
00301       cerr << " Simian Texture Utillities :: Error, failed to create 2D texture " << endl;
00302       return 0;
00303    }
00304 
00305 
00306    return 0; ///< should be unreachable
00307 }
00308 
00309 
00310 
00311 ///////////////////////////////////////////////////////////////////////////
00312 // find the best fit texture type, returns the higest precision (interpolating) type 
00313 //  for the current platform
00314 ///////////////////////////////////////////////////////////////////////////
00315 GLenum getInternalFormat(int nComps, int simtType)
00316 {
00317    /// try to identify the platform type
00318    /// this is a fucking hack, fix it, there must be a better way
00319 
00320    ///////////////////////////////////////////////////////
00321    /// NVIDIA
00322    if(glew.NV_texture_shader3 && (nComps <= 2) && (simtType == SIMT_BEST || simtType == SIMT_16FIXED))
00323    {
00324       derr("HILO16");
00325       return GL_HILO16_NV;
00326    }
00327    if(glew.NV_float_buffer && simtType == SIMT_16FLOAT)
00328    {
00329       derr("NV-16 float texture");
00330       if(nComps == 1)
00331          return GL_FLOAT_R16_NV;
00332       if(nComps == 2)
00333          return GL_FLOAT_RG16_NV;
00334       if(nComps == 3)
00335          return GL_FLOAT_RGB16_NV;
00336       if(nComps == 4)
00337          return GL_FLOAT_RGBA16_NV;             
00338    }
00339    if(glew.NV_float_buffer && simtType == SIMT_32FLOAT)
00340    {
00341       derr("NV-16 fixed texture");
00342       if(nComps == 1)
00343          return GL_FLOAT_R32_NV;
00344       if(nComps == 2)
00345          return GL_FLOAT_RG32_NV;
00346       if(nComps == 3)
00347          return GL_FLOAT_RGB32_NV;
00348       if(nComps == 4)
00349          return GL_FLOAT_RGBA32_NV;             
00350    }
00351 
00352    ///////////////////////////////////////////////////////
00353    /// ATI
00354    if(glew.ATI_texture_float && (simtType == SIMT_BEST || simtType == SIMT_16FIXED))
00355    {
00356       derr("ATI-16 Fixed texture");
00357       if(nComps == 1)
00358          return GL_LUMINANCE16;
00359       if(nComps == 2)
00360          return GL_LUMINANCE16_ALPHA16;
00361       if(nComps == 3)
00362          return GL_RGB16;
00363       if(nComps == 4)
00364          return GL_RGBA16;
00365    }
00366    if(glew.ATI_texture_float && simtType == SIMT_16FLOAT)
00367    {
00368       derr("ATI-16 float texture");
00369       if(nComps == 1)
00370          return GL_LUMINANCE_FLOAT16_ATI;
00371       if(nComps == 2)
00372          return GL_LUMINANCE_ALPHA_FLOAT16_ATI;
00373       if(nComps == 3)
00374          return GL_RGB_FLOAT16_ATI;
00375       if(nComps == 4)
00376          return GL_RGBA_FLOAT16_ATI;            
00377    }
00378 
00379    if(glew.ATI_texture_float && simtType == SIMT_32FLOAT)
00380    {
00381       derr("ATI-32 float texture");
00382       if(nComps == 1)
00383          return GL_LUMINANCE_FLOAT32_ATI;
00384       if(nComps == 2)
00385          return GL_LUMINANCE_ALPHA_FLOAT32_ATI;
00386       if(nComps == 3)
00387          return GL_RGB_FLOAT32_ATI;
00388       if(nComps == 4)
00389          return GL_RGBA_FLOAT32_ATI;            
00390    }
00391 
00392    ///////////////////////////////////////////////////////
00393    /// Default types
00394    if(nComps == 1)
00395    {
00396       derr("LUM8");
00397       return GL_LUMINANCE8;
00398    }
00399    if(nComps == 2)
00400    {
00401       derr("LUM8ALPH8");
00402       return GL_LUMINANCE8_ALPHA8;
00403    }
00404    if(nComps == 3)
00405    {
00406       derr("RGB8");
00407       return GL_RGB8;
00408    }
00409    if(nComps == 4)
00410    {
00411       derr("RGBA8");
00412       return GL_RGBA8;
00413    }
00414 
00415    derr("ERROR - internal texture type not found");
00416 
00417 
00418    return GL_RGBA8; ///< unreachable
00419 
00420 }
00421 
00422 ///////////////////////////////////////////////////////////////////////////
00423 // Get the gl texture format for the reqested number of components
00424 GLenum getExternalFormat(int nComps, GLenum inFormat)
00425 {
00426    if(inFormat)
00427    {
00428       if(inFormat == GL_HILO16_NV)
00429       {
00430          if(nComps != 2)
00431          {
00432             derr("invalid # of components for HILO", "getExternalFormat()");
00433          }
00434          derr("HILO");
00435          return GL_HILO_NV;
00436       }
00437    }
00438 
00439    if(nComps == 1)
00440    {
00441       derr("LUM");
00442       return GL_LUMINANCE;
00443    }
00444    if(nComps == 2)
00445    {
00446       derr("LUMALPH");
00447       return GL_LUMINANCE_ALPHA;
00448    }
00449    if(nComps == 3)
00450    {
00451       derr("RGB");
00452       return GL_RGB;
00453    }
00454    if(nComps == 4)
00455    {
00456       derr("RGBA");
00457       return GL_RGBA;
00458    }
00459 
00460    derr("ERROR - internal texture type not found");
00461 
00462    return GL_RGBA; ///< unreachable
00463 }
00464 

Send questions, comments, and bug reports to:
jmk