home *** CD-ROM | disk | FTP | other *** search
/ Quark 3 / Quark3.iso / KATALOG / ARCHIV / TOOL / T001.ZIP / SOURCE.ZIP / texture_res.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-19  |  8.1 KB  |  312 lines

  1. /*
  2. Copyright (C) Matthew 'pagan' Baranowski & Sander 'FireStorm' van Rossen
  3.  
  4. This program is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU General Public License
  6. as published by the Free Software Foundation; either version 2
  7. of the License, or (at your option) any later version.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17. */
  18.  
  19. #include "system.h"
  20. #include "ndictionary.h"
  21. #include "md3gl.h"
  22. #include "md3view.h"
  23. #include "targa.h"
  24.  
  25. /*
  26. bind current texture to filtered mode
  27. */
  28. void bindTextureFiltered()
  29. {
  30.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  31.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
  32.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  33.     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  34. }
  35.  
  36. /*
  37. bind current texture to unfiltered mode
  38. */
  39. void bindTextureUnFiltered()
  40. {
  41.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  42.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  43.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  44.     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  45. }
  46.  
  47.  
  48. /*
  49. bind current to fastest texture rendering
  50. */
  51. void bindTextureFast()
  52. {
  53.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  54.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  55.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  56.     glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
  57. }
  58.  
  59.  
  60. /*
  61. chooses the specific filter to be applied based on current mode
  62. */
  63. void setTextureToFilter()
  64. {
  65.     switch (mdview.texMode) {
  66.         case TEX_FAST: bindTextureFast(); break;
  67.         case TEX_UNFILTERED: bindTextureUnFiltered(); break;
  68.         case TEX_FILTERED: bindTextureFiltered(); break;
  69.     };
  70. }
  71.  
  72.  
  73. /*
  74. sets texture parameters to the current texMode
  75. */
  76. void setTextureFilter()
  77. {
  78.     NodePosition pos;
  79.     TextureGL *texture;
  80.     for (pos=mdview.textureRes->first() ; pos!= NULL ; pos=mdview.textureRes->after(pos)) {
  81.         texture = (TextureGL *)pos->element();
  82.         glBindTexture( GL_TEXTURE_2D, texture->Bind );
  83.         setTextureToFilter();
  84.     }
  85. }
  86.  
  87. /*
  88. searches for the file first in the texturePath, 
  89. then in each descending directory of basepath
  90. */
  91. bool searchForPath( char *texturePath, char *foundPath )
  92. {
  93.     char buffer1[512];
  94.     char buffer2[512];
  95.  
  96.     char *texname = &buffer1[0];
  97.     char *texpath = &buffer2[0];
  98.  
  99.     strcpy( texpath, (const char *)mdview.basepath );
  100.     strcpy( texname, texturePath );
  101.  
  102.     if (!file_exists( texname ))
  103.     {
  104.         int k = strlen(texpath);
  105.         do {
  106.             do    {
  107.                 k--;
  108.             } while ( (k>0) && (texpath[k]!='\\') && (texpath[k]!='/') );
  109.             texpath[k]=0;
  110.             if (k>0) {
  111.                 strcpy( texname, texpath );
  112.                 strcat( texname, "/" );
  113.                 strcat( texname, texturePath );
  114.             }
  115.         } while ( (k>0) && (!file_exists(texname)) );
  116.  
  117.         if (k<=0) {
  118.             Debug("texture \"%s\" not found",texturePath);
  119.             return false;
  120.         }
  121.     }
  122.  
  123.     strcpy( foundPath, texname );
  124.     return true;
  125. }
  126.  
  127. /*
  128. damn smart and efficient texture loader, 
  129. first searches for an existing teature name is parent directories
  130. then checks if texture has already been loaded,
  131. otherwise it loads it up, enters in textureRes manager and returns the new binding
  132. */
  133. GLuint loadTexture( char *texturepath )
  134. {
  135.     char foundPath[512];
  136.     GLenum error;
  137.     // look for the actual file
  138.     if (!searchForPath( texturepath, foundPath )) {
  139.         // if file doesn't exist just exit
  140.         return (GLuint)0;
  141.     }
  142.  
  143.     // check errors from before
  144.     error = glGetError();
  145. #ifdef DEBUG_PARANOID
  146.     if (error) {
  147.         Debug("before loadTexture::glGetError = %d", error);
  148.         return (GLuint)0;
  149.     }
  150. #endif
  151.  
  152.  
  153.     // see if it has been loaded into texture resource manager
  154.     TextureGL *texture = (TextureGL *)mdview.textureRes->find(foundPath);
  155.     
  156.     if (texture) {
  157.         // if so just return the binding
  158.         texture->numUsed++;
  159.         return texture->Bind;
  160.     } else {
  161.         // otherwise must load a new resource
  162.         texture = NULL;
  163.         texture = new TextureGL;
  164.         texture->Data = NULL;
  165.  
  166.         // load the texture
  167.         loadTGA( foundPath, &texture->Data, &texture->Width, &texture->Height, &texture->Type );
  168.  
  169.  
  170.         // now bind to opengl texture, 
  171.         if ( texture->Data != NULL ) {                    
  172.  
  173.             // allocate texture path string
  174.             texture->File = new char[strlen(foundPath)+1];
  175.             strcpy( texture->File, foundPath );
  176.             texture->numUsed = 1;
  177.  
  178.             // TODO: use glGenTextures perhaps
  179.             texture->Bind = ++mdview.topTextureBind;
  180.                                 
  181.             // bind and set texture parameters
  182.             glBindTexture( GL_TEXTURE_2D, texture->Bind );                
  183.             setTextureToFilter();
  184.  
  185.             // upload the image to opengl
  186.             glTexImage2D(GL_TEXTURE_2D, 0, 4, texture->Width,
  187.                                               texture->Height,
  188.                                               0,
  189.                                               GL_RGBA,
  190.                                               GL_UNSIGNED_BYTE,
  191.                                               texture->Data );
  192.  
  193.  
  194.             // check errors from texture binding
  195.             error = glGetError();
  196.             if (error) {
  197.                 Debug("loadTexture::glGetError = %d", error);
  198.                 return (GLuint)0;
  199.             }
  200.  
  201.             // insert texture keyed by file name
  202.             mdview.textureRes->insert( (Object)texture, (Object)texture->File );
  203.         }
  204.         else {        
  205.             delete texture;
  206.             return (GLuint)0;
  207.         }
  208.  
  209.         // return sucessfully loaded texture binding
  210.         return texture->Bind;
  211.     }    
  212. }
  213.  
  214. /* 
  215. reloads all the texture in the texture manager
  216. */
  217. void refreshTextureRes()
  218. {
  219.     NodePosition loc, next;
  220.     TextureGL *texture;
  221.     GLuint error;
  222.  
  223.     for (loc = mdview.textureRes->first() ; loc!=NULL ; loc=next) {
  224.  
  225.         next = mdview.textureRes->after(loc);
  226.         texture = (TextureGL *)loc->element();        
  227.  
  228.         // free texture data
  229.         delete [] texture->Data; texture->Data = NULL;        
  230.         loadTGA( texture->File, &texture->Data, &texture->Width, &texture->Height, &texture->Type );
  231.  
  232.         glBindTexture( GL_TEXTURE_2D, texture->Bind );                
  233.         setTextureToFilter();
  234.  
  235.         // upload the image to opengl
  236.         glTexImage2D(GL_TEXTURE_2D, 0, 4, texture->Width,
  237.                                           texture->Height,
  238.                                           0,
  239.                                           GL_RGBA,
  240.                                           GL_UNSIGNED_BYTE,
  241.                                           texture->Data );
  242.  
  243.  
  244.         // check errors from texture binding
  245.         error = glGetError();
  246.         if (error) {
  247.             Debug("refreshTextureRes::glGetError = %d", error);
  248.             return;
  249.         }
  250.     }                
  251. }
  252.  
  253. /*
  254. frees a texture resource, called whenever a mesh is being freed. a texture is freed only if nothing is using it anymore
  255. */
  256. void freeTexture( GLuint bind )
  257. {
  258.     NodePosition loc, next;
  259.     TextureGL *texture;
  260.  
  261.     if (bind == 0) return;
  262.  
  263.     for (loc = mdview.textureRes->first() ; loc!=NULL ; loc=next) {
  264.         next = mdview.textureRes->after(loc);
  265.         texture = (TextureGL *)loc->element();        
  266.  
  267. #ifdef DEBUG_PARANOID
  268.         if (texture == NULL) Debug("freeTexture: texture element is null");
  269.         if ( texture->Data == NULL ) Debug("freeTexture: texture Data is null");
  270. #endif
  271.  
  272.         if (bind == texture->Bind) {
  273.             texture->numUsed--;
  274.             if (texture->numUsed == 0) {
  275.                 ((NodeSequence)(mdview.textureRes))->remove( loc );
  276.                 delete [] texture->Data; texture->Data = NULL;                
  277.                 delete [] texture->File;
  278.                 delete texture; texture = NULL;                
  279.             }
  280.             return;
  281.         }
  282.     }
  283. }
  284.  
  285. /*
  286. deletes the entire texture resource manager with all its textures at once, usually called when reseting viewer state
  287. */
  288. void freeTextureRes()
  289. {
  290.     NodePosition loc, next;
  291.     TextureGL *texture;
  292.  
  293.     for (loc = mdview.textureRes->first() ; loc!=NULL ; loc=next) {
  294.  
  295.         next = mdview.textureRes->after(loc);
  296.         texture = (TextureGL *)loc->element();        
  297.  
  298. #ifdef DEBUG_PARANOID
  299.         if (texture == NULL) Debug("freeTextureRes: texture element is null");
  300.         if ( texture->Data == NULL ) Debug("freeTextureRes: texture Data is null");
  301. #endif
  302.         
  303.         ((NodeSequence)(mdview.textureRes))->remove( loc );
  304.         
  305.         delete [] texture->Data; texture->Data = NULL;        
  306.         delete [] texture->File;
  307.         delete texture; texture = NULL;                
  308.     }            
  309.  
  310.     mdview.topTextureBind = 0;
  311. }
  312.