00001 ////////////////////////////////////////////////////////////////////// 00002 // 8/11/02 Aaron Lefohn Scientific Computing and Imaging Institute 00003 // School of Computing University of Utah 00004 // 00005 // This library is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // This library is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with this library; if not, write to the Free Software 00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00018 00019 #ifndef GL_UTIL_GLIFT_H_ 00020 #define GL_UTIL_GLIFT_H_ 00021 00022 #include "gliftNrrd.h" 00023 #include <GL/glew.h> 00024 #include <GL/glUtil.h> 00025 #include <sstream> 00026 #include <mathGutz.h> 00027 #include <arrayGutz.h> 00028 #include "../texture/singleTex.h" 00029 00030 namespace glift { 00031 00032 #define NUM_TEX_UNIT_NAMES 32 00033 extern const GLenum g_texUnitName[NUM_TEX_UNIT_NAMES]; 00034 00035 ///////////////////////////////////////////////////////////////////////// 00036 /// 00037 /// Smattering of OpenGL utility routines 00038 /// - IMPORTANT: All Glift apps MUST call 'gliftInit()' to function properly 00039 /// 00040 /////////////////////////////////////////////////////////////////////// 00041 00042 /// Draw a 2D tile of pixels from 'data' into 'tex' 00043 /// - 'dataOrig' and 'dimen' denote the data tile 00044 /// - 'texOrig' and 'dimen' denote where in the texture the data is written 00045 /// - Number of color channels is determined by 'data.dim(2)' 00046 /// - Data is sent to texture via render-to-texture or by glCopySubTexImage2D(...). 00047 void drawSubPixels( const gutz::vec2i& dataOrig, const gutz::vec2i& texOrig, const gutz::vec2i& dimen, 00048 const gutz::arrayw3ub& data, SingleTex* tex, GLenum drawBuffer = GL_FRONT_LEFT ); 00049 00050 /// Draw pixels in 'data' into the texture, 'tex'. 00051 /// Dimensions of pixel rectangle are 'data.dim(0)' x 'data.dim(1)' 00052 void drawPixels( const gutz::arrayw3ub& data, SingleTex* tex, GLenum drawBuffer = GL_FRONT_LEFT ); 00053 00054 /// - Draw pixels in 'data' into the texture, 'tex' 00055 /// - Dimensions of pixel rectangle are 'data.dim(1)' x 'data.dim(0)' 00056 /// - Number of color channels is determined by 'data.dim(2)' 00057 /// - Draws to the currenly set surface UNLESS 'tex->pbuff()' is a SubPBuff. 00058 /// If that is the case, the surface defined in the SubPBuff is used instead 00059 /// 00060 /// WARNINGS: 00061 /// 1) Assumes an orthographic projection is already set up in the pbuffer context 00062 /// 2) Leaves pbuffer context enabled after drawing 00063 void drawPixels( const gutz::arrayw3f& data, SingleTex* tex ); 00064 00065 /// Draw a quad to the screen that is of size 'tex->dimen()' 00066 /// Will draw 'tex->pbuff()' if 'drawToPbuff' is true 00067 /// Assumes that render mode is in appropriate state ( glOrtho2D(...)? ) 00068 void drawSingleTexQuad( SingleTex* tex, bool drawToPbuff=false ); 00069 void drawSingleTexQuad( SingleTex* tex, const gutz::vec2i& dimen, bool drawToPbuff=false ); 00070 00071 /// Draw a quad of 'color' to lowerLeft=origin, upperRight=origin + dimen to 00072 /// 'tex' or current context (if pbuff==NULL) 00073 void drawColoredTile( const gutz::vec2i& origin, const gutz::vec2i& dimen, 00074 const gutz::vec2i& fullQuadDim, const gutz::vec3f& color, 00075 SingleTex* tex ); 00076 00077 /// Get header info from PNM 00078 //int readDimenPNM( char* fileName, gutz::vec2i& dimen ); 00079 00080 /// Get header info from 'fileName's header 00081 /// - 'fileName' can be a PGM, PPM, or any Nrrd-compatible file 00082 /// - 'dimen' will hold the size of each dimension of the dataset 00083 /// - 'dimen.size()' is the dimensionality of the dataset 00084 /// - Note 1: Ordering of the dimensions is Glift-like. 00085 /// - i.e. slowest index first, fastest index last (opposite of Nrrd convention) 00086 /// - Example: y, x, color 00087 /// - Note 2: Scalar data is a dimension of size 1 (counter to Nrrd convention!) 00088 /// - Note 3: 'isPNM' is true if file is PGM or PPM 00089 int readDimenNrrd( const char* fileName, gutz::arrayo1i& dimen, bool& isPNM ); 00090 00091 /// Read the PNM file, 'inFileName', sets 'width' and 'height' based on input file, 00092 /// and returns image in 'rgbaImage' 00093 /// - If file is PGM, all 'channels' have the replicated, scalar value 00094 /// - If file is PPM, up to 'channels' are output. 00095 /// - If format is RGBA and file is PPM, alpha channel is set to 255 00096 /// - If 'makeScalar' is true, PPMs are averaged down to scalar value (replicated as necessary) 00097 /// If false, RGB data is retained and alpha channel is padded with 255 if necessary 00098 /// - 'dimen' returns the size of each dimension: x,y,channels 00099 /// - Returns nrrd error code (0 is alles klar) 00100 int loadPNM( GLenum channels, bool makeScalar, const char* inFileName, 00101 gutz::arrayo3ub& data ); 00102 00103 /// Read the Nrrd file, 'inFileName'. 00104 /// - WARNING: 'inFileName' MUST be a scalar volume or this fcn will return an error 00105 /// and 'dimen' and 'data' will be unaltered. Must also be uchar data. 00106 /// - 'channels' is GL_RED, GL_RGB, GL_RGBA, etc and sets how many times the scalar 00107 /// voxel value is copied. 00108 /// - 'dimen' contains the size of each dimension of the volume. 00109 /// - 'data' contains the scalar volume data. Accessors are: z, y, x, channel 00110 int loadNrrd3D( GLenum channels, const char* inFileName, gutz::arrayo4ub& data ); 00111 00112 /// Read framebuffer to CPU memory and write to file. 00113 void writeFBtoPPM( GLenum channels, const gutz::vec2i& origin, const gutz::vec2i& dimen, 00114 char* baseFileName, bool sepChannels=false ); 00115 00116 /// Write to a pgm or ppm file called 'baseFileName.pgm' or 'baseFileName.ppm' 00117 /// - 'data' has dimens: height, width, numChannels 00118 /// - PGM is written if 'numChannels' == 1, otherwise a PPM is written 00119 /// - If 'numChannels' == 4, the last channel (alpha) is written to a separate pgm. 00120 void writePNM( char* baseFileName, const gutz::arrayw3ub& data, bool sepChannels ); 00121 00122 /// Write to a nrrd file called 'baseFileName.nrrd' 00123 /// - 'data' has dimens: numSlabs, height, width, numChannels 00124 void writeNrrd3D( const char* baseFileName, const gutz::arrayw4ub& data ); 00125 00126 /// Take a scalar volume and pack into an RGB volume 00127 /// - maxZ is the number of slabs in 'data' to process 00128 /// - maxZ MUST be a multiple of 3!!! 00129 /// - Returned data MUST be deleted to avoid memory leaks :( 00130 /// TODO: This could be fixed with a transfer operation? 00131 gutz::arrayw4ub packScalarToRGB( const gutz::arrayw4ub& data, int maxZ ); 00132 00133 /// Take an RGB-packed, scalar volume and unpack it into scalar slabs 00134 /// - Returned data MUST be deleted to avoid memory leaks :( 00135 /// TODO: This could be fixed with a transfer operation? 00136 /// - 'unpackZ' is the maxZ value for the unpacked data 00137 gutz::arrayw4ub unpackRGBToScalar( const gutz::arrayw4ub& data, int unpackZ ); 00138 00139 inline std::string itoa( int i ) { 00140 std::stringstream stream; 00141 stream << i; 00142 00143 std::string str; 00144 stream >> str; 00145 return str; 00146 } 00147 00148 } /// End of namespace glift 00149 00150 #endif 00151