Back to index

supertuxkart  0.5+dfsg1
material.cpp
Go to the documentation of this file.
00001 //  $Id: material.cpp 2111 2008-05-31 07:04:30Z cosmosninja $
00002 //
00003 //  SuperTuxKart - a fun racing game with go-kart
00004 //  Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
00005 //
00006 //  This program is free software; you can redistribute it and/or
00007 //  modify it under the terms of the GNU General Public License
00008 //  as published by the Free Software Foundation; either version 2
00009 //  of the License, or (at your option) any later version.
00010 //
00011 //  This program is distributed in the hope that it will be useful,
00012 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //  GNU General Public License for more details.
00015 //
00016 //  You should have received a copy of the GNU General Public License
00017 //  along with this program; if not, write to the Free Software
00018 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 
00020 #include "file_manager.hpp"
00021 #include "material.hpp"
00022 #include "string_utils.hpp"
00023 
00024 #define UCLAMP   1
00025 #define VCLAMP   2
00026 
00027 int clearSpheremap ( ssgEntity * )
00028 {
00029     glDisable   ( GL_TEXTURE_GEN_S ) ;
00030     glDisable   ( GL_TEXTURE_GEN_T ) ;
00031     return true ;
00032 }   // clearSpheremap
00033 
00034 //=============================================================================
00035 int setSpheremap ( ssgEntity * )
00036 {
00037     glTexGeni   ( GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ) ;
00038     glTexGeni   ( GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP ) ;
00039     glEnable    ( GL_TEXTURE_GEN_S ) ;
00040     glEnable    ( GL_TEXTURE_GEN_T ) ;
00041     return true ;
00042 }   // setSpheremap
00043 
00044 //=============================================================================
00045 bool Material::parseBool ( char **p )
00046 {
00047     /* Skip leading spaces */
00048 
00049     while ( **p <= ' ' && **p != '\0' ) (*p)++ ;
00050 
00051     const bool RES = ( ( **p == 'Y' ) || ( **p == 'y' ) ) ;
00052 
00053     while ( **p > ' ' && **p != '\0' ) (*p)++ ;
00054 
00055     return RES ;
00056 }   // parseBool
00057 
00058 //-----------------------------------------------------------------------------
00059 int Material::parseInt ( char **p )
00060 {
00061     /* Skip leading spaces */
00062 
00063     while ( **p <= ' ' && **p != '\0' ) (*p)++ ;
00064 
00065     return strtol ( *p, p, 0 ) ;
00066 }   // parseInt 
00067 
00068 //-----------------------------------------------------------------------------
00069 float Material::parseFloat ( char **p )
00070 {
00071     /* Skip leading spaces */
00072 
00073     while ( **p <= ' ' && **p != '\0' ) (*p)++ ;
00074 
00075     return (float)strtod ( *p, p ) ;
00076 }   // parseFloat 
00077 
00078 //-----------------------------------------------------------------------------
00079 Material::Material(int index)
00080 {
00081     m_texname = "";
00082     m_predraw  = m_postdraw = NULL ;
00083 
00084     init   (index);
00085     install();
00086 }   // Material
00087 
00088 //-----------------------------------------------------------------------------
00089 Material::Material(const std::string& fname, char *description, 
00090                    int index, bool is_full_path)
00091 {
00092     m_texname = fname;
00093     m_predraw  = m_postdraw = NULL ;
00094 
00095     init (index);
00096 
00097     if(strlen(description)>0)
00098     {
00099         m_clamp_tex    = parseBool (&description) ? UCLAMP : 0 ;
00100         m_clamp_tex   += parseBool (&description) ? VCLAMP : 0 ;
00101         
00102         m_transparency = parseBool (&description);
00103         m_alpha_ref    = parseFloat(&description);
00104         m_lighting     = parseBool (&description);
00105         m_sphere_map   = parseBool (&description);
00106         m_friction     = parseFloat(&description);
00107         m_ignore       = parseBool (&description);
00108         m_zipper       = parseBool (&description);
00109         m_resetter     = parseBool (&description);
00110         m_collideable  = parseBool (&description);
00111     }
00112     install(is_full_path);
00113 }   // Material
00114 
00115 //-----------------------------------------------------------------------------
00116 Material::~Material()
00117 {
00118     ssgDeRefDelete(m_state);
00119 }   // ~Material
00120 
00121 //-----------------------------------------------------------------------------
00122 void Material::init(int index)
00123 {
00124     m_index        = index ;
00125     m_clamp_tex    = 0     ;
00126     m_transparency = false ;
00127     m_alpha_ref    = 0.1f  ;
00128     m_lighting     = true  ;
00129     m_sphere_map   = false ;
00130     m_friction     = 1.0f  ;
00131     m_ignore       = false ;
00132     m_zipper       = false ;
00133     m_resetter     = false ;
00134     m_collideable  = true  ;
00135 }
00136 
00137 //-----------------------------------------------------------------------------
00138 void Material::applyToLeaf(ssgLeaf *l)
00139 {
00140     if ( m_predraw  ) l -> setCallback ( SSG_CALLBACK_PREDRAW , m_predraw  ) ;
00141     if ( m_postdraw ) l -> setCallback ( SSG_CALLBACK_POSTDRAW, m_postdraw ) ;
00142 }   // applyToLeaf
00143 
00144 //-----------------------------------------------------------------------------
00145 void Material::install(bool is_full_path)
00146 {
00147     if ( isSphereMap () )
00148     {
00149         m_predraw  =   setSpheremap ;
00150         m_postdraw = clearSpheremap ;
00151     }
00152 
00153     m_state = new ssgSimpleState ;
00154 
00155     m_state -> ref () ;
00156     m_state -> setExternalPropertyIndex ( m_index ) ;
00157     if ( m_texname.size()>0 )
00158     {
00159         std::string fn=is_full_path ? m_texname 
00160                                     : file_manager->getTextureFile(m_texname);
00161         if(fn=="")
00162         {
00163             fprintf(stderr, "WARNING: texture '%s' not found.\n", 
00164                     m_texname.c_str());
00165         }
00166         m_state -> setTexture ( fn.c_str(), !(m_clamp_tex & UCLAMP),
00167                               !(m_clamp_tex & VCLAMP) );
00168         m_state -> enable  ( GL_TEXTURE_2D ) ;
00169     }
00170     else
00171         m_state -> disable ( GL_TEXTURE_2D ) ;
00172 
00173     if ( m_lighting )
00174         m_state -> enable  ( GL_LIGHTING ) ;
00175     else
00176         m_state -> disable ( GL_LIGHTING ) ;
00177 
00178     m_state -> setShadeModel ( GL_SMOOTH ) ;
00179     m_state -> enable        ( GL_COLOR_MATERIAL ) ;
00180     m_state -> enable        ( GL_CULL_FACE      ) ;
00181     m_state -> setColourMaterial ( GL_AMBIENT_AND_DIFFUSE ) ;
00182     m_state -> setMaterial   ( GL_EMISSION, 0, 0, 0, 1 ) ;
00183     m_state -> setMaterial   ( GL_SPECULAR, 0, 0, 0, 1 ) ;
00184     m_state -> setShininess  ( 0 ) ;
00185 
00186     if ( m_transparency )
00187     {
00188         m_state -> setTranslucent () ;
00189         m_state -> enable         ( GL_ALPHA_TEST ) ;
00190         m_state -> setAlphaClamp  ( m_alpha_ref ) ;
00191         m_state -> enable         ( GL_BLEND ) ;
00192     }
00193     else
00194     {
00195         m_state -> setOpaque () ;
00196         m_state -> disable   ( GL_BLEND ) ;
00197     }
00198 
00199     // now set the name to the basename, so that all tests work as expected
00200     m_texname  = StringUtils::basename(m_texname);
00201 }
00202