home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright (C) Matthew 'pagan' Baranowski & Sander 'FireStorm' van Rossen
-
- 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
- #include "system.h"
- #include "ndictionary.h"
- #include "md3gl.h"
- #include "md3view.h"
- #include "targa.h"
-
- /*
- bind current texture to filtered mode
- */
- void bindTextureFiltered()
- {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
- }
-
- /*
- bind current texture to unfiltered mode
- */
- void bindTextureUnFiltered()
- {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
- }
-
-
- /*
- bind current to fastest texture rendering
- */
- void bindTextureFast()
- {
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
- }
-
-
- /*
- chooses the specific filter to be applied based on current mode
- */
- void setTextureToFilter()
- {
- switch (mdview.texMode) {
- case TEX_FAST: bindTextureFast(); break;
- case TEX_UNFILTERED: bindTextureUnFiltered(); break;
- case TEX_FILTERED: bindTextureFiltered(); break;
- };
- }
-
-
- /*
- sets texture parameters to the current texMode
- */
- void setTextureFilter()
- {
- NodePosition pos;
- TextureGL *texture;
- for (pos=mdview.textureRes->first() ; pos!= NULL ; pos=mdview.textureRes->after(pos)) {
- texture = (TextureGL *)pos->element();
- glBindTexture( GL_TEXTURE_2D, texture->Bind );
- setTextureToFilter();
- }
- }
-
- /*
- searches for the file first in the texturePath,
- then in each descending directory of basepath
- */
- bool searchForPath( char *texturePath, char *foundPath )
- {
- char buffer1[512];
- char buffer2[512];
-
- char *texname = &buffer1[0];
- char *texpath = &buffer2[0];
-
- strcpy( texpath, (const char *)mdview.basepath );
- strcpy( texname, texturePath );
-
- if (!file_exists( texname ))
- {
- int k = strlen(texpath);
- do {
- do {
- k--;
- } while ( (k>0) && (texpath[k]!='\\') && (texpath[k]!='/') );
- texpath[k]=0;
- if (k>0) {
- strcpy( texname, texpath );
- strcat( texname, "/" );
- strcat( texname, texturePath );
- }
- } while ( (k>0) && (!file_exists(texname)) );
-
- if (k<=0) {
- Debug("texture \"%s\" not found",texturePath);
- return false;
- }
- }
-
- strcpy( foundPath, texname );
- return true;
- }
-
- /*
- damn smart and efficient texture loader,
- first searches for an existing teature name is parent directories
- then checks if texture has already been loaded,
- otherwise it loads it up, enters in textureRes manager and returns the new binding
- */
- GLuint loadTexture( char *texturepath )
- {
- char foundPath[512];
- GLenum error;
- // look for the actual file
- if (!searchForPath( texturepath, foundPath )) {
- // if file doesn't exist just exit
- return (GLuint)0;
- }
-
- // check errors from before
- error = glGetError();
- #ifdef DEBUG_PARANOID
- if (error) {
- Debug("before loadTexture::glGetError = %d", error);
- return (GLuint)0;
- }
- #endif
-
-
- // see if it has been loaded into texture resource manager
- TextureGL *texture = (TextureGL *)mdview.textureRes->find(foundPath);
-
- if (texture) {
- // if so just return the binding
- texture->numUsed++;
- return texture->Bind;
- } else {
- // otherwise must load a new resource
- texture = NULL;
- texture = new TextureGL;
- texture->Data = NULL;
-
- // load the texture
- loadTGA( foundPath, &texture->Data, &texture->Width, &texture->Height, &texture->Type );
-
-
- // now bind to opengl texture,
- if ( texture->Data != NULL ) {
-
- // allocate texture path string
- texture->File = new char[strlen(foundPath)+1];
- strcpy( texture->File, foundPath );
- texture->numUsed = 1;
-
- // TODO: use glGenTextures perhaps
- texture->Bind = ++mdview.topTextureBind;
-
- // bind and set texture parameters
- glBindTexture( GL_TEXTURE_2D, texture->Bind );
- setTextureToFilter();
-
- // upload the image to opengl
- glTexImage2D(GL_TEXTURE_2D, 0, 4, texture->Width,
- texture->Height,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- texture->Data );
-
-
- // check errors from texture binding
- error = glGetError();
- if (error) {
- Debug("loadTexture::glGetError = %d", error);
- return (GLuint)0;
- }
-
- // insert texture keyed by file name
- mdview.textureRes->insert( (Object)texture, (Object)texture->File );
- }
- else {
- delete texture;
- return (GLuint)0;
- }
-
- // return sucessfully loaded texture binding
- return texture->Bind;
- }
- }
-
- /*
- reloads all the texture in the texture manager
- */
- void refreshTextureRes()
- {
- NodePosition loc, next;
- TextureGL *texture;
- GLuint error;
-
- for (loc = mdview.textureRes->first() ; loc!=NULL ; loc=next) {
-
- next = mdview.textureRes->after(loc);
- texture = (TextureGL *)loc->element();
-
- // free texture data
- delete [] texture->Data; texture->Data = NULL;
- loadTGA( texture->File, &texture->Data, &texture->Width, &texture->Height, &texture->Type );
-
- glBindTexture( GL_TEXTURE_2D, texture->Bind );
- setTextureToFilter();
-
- // upload the image to opengl
- glTexImage2D(GL_TEXTURE_2D, 0, 4, texture->Width,
- texture->Height,
- 0,
- GL_RGBA,
- GL_UNSIGNED_BYTE,
- texture->Data );
-
-
- // check errors from texture binding
- error = glGetError();
- if (error) {
- Debug("refreshTextureRes::glGetError = %d", error);
- return;
- }
- }
- }
-
- /*
- frees a texture resource, called whenever a mesh is being freed. a texture is freed only if nothing is using it anymore
- */
- void freeTexture( GLuint bind )
- {
- NodePosition loc, next;
- TextureGL *texture;
-
- if (bind == 0) return;
-
- for (loc = mdview.textureRes->first() ; loc!=NULL ; loc=next) {
- next = mdview.textureRes->after(loc);
- texture = (TextureGL *)loc->element();
-
- #ifdef DEBUG_PARANOID
- if (texture == NULL) Debug("freeTexture: texture element is null");
- if ( texture->Data == NULL ) Debug("freeTexture: texture Data is null");
- #endif
-
- if (bind == texture->Bind) {
- texture->numUsed--;
- if (texture->numUsed == 0) {
- ((NodeSequence)(mdview.textureRes))->remove( loc );
- delete [] texture->Data; texture->Data = NULL;
- delete [] texture->File;
- delete texture; texture = NULL;
- }
- return;
- }
- }
- }
-
- /*
- deletes the entire texture resource manager with all its textures at once, usually called when reseting viewer state
- */
- void freeTextureRes()
- {
- NodePosition loc, next;
- TextureGL *texture;
-
- for (loc = mdview.textureRes->first() ; loc!=NULL ; loc=next) {
-
- next = mdview.textureRes->after(loc);
- texture = (TextureGL *)loc->element();
-
- #ifdef DEBUG_PARANOID
- if (texture == NULL) Debug("freeTextureRes: texture element is null");
- if ( texture->Data == NULL ) Debug("freeTextureRes: texture Data is null");
- #endif
-
- ((NodeSequence)(mdview.textureRes))->remove( loc );
-
- delete [] texture->Data; texture->Data = NULL;
- delete [] texture->File;
- delete texture; texture = NULL;
- }
-
- mdview.topTextureBind = 0;
- }
-