Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/PlugIns/BSPSceneManager/src/OgreQuake3Shader.cpp @ 3

Last change on this file since 3 was 3, checked in by anonymous, 17 years ago

=update

File size: 10.7 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4    (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2006 Torus Knot Software Ltd
8Also see acknowledgements in Readme.html
9
10This program is free software; you can redistribute it and/or modify it under
11the terms of the GNU Lesser General Public License as published by the Free Software
12Foundation; either version 2 of the License, or (at your option) any later
13version.
14
15This program is distributed in the hope that it will be useful, but WITHOUT
16ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
18
19You should have received a copy of the GNU Lesser General Public License along with
20this program; if not, write to the Free Software Foundation, Inc., 59 Temple
21Place - Suite 330, Boston, MA 02111-1307, USA, or go to
22http://www.gnu.org/copyleft/lesser.txt.
23
24You may alternatively use this source under the terms of a specific version of
25the OGRE Unrestricted License provided you have obtained such a license from
26Torus Knot Software Ltd.
27-----------------------------------------------------------------------------
28*/
29
30#include "OgreQuake3Shader.h"
31#include "OgreSceneManager.h"
32#include "OgreMaterial.h"
33#include "OgreTechnique.h"
34#include "OgrePass.h"
35#include "OgreTextureUnitState.h"
36#include "OgreMath.h"
37#include "OgreLogManager.h"
38#include "OgreTextureManager.h"
39#include "OgreRoot.h"
40#include "OgreMaterialManager.h"
41
42namespace Ogre {
43
44
45    //-----------------------------------------------------------------------
46    Quake3Shader::Quake3Shader(const String& name)
47    {
48        mName = name;
49        numPasses = 0;
50        deformFunc = DEFORM_FUNC_NONE;
51        farbox = false;
52        skyDome = false;
53        flags = 0;
54        fog = false;
55        cullMode = MANUAL_CULL_BACK;
56
57    }
58    //-----------------------------------------------------------------------
59    Quake3Shader::~Quake3Shader()
60    {
61    }
62    //-----------------------------------------------------------------------
63    MaterialPtr Quake3Shader::createAsMaterial(int lightmapNumber)
64    {
65                String matName;
66                StringUtil::StrStreamType str;
67        String resourceGroup = ResourceGroupManager::getSingleton().getWorldResourceGroupName();
68
69        str << mName << "#" << lightmapNumber;
70                matName = str.str();
71
72        MaterialPtr mat = MaterialManager::getSingleton().create(matName, 
73            resourceGroup);
74                Ogre::Pass* ogrePass = mat->getTechnique(0)->getPass(0);
75
76        LogManager::getSingleton().logMessage("Using Q3 shader " + mName, LML_CRITICAL);
77        for (int p = 0; p < numPasses; ++p)
78        {
79            TextureUnitState* t;
80            // Create basic texture
81            if (pass[p].textureName == "$lightmap")
82            {
83                StringUtil::StrStreamType str2;
84                                str2 << "@lightmap" << lightmapNumber;
85                t = ogrePass->createTextureUnitState(str2.str());
86            }
87            // Animated texture support
88            else if (pass[p].animNumFrames > 0)
89            {
90                Real sequenceTime = pass[p].animNumFrames / pass[p].animFps;
91                /* Pre-load textures
92                   We need to know if each one was loaded OK since extensions may change for each
93                   Quake3 can still include alternate extension filenames e.g. jpg instead of tga
94                   Pain in the arse - have to check for each frame as letters<n>.tga for example
95                   is different per frame!
96                */
97                for (unsigned int alt = 0; alt < pass[p].animNumFrames; ++alt)
98                {
99                    if (!ResourceGroupManager::getSingleton().resourceExists(
100                        resourceGroup, pass[p].frames[alt]))
101                    {
102                        // Try alternate extension
103                        pass[p].frames[alt] = getAlternateName(pass[p].frames[alt]);
104                        if (!ResourceGroupManager::getSingleton().resourceExists(
105                            resourceGroup, pass[p].frames[alt]))
106                        { 
107                            // stuffed - no texture
108                            continue;
109                        }
110                    }
111
112                }
113
114                t = ogrePass->createTextureUnitState("");
115                t->setAnimatedTextureName(pass[p].frames, pass[p].animNumFrames, sequenceTime);
116
117            }
118            else
119            {
120                // Quake3 can still include alternate extension filenames e.g. jpg instead of tga
121                // Pain in the arse - have to check for failure
122                if (!ResourceGroupManager::getSingleton().resourceExists(
123                    resourceGroup, pass[p].textureName))
124                {
125                    // Try alternate extension
126                    pass[p].textureName = getAlternateName(pass[p].textureName);
127                    if (!ResourceGroupManager::getSingleton().resourceExists(
128                        resourceGroup, pass[p].textureName))
129                    { 
130                        // stuffed - no texture
131                        continue;
132                    }
133                }
134                t = ogrePass->createTextureUnitState(pass[p].textureName);
135            }
136            // Blending
137            if (p == 0)
138            {
139                // scene blend
140                mat->setSceneBlending(pass[p].blendSrc, pass[p].blendDest);
141                if (mat->isTransparent())
142                    mat->setDepthWriteEnabled(false);
143
144                t->setColourOperation(LBO_REPLACE);
145                                // Alpha mode
146                                ogrePass->setAlphaRejectSettings(
147                                        pass[p].alphaFunc, pass[p].alphaVal);
148            }
149            else
150            {
151                if (pass[p].customBlend)
152                {
153                    // Fallback for now
154                    t->setColourOperation(LBO_MODULATE);
155                }
156                else
157                {
158                    // simple layer blend
159                    t->setColourOperation(pass[p].blend);
160                }
161                                // Alpha mode, prefer 'most alphary'
162                                CompareFunction currFunc = ogrePass->getAlphaRejectFunction();
163                                unsigned char currVal = ogrePass->getAlphaRejectValue();
164                                if (pass[p].alphaFunc > currFunc ||
165                                        (pass[p].alphaFunc == currFunc && pass[p].alphaVal < currVal))
166                                {
167                                        ogrePass->setAlphaRejectSettings(
168                                                pass[p].alphaFunc, pass[p].alphaVal);
169                                }
170            }
171            // Tex coords
172            if (pass[p].texGen == TEXGEN_BASE)
173            {
174                t->setTextureCoordSet(0);
175            }
176            else if (pass[p].texGen == TEXGEN_LIGHTMAP)
177            {
178                t->setTextureCoordSet(1);
179            }
180            else if (pass[p].texGen == TEXGEN_ENVIRONMENT)
181            {
182                t->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR);
183            }
184            // Tex mod
185            // Scale
186            t->setTextureUScale(pass[p].tcModScale[0]);
187            t->setTextureVScale(pass[p].tcModScale[1]);
188            // Procedural mods
189            // Custom - don't use mod if generating environment
190            // Because I do env a different way it look horrible
191            if (pass[p].texGen != TEXGEN_ENVIRONMENT)
192            {
193                if (pass[p].tcModRotate)
194                {
195                    t->setRotateAnimation(pass[p].tcModRotate);
196                }
197                if (pass[p].tcModScroll[0] || pass[p].tcModScroll[1])
198                {
199                    if (pass[p].tcModTurbOn)
200                    {
201                        // Turbulent scroll
202                        if (pass[p].tcModScroll[0])
203                        {
204                            t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_U, WFT_SINE,
205                                pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
206                        }
207                        if (pass[p].tcModScroll[1])
208                        {
209                            t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_V, WFT_SINE,
210                                pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]);
211                        }
212                    }
213                    else
214                    {
215                        // Constant scroll
216                        t->setScrollAnimation(pass[p].tcModScroll[0], pass[p].tcModScroll[1]);
217                    }
218                }
219                if (pass[p].tcModStretchWave != SHADER_FUNC_NONE)
220                {
221                    WaveformType wft;
222                    switch(pass[p].tcModStretchWave)
223                    {
224                    case SHADER_FUNC_SIN:
225                        wft = WFT_SINE;
226                        break;
227                    case SHADER_FUNC_TRIANGLE:
228                        wft = WFT_TRIANGLE;
229                        break;
230                    case SHADER_FUNC_SQUARE:
231                        wft = WFT_SQUARE;
232                        break;
233                    case SHADER_FUNC_SAWTOOTH:
234                        wft = WFT_SAWTOOTH;
235                        break;
236                    case SHADER_FUNC_INVERSESAWTOOTH:
237                        wft = WFT_INVERSE_SAWTOOTH;
238                        break;
239                    default:
240                        break;
241                    }
242                    // Create wave-based stretcher
243                    t->setTransformAnimation(TextureUnitState::TT_SCALE_U, wft, pass[p].tcModStretchParams[3],
244                        pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
245                    t->setTransformAnimation(TextureUnitState::TT_SCALE_V, wft, pass[p].tcModStretchParams[3],
246                        pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]);
247                }
248            }
249            // Address mode
250            t->setTextureAddressingMode(pass[p].addressMode);
251
252            //assert(!t->isBlank());
253
254
255        }
256        // Do farbox (create new material)
257
258        // Set culling mode and lighting to defaults
259        mat->setCullingMode(CULL_NONE);
260        mat->setManualCullingMode(cullMode);
261        mat->setLightingEnabled(false);
262        mat->load();
263        return mat;
264    }
265    String Quake3Shader::getAlternateName(const String& texName)
266    {
267        // Get alternative JPG to TGA and vice versa
268        size_t pos;
269        String ext, base;
270
271        pos = texName.find_last_of(".");
272        ext = texName.substr(pos, 4);
273                StringUtil::toLowerCase(ext);
274        base = texName.substr(0,pos);
275        if (ext == ".jpg")
276        {
277            return base + ".tga";
278        }
279        else
280        {
281            return base + ".jpg";
282        }
283
284    }
285}
Note: See TracBrowser for help on using the repository browser.