Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

# OgreQuake3Shader.cpp

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright © 2000-2002 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025
    00026 #include "OgreQuake3Shader.h"
    00027 #include "OgreSceneManager.h"
    00028 #include "OgreMaterial.h"
    00029 #include "OgreTechnique.h"
    00030 #include "OgrePass.h"
    00031 #include "OgreTextureUnitState.h"
    00032 #include "OgreMath.h"
    00033 #include "OgreLogManager.h"
    00034 #include "OgreTextureManager.h"
    00035
    00036 namespace Ogre {
    00037
    00038
    00039     //-----------------------------------------------------------------------
    00040     Quake3Shader::Quake3Shader(const String& name)
    00041     {
    00042         mName = name;
    00043         numPasses = 0;
    00044         deformFunc = DEFORM_FUNC_NONE;
    00045         farbox = false;
    00046         skyDome = false;
    00047         flags = 0;
    00048         fog = false;
    00049         cullMode = MANUAL_CULL_BACK;
    00050
    00051     }
    00052     //-----------------------------------------------------------------------
    00053     Quake3Shader::~Quake3Shader()
    00054     {
    00055     }
    00056     //-----------------------------------------------------------------------
    00057     void Quake3Shader::load(void)
    00058     {
    00059         // Do nothing
    00060     }
    00061     //-----------------------------------------------------------------------
    00062     void Quake3Shader::unload(void)
    00063     {
    00064         // Do nothing
    00065     }
    00066     //-----------------------------------------------------------------------
    00067     Material* Quake3Shader::createAsMaterial(SceneManager* sm, int lightmapNumber)
    00068     {
    00069         char matName[72];
    00070         sprintf(matName, "%s#%d", mName.c_str(), lightmapNumber);
    00071         Material* mat = sm->createMaterial(matName);
    00072
    00073         char msg[256];
    00074         sprintf(msg, "Using Q3 shader %s", mName.c_str());
    00075         LogManager::getSingleton().logMessage(msg, LML_CRITICAL);
    00076         for (int p = 0; p < numPasses; ++p)
    00077         {
    00078             TextureUnitState* t;
    00079             // Create basic texture
    00080             if (pass[p].textureName == "$lightmap")
    00081             {
    00082                 char lightmapName[16];
    00083                 sprintf(lightmapName, "@lightmap%d", lightmapNumber);
    00084                 t = mat->getTechnique(0)->getPass(0)->createTextureUnitState(lightmapName);
    00085             }
    00086             // Animated texture support
    00087             else if (pass[p].animNumFrames > 0)
    00088             {
    00089                 Real sequenceTime = pass[p].animNumFrames / pass[p].animFps;
    00090                 /* Pre-load textures
    00091                    We need to know if each one was loaded OK since extensions may change for each
    00092                    Quake3 can still include alternate extension filenames e.g. jpg instead of tga
    00093                    Pain in the arse - have to check for each frame as letters<n>.tga for example
    00094                    is different per frame!
    00095                 */
    00096                 for (unsigned int alt = 0; alt < pass[p].animNumFrames; ++alt)
    00097                 {
    00098                     try {
    00099                         TextureManager::getSingleton().load(pass[p].frames[alt]);
    00100                     }
    00101                     catch (...)
    00102                     {
    00103                         // Try alternate extension
    00104                         pass[p].frames[alt] = getAlternateName(pass[p].frames[alt]);
    00105                         try {
    00106                             TextureManager::getSingleton().load(pass[p].frames[alt]);
    00107                         }
    00108                         catch (...)
    00109                         { // stuffed - no texture
    00110                         }
    00111                     }
    00112
    00113                 }
    00114
    00115                 t = mat->getTechnique(0)->getPass(0)->createTextureUnitState("");
    00116                 t->setAnimatedTextureName(pass[p].frames, pass[p].animNumFrames, sequenceTime);
    00117
    00118             }
    00119             else
    00120             {
    00121                 // Quake3 can still include alternate extension filenames e.g. jpg instead of tga
    00122                 // Pain in the arse - have to check for failure
    00123                 try {
    00124                     TextureManager::getSingleton().load(pass[p].textureName);
    00125                 }
    00126                 catch (...)
    00127                 {
    00128                     // Try alternate extension
    00129                     pass[p].textureName = getAlternateName(pass[p].textureName);
    00130                     try {
    00131                         TextureManager::getSingleton().load(pass[p].textureName);
    00132                     }
    00133                     catch (...)
    00134                     { // stuffed - no texture
    00135                     }
    00136                 }
    00137                 t = mat->getTechnique(0)->getPass(0)->createTextureUnitState(pass[p].textureName);
    00138             }
    00139             // Blending
    00140             if (p == 0)
    00141             {
    00142                 // scene blend
    00143                 mat->setSceneBlending(pass[p].blendSrc, pass[p].blendDest);
    00144                 if (mat->isTransparent() &&
    00145                     pass[p].blendSrc != SBF_SOURCE_ALPHA)
    00146                     mat->setDepthWriteEnabled(false);
    00147
    00148                 t->setColourOperation(LBO_REPLACE);
    00149             }
    00150             else
    00151             {
    00152                 if (pass[p].customBlend)
    00153                 {
    00154                     // Fallback for now
    00155                     t->setColourOperation(LBO_MODULATE);
    00156                 }
    00157                 else
    00158                 {
    00159                     // simple layer blend
    00160                     t->setColourOperation(pass[p].blend);
    00161                 }
    00162             }
    00163             // Tex coords
    00164             if (pass[p].texGen == TEXGEN_BASE)
    00165             {
    00166                 t->setTextureCoordSet(0);
    00167             }
    00168             else if (pass[p].texGen == TEXGEN_LIGHTMAP)
    00169             {
    00170                 t->setTextureCoordSet(1);
    00171             }
    00172             else if (pass[p].texGen == TEXGEN_ENVIRONMENT)
    00173             {
    00174                 t->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR);
    00175             }
    00176             // Tex mod
    00177             // Scale
    00178             t->setTextureUScale(pass[p].tcModScale[0]);
    00179             t->setTextureVScale(pass[p].tcModScale[1]);
    00180             // Procedural mods
    00181             // Custom - don't use mod if generating environment
    00182             // Because I do env a different way it look horrible
    00183             if (pass[p].texGen != TEXGEN_ENVIRONMENT)
    00184             {
    00185                 if (pass[p].tcModRotate)
    00186                 {
    00187                     t->setRotateAnimation(pass[p].tcModRotate);
    00188                 }
    00189                 if (pass[p].tcModScroll[0] || pass[p].tcModScroll[1])
    00190                 {
    00191                     if (pass[p].tcModTurbOn)
    00192                     {
    00193                         // Turbulent scroll
    00194                         if (pass[p].tcModScroll[0])
    00195                         {
    00196                             t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_U, WFT_SINE,
    00197                                 pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
    00198                         }
    00199                         if (pass[p].tcModScroll[1])
    00200                         {
    00201                             t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_V, WFT_SINE,
    00202                                 pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
    00203                         }
    00204                     }
    00205                     else
    00206                     {
    00207                         // Constant scroll
    00208                         t->setScrollAnimation(pass[p].tcModScroll[0], pass[p].tcModScroll[1]);
    00209                     }
    00210                 }
    00211                 if (pass[p].tcModStretchWave != SHADER_FUNC_NONE)
    00212                 {
    00213                     WaveformType wft;
    00214                     switch(pass[p].tcModStretchWave)
    00215                     {
    00216                     case SHADER_FUNC_SIN:
    00217                         wft = WFT_SINE;
    00218                         break;
    00219                     case SHADER_FUNC_TRIANGLE:
    00220                         wft = WFT_TRIANGLE;
    00221                         break;
    00222                     case SHADER_FUNC_SQUARE:
    00223                         wft = WFT_SQUARE;
    00224                         break;
    00225                     case SHADER_FUNC_SAWTOOTH:
    00226                         wft = WFT_SAWTOOTH;
    00227                         break;
    00228                     case SHADER_FUNC_INVERSESAWTOOTH:
    00229                         wft = WFT_INVERSE_SAWTOOTH;
    00230                         break;
    00231                     default:
    00232                         break;
    00233                     }
    00234                     // Create wave-based stretcher
    00235                     t->setTransformAnimation(TextureUnitState::TT_SCALE_U, wft, pass[p].tcModStretchParams[3],
    00236                         pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
    00237                     t->setTransformAnimation(TextureUnitState::TT_SCALE_V, wft, pass[p].tcModStretchParams[3],
    00238                         pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
    00239                 }
    00240             }
    00241             // Address mode
    00242             t->setTextureAddressingMode(pass[p].addressMode);
    00243             // Alpha mode
    00244             t->setAlphaRejectSettings(pass[p].alphaFunc, pass[p].alphaVal);
    00245
    00246             //assert(!t->isBlank());
    00247
    00248
    00249         }
    00250         // Do farbox (create new material)
    00251
    00252         // Do skydome (use this material)
    00253         if (skyDome)
    00254         {
    00255             // Quake3 is always aligned with Z upwards
    00256             Quaternion q;
    00257             q.FromAngleAxis(Radian(Math::HALF_PI), Vector3::UNIT_X);
    00258             // Also draw last, and make close to camera (far clip plane is shorter)
    00259             sm->setSkyDome(true, matName, 20 - (cloudHeight / 256 * 18), 12, 2000, false, q);
    00260         }
    00261
    00262
    00263         // Set culling mode and lighting to defaults
    00264         mat->setCullingMode(CULL_NONE);
    00265         mat->setManualCullingMode(cullMode);
    00266         mat->setLightingEnabled(false);
    00267         mat->load();
    00268         return mat;
    00269     }
    00270     String Quake3Shader::getAlternateName(const String& texName)
    00271     {
    00272         // Get alternative JPG to TGA and vice versa
    00273         size_t pos;
    00274         String ext, base;
    00275
    00276         pos = texName.find_last_of(".");
    00277         ext = texName.substr(pos, 4);
    00278         StringUtil::toLowerCase(ext);
    00279         base = texName.substr(0,pos);
    00280         if (ext == ".jpg")
    00281         {
    00282             return base + ".tga";
    00283         }
    00284         else
    00285         {
    00286             return base + ".jpg";
    00287         }
    00288
    00289     }
    00290 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:40 2004