~ubuntu-branches/debian/sid/ember/sid

« back to all changes in this revision

Viewing changes to src/components/ogre/SceneManagers/EmberPagingSceneManager/src/OgrePagingLandScapeTexture.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2009-07-23 07:46:40 UTC
  • Revision ID: james.westby@ubuntu.com-20090723074640-wh0ukzis0kda36qv
Tags: upstream-0.5.6
ImportĀ upstreamĀ versionĀ 0.5.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
OgrePagingLandScapeTexture.cpp  -  description
 
3
-------------------
 
4
begin                : Fri Apr 16 2004
 
5
copyright            : (C) 2003-2006 by Jose A Milan && Tuan Kuranes
 
6
email                : spoke@supercable.es & tuan.kuranes@free.fr
 
7
***************************************************************************/
 
8
 
 
9
/***************************************************************************
 
10
*                                                                         *
 
11
*   This program is free software; you can redistribute it and/or modify  *
 
12
*   it under the terms of the GNU Lesser General Public License as published by  *
 
13
*   the Free Software Foundation; either version 2 of the License, or     *
 
14
*   (at your option) any later version.                                   *
 
15
*                                                                         *
 
16
***************************************************************************/
 
17
 
 
18
#include "OgrePagingLandScapePrecompiledHeaders.h"
 
19
 
 
20
#include "OgreVector3.h"
 
21
#include "OgreColourValue.h"
 
22
 
 
23
#include "OgreStringConverter.h"
 
24
#include "OgreMaterialManager.h"
 
25
#include "OgreTextureManager.h"
 
26
#include "OgreTechnique.h"
 
27
#include "OgrePass.h"
 
28
 
 
29
#include "OgrePagingLandScapeTexture.h"
 
30
 
 
31
#include "OgrePagingLandScapeOptions.h"
 
32
#include "OgrePagingLandScapeSceneManager.h"
 
33
#include "OgrePagingLandScapeTextureManager.h"
 
34
#include "OgrePagingLandScapeData2DManager.h"
 
35
#include "OgrePagingLandScapeData2D.h"
 
36
 
 
37
#include "fileutils.h"
 
38
 
 
39
namespace Ogre
 
40
{
 
41
    //-----------------------------------------------------------------------
 
42
    PagingLandScapeTexture::PagingLandScapeTexture(PagingLandScapeTextureManager *textureMgr, 
 
43
                                                                                                        const String materialBaseName,
 
44
                                                                                                    const unsigned int numTexture,
 
45
                                                                                                        const bool isSplatMode) :
 
46
        mParent(textureMgr),
 
47
                mMaterialBaseName(materialBaseName),
 
48
            mIsLoaded (false),
 
49
        mIsModified (false),
 
50
            mDataX (0),
 
51
            mDataZ (0),
 
52
        mPaintRect (0, 0, 0, 0, 0, 1),
 
53
        mIsPaintRectModified(false),
 
54
        mDeformRect (0, 0, 0, 0, 0, 1),
 
55
        mIsDeformRectModified(false),
 
56
        mIsSplatMode(isSplatMode),
 
57
                mNumTexture(numTexture),
 
58
                mIsShadowed(false),
 
59
                mIsShaderShadowed(false),
 
60
                mIsBaseMode(false)
 
61
    {
 
62
        mMaterial.setNull();
 
63
    }
 
64
    //-----------------------------------------------------------------------
 
65
        PagingLandScapeTexture::~PagingLandScapeTexture()
 
66
        {
 
67
                mNumChannelperTexture.clear();                  
 
68
                mImages.clear();
 
69
                mTextures.clear();
 
70
                mBuffers.clear();
 
71
                doTextureNeedUpdate.clear();
 
72
                isTextureModified.clear();
 
73
        }
 
74
        //-----------------------------------------------------------------------
 
75
        void PagingLandScapeTexture::setNumTexture()
 
76
        {
 
77
                if (mNumTexture > 0)
 
78
                {
 
79
                        mNumChannelperTexture.reserve(mNumTexture);     
 
80
                        doTextureNeedUpdate.reserve(mNumTexture);
 
81
                        isTextureModified.reserve(mNumTexture); 
 
82
                        mTextures.reserve(mNumTexture);
 
83
                        mBuffers.reserve(mNumTexture);
 
84
 
 
85
                        mImages.reserve(mNumTexture);
 
86
 
 
87
                        mNumChannelperTexture.resize(mNumTexture);      
 
88
                        doTextureNeedUpdate.resize(mNumTexture);
 
89
                        isTextureModified.resize(mNumTexture);
 
90
                        mTextures.resize(mNumTexture);
 
91
                        mBuffers.resize(mNumTexture);           
 
92
 
 
93
                        mImages.resize(mNumTexture);
 
94
 
 
95
                        for (size_t i = 0; i < mNumTexture; i++)
 
96
                        {
 
97
                                mImages[i].loadDynamicImage (0, 0, 0, 1, PF_R8G8B8A8, true, 1, 0);
 
98
                        }
 
99
 
 
100
                }
 
101
        }
 
102
    //-----------------------------------------------------------------------
 
103
    const String &PagingLandScapeTexture::getMaterialName()
 
104
    {
 
105
        return mMaterial->getName ();
 
106
    }
 
107
    //-----------------------------------------------------------------------
 
108
    void PagingLandScapeTexture::bindCompressionSettings()
 
109
        {
 
110
                const PagingLandScapeOptions * const opt = mParent->getOptions();
 
111
                
 
112
                Material::TechniqueIterator tIt = mMaterial->getTechniqueIterator ();
 
113
                while (tIt.hasMoreElements ())
 
114
                {
 
115
                        Technique * const t = tIt.getNext ();
 
116
                        Technique::PassIterator pIt = t->getPassIterator ();
 
117
                        while (pIt.hasMoreElements ())
 
118
                        {
 
119
                                Pass *p = pIt.getNext ();
 
120
                                if (p->hasVertexProgram ())
 
121
                                {
 
122
                                        // vertex compression setting
 
123
                                        GpuProgramParametersSharedPtr params = p->getVertexProgramParameters(); 
 
124
                                        if (opt->VertexCompression)
 
125
                                        {
 
126
                                                bindCompressionSettings (params);
 
127
                                                bindCompressionSettings (p->getShadowReceiverVertexProgramParameters ());
 
128
                                        }
 
129
 
 
130
                                        // splat settings.
 
131
#ifdef PLSM2_EIHORT
 
132
                                        GpuConstantDefinition const * const e = params->_findNamedConstantDefinition("splatSettings", false);
 
133
                                        if (e)
 
134
                                        {
 
135
                                                // use index to get RealConstantEntry
 
136
                                                params->_writeRawConstant(e->physicalIndex + 0, opt->matHeight[1]);
 
137
                                                params->_writeRawConstant(e->physicalIndex + 1, opt->matHeight[2]);
 
138
                                                params->_writeRawConstant(e->physicalIndex + 2, float(opt->maxValue));
 
139
                                                params->_writeRawConstant(e->physicalIndex + 3, 0.0f);                          
 
140
                                        }
 
141
#else
 
142
                                        GpuProgramParameters::RealConstantEntry * const e = params->getNamedRealConstantEntry ("splatSettings");
 
143
                                        if (e)
 
144
                                        {
 
145
                                                e->val[0] = static_cast <float> (opt->matHeight[1]);
 
146
                                                e->val[1] = static_cast <float> (opt->matHeight[2]); 
 
147
                                                e->val[2] = static_cast <float> (opt->maxValue); 
 
148
                                                e->val[3] = static_cast <float> (0.0);
 
149
                                                e->isSet = true;
 
150
                                        }
 
151
#endif
 
152
 
 
153
 
 
154
                                }
 
155
                        }
 
156
                }
 
157
        }
 
158
        //-----------------------------------------------------------------------
 
159
        void PagingLandScapeTexture::bindCompressionSettings(GpuProgramParametersSharedPtr params)
 
160
        {
 
161
                GpuProgramParameters::AutoConstantIterator aci = params->getAutoConstantIterator();
 
162
        bool found = false;
 
163
        while (aci.hasMoreElements())
 
164
        {
 
165
            const GpuProgramParameters::AutoConstantEntry& ace = aci.getNext();
 
166
            if (ace.paramType == GpuProgramParameters::ACT_CUSTOM && 
 
167
                ace.data == MORPH_CUSTOM_PARAM_ID)
 
168
            {
 
169
                found = true;
 
170
            }
 
171
        }
 
172
        if (!found)
 
173
        {                        
 
174
            params->setNamedAutoConstant("compressionSettings", 
 
175
                GpuProgramParameters::ACT_CUSTOM, MORPH_CUSTOM_PARAM_ID);                       
 
176
        }
 
177
    }
 
178
        //-----------------------------------------------------------------------
 
179
        void PagingLandScapeTexture::loadTexturesToModify()
 
180
        {
 
181
                if (mNumTexture > 0 || (mIsShadowed && !mIsShaderShadowed))
 
182
                {
 
183
                        const String nameSep(".");
 
184
                        const PagingLandScapeOptions * const opt = mParent->getOptions();
 
185
                        const String filename (opt->LandScape_filename);
 
186
                        const String commonName (StringConverter::toString(mDataZ) + 
 
187
                                                nameSep + StringConverter::toString(mDataX));
 
188
 
 
189
                        unsigned int channel = 0;
 
190
                        TextureManager* texMgr = TextureManager::getSingletonPtr();
 
191
 
 
192
                        const unsigned short numLodLevels = 
 
193
                                mMaterial->getNumLodLevels(MaterialManager::getSingleton()._getActiveSchemeIndex());
 
194
                        // some texture are shared between techniques, ensure it's loaded once.
 
195
                        bool imageLoaded = false;
 
196
                        bool baseLoaded = false;
 
197
                        bool coverageLoaded = false;
 
198
                        bool lightLoaded = false;
 
199
                        bool horizonLoaded = false;
 
200
 
 
201
                        for(unsigned short k = 0; k < numLodLevels; k++)
 
202
                        {
 
203
                                Technique *t = mMaterial->getBestTechnique (k);
 
204
                                Technique::PassIterator pIt = t->getPassIterator ();
 
205
                String texType;
 
206
                channel = 0;
 
207
                                while (pIt.hasMoreElements ())
 
208
                                {
 
209
                                        Pass *p = pIt.getNext ();
 
210
                                        Pass::TextureUnitStateIterator tuIt = p->getTextureUnitStateIterator ();
 
211
                                        while (tuIt.hasMoreElements ())
 
212
                                        {
 
213
                                                TextureUnitState *tu = tuIt.getNext ();
 
214
 
 
215
                                                const String texName (tu->getTextureName());
 
216
                                                if (!imageLoaded && opt->ImageNameLoad && 
 
217
                                                        StringUtil::startsWith (texName, opt->image_filename))
 
218
                                                {
 
219
                                                        // if it's an Image Texture mode
 
220
                                                        mTextures[channel] = texMgr->getByName (texName);
 
221
                                                        assert (!mTextures[channel].isNull() && 
 
222
                                                                String(texName + " is missing").c_str());
 
223
                                                        mBuffers[channel] = mTextures[channel]->getBuffer();
 
224
                                                        loadColorTexture (texName, channel);
 
225
                                                        channel++;
 
226
                                                        imageLoaded = true;
 
227
                                                }
 
228
                                                else if (StringUtil::startsWith (texName, filename, false))
 
229
                                                {
 
230
                                                        // if it's a dynamic texture updated by texture mode
 
231
                                                        // subtracts filename from texname 
 
232
                                                        String texNameInfo = texName.substr (filename.size ());
 
233
                                                        //then split on Dot (in case of filename with dot in it.)
 
234
                                                        const StringVector texNameInfos = 
 
235
                                                                StringUtil::split(texNameInfo, nameSep);
 
236
                                                        texType = texNameInfos[0];
 
237
 
 
238
                                                        if (texType == "Alpha")
 
239
                                                        {
 
240
                                                                mTextures[channel] = texMgr->getByName (texName);
 
241
                                                                assert (!mTextures[channel].isNull() && 
 
242
                                                                        String(texName + " is missing").c_str());
 
243
                                                                mBuffers[channel] = mTextures[channel]->getBuffer();
 
244
                                                                loadAlphaTexture (texName, channel);
 
245
                                                                channel++;
 
246
                                                        }
 
247
                                                        else if (texType == "Coverage")
 
248
                                                        {
 
249
                                                                mTextures[channel] = texMgr->getByName (texName);
 
250
                                                                assert (!mTextures[channel].isNull() && 
 
251
                                                                        String(texName + " is missing").c_str());
 
252
                                                                mBuffers[channel] = mTextures[channel]->getBuffer();
 
253
                                                                loadColorTexture (texName, channel);
 
254
                                                                coverageLoaded = true;
 
255
                                                                channel++;
 
256
                                                        }
 
257
                                                        else if (!lightLoaded && !mIsShaderShadowed 
 
258
                                                                && texType ==  "Light" )
 
259
                                                        {
 
260
                                                                mLightTexture = texMgr->getByName (texName);
 
261
                                                                assert (!mLightTexture.isNull() && 
 
262
                                                                        String(texName + " is missing").c_str());
 
263
                                                                mLightBuffer = mLightTexture->getBuffer();
 
264
                                                                loadTexture (texName, mLightImage);
 
265
 
 
266
                                                                assert (mLightBuffer->getWidth () ==  mLightImage.getWidth () && 
 
267
                                                                        mLightBuffer->getHeight () == mLightImage.getHeight ());
 
268
 
 
269
                                                                String shadowTexName (filename + nameSep + "HS");
 
270
                                                                for (size_t k = 1; k < texNameInfos.size(); k++)
 
271
                                                                        shadowTexName +=  nameSep + texNameInfos[k];
 
272
                                                                if (ResourceGroupManager::getSingleton().
 
273
                                                                        resourceExists (opt->groupName, shadowTexName))
 
274
                                                                {
 
275
                                                                        loadTexture (shadowTexName, mShadow);
 
276
                                                                        assert (mShadow.getWidth () ==  mLightImage.getWidth () && 
 
277
                                                                                mShadow.getHeight () == mLightImage.getHeight ());
 
278
                                                                        lightUpdate ();     
 
279
                                                                }
 
280
                                                                else
 
281
                                                                {
 
282
                                                                        mIsShadowed = false;
 
283
                                                                }
 
284
                                                                lightLoaded = true;
 
285
                                                        }
 
286
                                                        else if (!coverageLoaded && !baseLoaded && texType == "Base")
 
287
                                                        {
 
288
                                                                mTextures[channel] = texMgr->getByName (texName);
 
289
                                                                assert (!mTextures[channel].isNull() && 
 
290
                                                                        String(texName + " is missing").c_str());
 
291
                                                                mBuffers[channel] = mTextures[channel]->getBuffer();
 
292
                                                                loadColorTexture (texName, channel);
 
293
                                                                channel++;
 
294
                                                                baseLoaded = true;
 
295
                                                        }
 
296
                                                }
 
297
                                        }
 
298
                                }
 
299
                                for (unsigned int i = 0; i < mNumTexture; i++)
 
300
                                {
 
301
                                        mNumChannelperTexture[i] = mImages[i].getBPP () / 8;
 
302
                                        doTextureNeedUpdate[i] = false;
 
303
                                        isTextureModified[i] = false;
 
304
                                }
 
305
                        }
 
306
                }
 
307
        }
 
308
        //-----------------------------------------------------------------------
 
309
        void PagingLandScapeTexture::setOptions(void)
 
310
        {
 
311
                PagingLandScapeOptions * const opt  = mParent->getOptions();
 
312
                String matClassName ( 
 
313
                        (opt->VertexCompression ?
 
314
                        String(mMaterialBaseName + "Decompress")
 
315
                        :
 
316
                        mMaterialBaseName));
 
317
 
 
318
                MaterialPtr material = MaterialManager::getSingleton().getByName (matClassName);
 
319
                if (opt->VertexCompression && material.isNull())
 
320
                {
 
321
                        matClassName = mMaterialBaseName;
 
322
                        opt->VertexCompression = false;
 
323
                        opt->lodMorph = false;
 
324
                        material = MaterialManager::getSingleton().getByName (matClassName);
 
325
                }
 
326
                assert (!material.isNull() && 
 
327
                        String(matClassName + "Must exists in the" + opt->groupName + "group").c_str ());
 
328
                
 
329
                bool hasVertexProgram = false;
 
330
                bool hasFragmentProgram = false;
 
331
 
 
332
                Material::TechniqueIterator tIt = material->getTechniqueIterator ();
 
333
                while (tIt.hasMoreElements ())
 
334
                {
 
335
                        Technique * const t = tIt.getNext ();
 
336
                        Technique::PassIterator pIt = t->getPassIterator ();
 
337
                        while (pIt.hasMoreElements ())
 
338
                        {
 
339
                                Pass * const p = pIt.getNext ();
 
340
 
 
341
                                // vertex shaders.
 
342
                                if ( p->hasVertexProgram ())
 
343
                                {
 
344
                                        if (hasVertexProgram == false)
 
345
                                        {
 
346
                                                hasVertexProgram = p->hasVertexProgram ();
 
347
                                        }
 
348
                                        GpuProgramParametersSharedPtr params = p->getVertexProgramParameters(); 
 
349
 
 
350
#ifdef PLSM2_EIHORT
 
351
                    GpuConstantDefinition const * const e = params->_findNamedConstantDefinition("splatSettings");
 
352
#else
 
353
                                        GpuProgramParameters::RealConstantEntry * const e = params->getNamedRealConstantEntry ("splatSettings");
 
354
#endif
 
355
                                        if (e)
 
356
                                        {
 
357
                                                opt->normals = true;
 
358
                                        }
 
359
                                }               
 
360
 
 
361
                                // pixel shaders.
 
362
                                if (hasFragmentProgram == false)
 
363
                                {
 
364
                                        hasFragmentProgram = p->hasFragmentProgram ();  
 
365
                                }
 
366
                        }
 
367
                }
 
368
                if (!hasVertexProgram) 
 
369
                {
 
370
                        opt->VertexCompression = false;
 
371
                        opt->lodMorph = false;
 
372
                }
 
373
        }
 
374
        //-----------------------------------------------------------------------
 
375
    bool PagingLandScapeTexture::isMaterialSupported(bool recursive)
 
376
    {
 
377
                const PagingLandScapeOptions * const opt = mParent->getOptions();
 
378
 
 
379
                if (opt->VertexCompression && recursive)
 
380
                {
 
381
                        const String MatClassName (mMaterialBaseName);
 
382
                        mMaterialBaseName =  mMaterialBaseName + "Decompress";                  
 
383
                        const bool isOk = MaterialManager::getSingleton ().resourceExists (mMaterialBaseName) && 
 
384
                                        isMaterialSupported(false);
 
385
                        mMaterialBaseName = MatClassName;
 
386
                        if (isOk)
 
387
                                return true;
 
388
                }
 
389
 
 
390
                MaterialPtr material = MaterialManager::getSingleton().getByName (mMaterialBaseName);
 
391
                assert (!material.isNull() && 
 
392
                                        String(mMaterialBaseName + " Must exists in the" + opt->groupName + "group").c_str ());
 
393
 
 
394
                unsigned short numPasses = 0;
 
395
 
 
396
                //these will store the maximum number of texture units, alpha textures, 
 
397
                //coverage textures, etc. after iterating through all passes in the material
 
398
                size_t numTextureUnits = 0;
 
399
                size_t numAlphaTexture = 0;
 
400
                size_t numCoverageTexture = 0;
 
401
                size_t numSplats = 0;
 
402
                unsigned int numDynamicTexture = 0;
 
403
 
 
404
                //per pass count
 
405
                size_t passNumTextureUnits;
 
406
                size_t passNumAlphaTextures;
 
407
                size_t passNumCoverageTextures;
 
408
                size_t passNumSplats;
 
409
                unsigned int passNumDynamicTextures;
 
410
 
 
411
                bool needVertexProgram = false;
 
412
                bool needFragmentProgram = false;
 
413
                bool isImageMode = false;
 
414
                bool isSplatMode = false;
 
415
                bool isBaseMode = false;
 
416
                
 
417
                Material::TechniqueIterator tIt = material->getTechniqueIterator ();
 
418
                while (tIt.hasMoreElements ())
 
419
                {
 
420
                        Technique * const t = tIt.getNext ();
 
421
                        numPasses = std::max (numPasses, t->getNumPasses());
 
422
            Technique::PassIterator pIt = t->getPassIterator ();
 
423
                        while (pIt.hasMoreElements ())
 
424
                        {
 
425
 
 
426
                passNumTextureUnits = 0;
 
427
                passNumAlphaTextures = 0;
 
428
                passNumCoverageTextures = 0;
 
429
                passNumSplats = 0;
 
430
                passNumDynamicTextures = 0;
 
431
                Pass * const p = pIt.getNext ();
 
432
                                if (needVertexProgram == false)
 
433
                                        needVertexProgram = p->hasVertexProgram ();
 
434
                                if (needFragmentProgram == false)
 
435
                                        needFragmentProgram = p->hasFragmentProgram ();
 
436
#ifdef PLSM2_EIHORT
 
437
                numTextureUnits = std::max<unsigned int>(static_cast<unsigned int>(numTextureUnits), static_cast<unsigned int>(p->getNumTextureUnitStates()));
 
438
#else                   
 
439
                                numTextureUnits = std::max (numTextureUnits, p->getNumTextureUnitStates());
 
440
#endif
 
441
                                Pass::TextureUnitStateIterator tuIt = p->getTextureUnitStateIterator ();
 
442
                                while (tuIt.hasMoreElements ())
 
443
                                {
 
444
                                        TextureUnitState * const tu = tuIt.getNext ();
 
445
                                        const String texType (tu->getTextureName());
 
446
                                        if (std::string::npos == texType.find("."))
 
447
                                        {
 
448
                                                // This Texture Name is A keyword,
 
449
                                                // check how many are dynamic in this material
 
450
                        if (!isBaseMode && 
 
451
                            StringUtil::startsWith (texType, "base", true))
 
452
                                                {
 
453
                                                        isBaseMode = true;
 
454
                                                        passNumDynamicTextures++;
 
455
                                                }
 
456
                                                else if (!isImageMode && 
 
457
                            StringUtil::startsWith (texType, "image", true))
 
458
                                                {
 
459
                                                        isImageMode = true;
 
460
                                                        passNumDynamicTextures++;
 
461
                                                }
 
462
                        else if (texType == "Alpha" && 
 
463
                            StringUtil::startsWith (texType, "alpha", true))
 
464
                                                {
 
465
                                                        isSplatMode = true;
 
466
                                                        passNumAlphaTextures++;
 
467
                                                        passNumDynamicTextures++;
 
468
                                                }
 
469
                        else if (texType == "Coverage" && 
 
470
                            StringUtil::startsWith (texType, "coverage", true))
 
471
                                                {
 
472
                                                        isSplatMode = true;
 
473
                                                        passNumDynamicTextures++;
 
474
                                                        passNumCoverageTextures++;
 
475
                                                }
 
476
                        else if (texType == "Splatting" && 
 
477
                            StringUtil::startsWith (texType, "splatting", true))
 
478
                                                {
 
479
                                                        mIsSplatMode = true;
 
480
                                                        passNumSplats++;
 
481
                                                }
 
482
                        else if (texType == "Light" && 
 
483
                            StringUtil::startsWith (texType, "light", true))
 
484
                                                {
 
485
                                                        //dynamic light... but in software
 
486
                                                        mIsShadowed = true;
 
487
                                                }
 
488
                        else if (texType == "Horizon" && 
 
489
                            StringUtil::startsWith (texType, "horizon", true))
 
490
                                                {
 
491
                                                        //dynamic light...  but shader
 
492
                                                        mIsShaderShadowed = true;
 
493
                                                        mIsShadowed = true;
 
494
                                                }
 
495
                                        }
 
496
                                }
 
497
                                
 
498
                                if(passNumTextureUnits > numTextureUnits)
 
499
                                        numTextureUnits = passNumTextureUnits;
 
500
 
 
501
                                numAlphaTexture += passNumAlphaTextures;
 
502
                numCoverageTexture += passNumCoverageTextures;
 
503
                numSplats += passNumSplats;
 
504
                numDynamicTexture += passNumDynamicTextures;
 
505
 
 
506
                        }
 
507
                }
 
508
                if (isImageMode && !opt->ImageNameLoad)
 
509
                        return false;
 
510
                if (opt->numTextureUnits < numTextureUnits)
 
511
                        return false;        
 
512
                if (needVertexProgram && opt->hasVertexShader == false)
 
513
                        return false;
 
514
                if (needFragmentProgram && opt->hasFragmentShader == false)
 
515
                        return false;
 
516
 
 
517
                if (isSplatMode && numAlphaTexture && opt->NumMatHeightSplat < numAlphaTexture)
 
518
                        return false;
 
519
 
 
520
                // does all coverage must be 4 alpha ?
 
521
                //if (isSplatMode && numCoverageTexture && opt->NumMatHeightSplat < numCoverageTexture * 4)
 
522
                //      return false;
 
523
                if (isSplatMode && numCoverageTexture && opt->NumMatHeightSplat < 4)
 
524
                        return false;
 
525
 
 
526
                if (mIsShaderShadowed && !opt->hasFragmentShader2)
 
527
                        return false;
 
528
 
 
529
                mIsSplatMode = isSplatMode;
 
530
                mIsBaseMode = !mIsSplatMode && isBaseMode;
 
531
                mNumTexture = (mParent->getOptions()->textureModifiable)? numDynamicTexture : 0;
 
532
                return true;
 
533
        }
 
534
        //-----------------------------------------------------------------------
 
535
        void PagingLandScapeTexture::_loadMaterial()
 
536
        {
 
537
                if (mMaterial.isNull())
 
538
                {
 
539
                        const PagingLandScapeOptions * const opt = mParent->getOptions();
 
540
                        const String nameSep(".");
 
541
                        const String commonName (StringConverter::toString(mDataZ) + 
 
542
                                nameSep + StringConverter::toString(mDataX));
 
543
                        if (opt->materialPerPage)
 
544
                        {
 
545
                                // JEFF - all material settings configured through material script
 
546
                                mMaterial = MaterialManager::getSingleton().getByName(
 
547
                                        mMaterialBaseName + commonName);
 
548
                        }
 
549
                        else
 
550
                        {
 
551
                                const String filename (opt->LandScape_filename);
 
552
                                const bool compressed = opt->VertexCompression;
 
553
                                const String MatClassName ( 
 
554
                                        (compressed ?
 
555
                                                                String(mMaterialBaseName + "Decompress")
 
556
                                                                :
 
557
                                                                mMaterialBaseName));
 
558
                                const String matname (MatClassName + nameSep 
 
559
                                                                                + commonName + nameSep  
 
560
                                                                                + filename);
 
561
                                mMaterial = MaterialManager::getSingleton().getByName(matname);
 
562
                                if (mMaterial.isNull())
 
563
                                {                                       
 
564
                                        mMaterial = MaterialManager::getSingleton().getByName(MatClassName);
 
565
                                        assert (!mMaterial.isNull() && 
 
566
                                                        String(MatClassName + "Must exists in the" + opt->groupName + "group").c_str ());
 
567
                                        mMaterial = mMaterial->clone(matname);
 
568
                                        const String extName (opt->TextureExtension);
 
569
                                        const String beginName (filename + nameSep);
 
570
                                        const String endName (nameSep + commonName + 
 
571
                                                                                  nameSep);
 
572
                                        bool deformable;
 
573
                                        String texName, finalTexName;
 
574
                                        unsigned int channel = 0;
 
575
                                        unsigned int splat = 0;
 
576
 
 
577
                                        unsigned int alphachannel = 0;
 
578
                                        unsigned int coveragechannel = 0;
 
579
 
 
580
                                        Material::TechniqueIterator tIt = mMaterial->getTechniqueIterator ();
 
581
                                        while (tIt.hasMoreElements ())
 
582
                    {
 
583
                        splat = 0;
 
584
                        channel = 0;
 
585
                        coveragechannel = 0;
 
586
                        alphachannel = 0;
 
587
                                                Technique * const t = tIt.getNext ();
 
588
                                                Technique::PassIterator pIt = t->getPassIterator ();
 
589
                                                while (pIt.hasMoreElements ())
 
590
                                                {
 
591
                                                        Pass * const p = pIt.getNext ();
 
592
                                                        Pass::TextureUnitStateIterator tuIt = p->getTextureUnitStateIterator ();
 
593
                                                        while (tuIt.hasMoreElements ())
 
594
                                                        {
 
595
                                                                TextureUnitState * const tu = tuIt.getNext ();
 
596
                                                                const String texType (tu->getTextureName());
 
597
                                                                if (std::string::npos == texType.find("."))
 
598
                                                                {
 
599
                                                                        // This Texture Name is A keyword,
 
600
                                                                        // meaning we have to dynamically replace it
 
601
                                                                        deformable = false;
 
602
                                                                        // check by what texture to replace keyword
 
603
                                                                        if (StringUtil::startsWith (texType, "image", true))
 
604
                                                                        {
 
605
                                                                                texName = opt->image_filename + endName;
 
606
                                                                                deformable = true;
 
607
                                                                        }
 
608
                                                                        else if (StringUtil::startsWith (texType, "splatting", true))
 
609
                                                                        {
 
610
                                                                                texName = opt->SplatDetailMapNames[splat % opt->NumMatHeightSplat];
 
611
                                                                                splat++;
 
612
                                                                        }
 
613
                                                                        else if (StringUtil::startsWith (texType, "base", true))
 
614
                                                                        {
 
615
                                                                                texName = beginName + texType + endName;
 
616
                                                                                channel++;
 
617
                                                                                deformable = true;
 
618
                                                                        }
 
619
                                                                        else if (StringUtil::startsWith (texType, "alpha", true))
 
620
                                                                        {
 
621
                                                                                texName = beginName + texType + nameSep + 
 
622
                                                                                        StringConverter::toString(alphachannel) + endName;
 
623
                                                                                deformable = true;
 
624
                                                                                alphachannel++;
 
625
                                                                                channel++;
 
626
                                                                        }
 
627
                                                                        else if (StringUtil::startsWith (texType, "coverage", true))
 
628
                                                                        {
 
629
                                                                                texName = beginName + texType + nameSep + 
 
630
                                                                                        StringConverter::toString((coveragechannel * 4)  % opt->NumMatHeightSplat) + endName;
 
631
                                                                                deformable = true;
 
632
                                                                                channel++;
 
633
                                                                                coveragechannel++;
 
634
                                                                        }
 
635
                                                                        else if (StringUtil::startsWith (texType, "light", true))
 
636
                                                                        {
 
637
                                                                                texName = beginName +  texType + endName + extName;                                                                             
 
638
                                                                        }
 
639
                                                                        else if (StringUtil::startsWith (texType, "horizon", true))
 
640
                                                                        {
 
641
                                                                                texName = beginName +  "HSP" + endName + extName;
 
642
                                                                                mPositiveShadow = true;                   
 
643
                                                                        }
 
644
                                                                        if (deformable)
 
645
                                                                        {
 
646
                                                                                if(opt->Deformable &&
 
647
                                                                                        ResourceGroupManager::getSingleton().resourceExists(
 
648
                                                                                                        opt->groupName, 
 
649
                                                                                                        texName + "modif." + extName))
 
650
                                                                                {
 
651
                                                                                        finalTexName = texName + "modif." + extName;             
 
652
                                                                                }
 
653
                                                                                else
 
654
                                                                                {
 
655
                                                                                        finalTexName = texName + extName;
 
656
                                                                                }
 
657
                                                                        }
 
658
                                                                        else
 
659
                                                                        {
 
660
                                                                                finalTexName = texName;
 
661
                                                                        }
 
662
                                                                        tu->setTextureName (finalTexName);
 
663
                                                                }
 
664
                                                        }
 
665
                                                }
 
666
                                        }
 
667
                                }
 
668
                        }
 
669
                }
 
670
        }
 
671
        //-----------------------------------------------------------------------
 
672
        void PagingLandScapeTexture::_unloadMaterial()
 
673
        {
 
674
 
 
675
 
 
676
        }
 
677
    //-----------------------------------------------------------------------
 
678
    void PagingLandScapeTexture::load(unsigned int x, unsigned int z)
 
679
    {
 
680
        if (!mIsLoaded && isMaterialSupported())
 
681
                {
 
682
                mDataX = x;
 
683
                        mDataZ = z;
 
684
                        updated();
 
685
                        setNumTexture ();
 
686
                _loadMaterial();
 
687
                        const PagingLandScapeOptions * const opt = mParent->getOptions();
 
688
                        mMaterial->setLightingEnabled (opt->lit);
 
689
                        mMaterial->setLodLevels (opt->lodMaterialDistanceList);
 
690
                        mMaterial->setReceiveShadows (true);
 
691
                        // If vertex shader, have to bind parameters
 
692
                        bindCompressionSettings ();
 
693
                        mMaterial->load ();
 
694
                        // load texture in main memory if we want to update it Real-Time
 
695
                        loadTexturesToModify();
 
696
 
 
697
                mIsLoaded = true;
 
698
            mIsModified = false; 
 
699
        }
 
700
    }
 
701
    //-----------------------------------------------------------------------
 
702
        void PagingLandScapeTexture::unload()
 
703
        {
 
704
        if (mIsLoaded)
 
705
        {
 
706
            if (mIsModified && mParent->getOptions()->saveDeformation)
 
707
                _save();
 
708
 
 
709
                        if (!mMaterial.isNull())
 
710
                                mMaterial->unload();
 
711
 
 
712
                        for (unsigned int i = 0; i < mNumTexture; i++)
 
713
                        {
 
714
                                doTextureNeedUpdate[i] = false;
 
715
                                isTextureModified[i] = false;
 
716
                                mBuffers[i].setNull ();
 
717
                                mTextures[i].setNull ();
 
718
                                mImages[i].loadDynamicImage (0, 0, 0, 1, PF_R8G8B8A8, true, 1, 0);
 
719
                        } 
 
720
                        // Anyway, they're surely null already, as they're freed by delete page()
 
721
                        
 
722
                _unloadMaterial();
 
723
 
 
724
                        const String resourceName (mMaterial->getName ());
 
725
 
 
726
            assert (!mMaterial.isNull() && "PagingLandScapeTexture::unload");      
 
727
                        mMaterial->unload();
 
728
                        mMaterial.setNull();
 
729
                        ///ember change start
 
730
                        ///don't remove from the manager, since it's tricky to add it again it later on
 
731
//                      MaterialManager::getSingleton().remove (resourceName);
 
732
                        ///ember change stop
 
733
                        
 
734
                mIsLoaded = false;
 
735
        }
 
736
 
 
737
        }
 
738
        //-----------------------------------------------------------------------
 
739
        void PagingLandScapeTexture::_save(void)
 
740
        {
 
741
                assert (!mMaterial.isNull() && "PagingLandScapeTexture::::_save");  
 
742
                
 
743
                const PagingLandScapeOptions * const opt = mParent->getOptions();
 
744
                if (mNumTexture > 0 && opt->textureModifiable)
 
745
                {
 
746
                        const String extname (opt->TextureExtension);
 
747
                        for (unsigned int i = 0; i < mNumTexture; i++)
 
748
                        {
 
749
                                if (isTextureModified[i])
 
750
                                {
 
751
                                        String texName = mTextures[i]->getName ();
 
752
 
 
753
                                        FileInfoListPtr finfo =  ResourceGroupManager::getSingleton().findResourceFileInfo (
 
754
                                                                                                        opt->groupName, texName);
 
755
                                        FileInfoList::iterator it = finfo->begin();
 
756
                                        if (it != finfo->end())
 
757
                                        {
 
758
                                                char *olddir = ChangeToDir (const_cast< char * > (((it)->archive->getName()).c_str()));
 
759
                                                        //FileSystemArchive::pushDirectory()
 
760
 
 
761
                                                assert (mImages[i].getData ());
 
762
                                                // check if we have to add modif to the name.
 
763
                                                const String baseTexName (texName, 0, texName.size () - extname.size());
 
764
                                                if (!StringUtil::endsWith (baseTexName, "modif."))
 
765
                                                {
 
766
                                                        texName = baseTexName + "modif." + extname; 
 
767
                                                }
 
768
                                                mImages[i].save (texName); 
 
769
 
 
770
                                                RetablishDir (olddir);
 
771
                                                        //FileSystemArchive::popDirectory();
 
772
 
 
773
                                        } // if (it != finfo->end())
 
774
                                } // if (doTextureNeedUpdate[i])
 
775
                        } // for (unsigned int i = 0; i < mNumTexture; i++)       
 
776
                }
 
777
        }
 
778
        //-----------------------------------------------------------------------
 
779
        void PagingLandScapeTexture::upload(const Image::Box& textureRect)
 
780
        {    
 
781
                assert (mNumTexture > 0);
 
782
                assert (!mMaterial.isNull() && "PagingLandScapeTexture::update()");
 
783
 
 
784
                for (unsigned int i = 0; i < mNumTexture; i++)
 
785
                {
 
786
                        if (doTextureNeedUpdate[i])
 
787
                        {
 
788
                                assert (!mTextures[i].isNull() && "PagingLandScapeTexture::update()");
 
789
                                assert (!mBuffers[i].isNull() && "PagingLandScapeTexture::update()");
 
790
                                assert (mImages[i].getData () != 0 && "PagingLandScapeTexture::update()");
 
791
 
 
792
                                const PixelBox srcBox = mImages[i].getPixelBox().getSubVolume(textureRect);     
 
793
                                const PixelBox lock = mBuffers[i]->lock(textureRect, HardwareBuffer::HBL_DISCARD); 
 
794
                                PixelUtil::bulkPixelConversion(srcBox, lock); 
 
795
                                mBuffers[i]->unlock();          
 
796
 
 
797
                                doTextureNeedUpdate[i] = false;
 
798
                                isTextureModified[i] = true;
 
799
 
 
800
                                //#define _Missed_Spot 
 
801
 
 
802
                                #ifdef _Missed_Spot                
 
803
                                        // debug can help finding missed spot.
 
804
                                        const PixelBox srcSpotBox = mImages[i].getPixelBox();   
 
805
                                        const unsigned int textureSize = (mParent->getOptions()->PageSize - 1) *
 
806
                                                mParent->getOptions()->TextureStretchFactor;
 
807
                                        const Image::Box rect (0, 0, 0, textureSize, textureSize, 1);
 
808
                                        const PixelBox lockSpot = mBuffers[i]->lock (rect ,HardwareBuffer::HBL_DISCARD); 
 
809
                                        PixelUtil::bulkPixelConversion(srcSpotBox, lockSpot); 
 
810
                                        mBuffers[i]->unlock();
 
811
                                #endif //_Missed_Spot   
 
812
                        }
 
813
                }        
 
814
        }
 
815
    //-----------------------------------------------------------------------
 
816
    bool PagingLandScapeTexture::isLoaded() const
 
817
    {
 
818
            return mIsLoaded;
 
819
    }
 
820
    //-----------------------------------------------------------------------
 
821
    const MaterialPtr&  PagingLandScapeTexture::getMaterial() const
 
822
    {
 
823
            return mMaterial;
 
824
        }
 
825
        //-----------------------------------------------------------------------
 
826
        void PagingLandScapeTexture::loadAlphaTexture(const String &filename, const unsigned int channel)
 
827
        {       
 
828
                assert (mNumTexture > 0);
 
829
                if (mImages[channel].getData () == 0)
 
830
                {                       
 
831
                        Image Imageloader;
 
832
                        Imageloader.load(filename, mParent->getOptions()->groupName);
 
833
                        const size_t size = Imageloader.getSize();
 
834
                        uchar *data = new uchar [size];
 
835
                        memcpy (data, Imageloader.getData(), size*sizeof(uchar));
 
836
                        mImages[channel].loadDynamicImage(data, 
 
837
                                Imageloader.getWidth(), Imageloader.getHeight(), 
 
838
                                1,  PF_A8, true, 1, 0); 
 
839
                }
 
840
                
 
841
                assert (mImages[channel].getHeight() == mImages[channel].getWidth());
 
842
                assert (mImages[channel].getHeight() / (mParent->getOptions()->PageSize - 1)
 
843
                        == mParent->getOptions()->TextureStretchFactor && 
 
844
                        String("(texture size / (pagesize-1)) and texture stretch factor defined in terrain config file doesn't fit.").c_str());
 
845
        }
 
846
        //-----------------------------------------------------------------------
 
847
        void PagingLandScapeTexture::loadColorTexture(const String &filename, const unsigned int channel)
 
848
        {  
 
849
                assert (mNumTexture > 0);               
 
850
 
 
851
                loadTexture (filename, mImages[channel]);
 
852
 
 
853
                assert (mImages[channel].getHeight() == mImages[channel].getWidth());
 
854
                assert (mImages[channel].getHeight() / (mParent->getOptions()->PageSize - 1)
 
855
                        == mParent->getOptions()->TextureStretchFactor && 
 
856
                        String("(texture size / (pagesize-1)) and texture stretch factor defined in terrain config file doesn't fit.").c_str());
 
857
        }
 
858
        //-----------------------------------------------------------------------
 
859
        void PagingLandScapeTexture::loadTexture(const String &filename, Image &img)
 
860
        {  
 
861
                if (img.getData () == 0)
 
862
                {
 
863
                        img.load(filename, mParent->getOptions()->groupName);   
 
864
                }
 
865
        }
 
866
    //-----------------------------------------------------------------------
 
867
    void PagingLandScapeTexture::updated ()
 
868
    {
 
869
        mPaintRect.left = 0;
 
870
        mPaintRect.right = 0;
 
871
        mPaintRect.top = 0;
 
872
        mPaintRect.bottom = 0;
 
873
        mIsPaintRectModified = false;
 
874
 
 
875
        mDeformRect.left = 0;
 
876
        mDeformRect.right = 0;
 
877
        mDeformRect.top = 0;
 
878
        mDeformRect.bottom = 0;
 
879
        mIsDeformRectModified = false;
 
880
    }
 
881
    //-----------------------------------------------------------------------
 
882
    void PagingLandScapeTexture::compute(
 
883
                PagingLandScapeData2D* data, 
 
884
        const Image::Box& dataRect,
 
885
        const Image::Box& textureRect)
 
886
    {
 
887
                assert (mNumTexture > 0);
 
888
        const size_t heightfiledsize = mParent->getOptions()->PageSize - 1;
 
889
        const Real textureScale = mParent->getOptions()->TextureStretchFactor;
 
890
        const unsigned int textureSize = static_cast<unsigned int>(heightfiledsize * textureScale);
 
891
        unsigned int curr_image_pos = static_cast <unsigned int>(textureRect.top*textureSize + textureRect.left);
 
892
        const unsigned int image_width = static_cast <unsigned int>((textureSize - (textureRect.right - textureRect.left)));
 
893
        const Real inv_scale = 1 / textureScale;
 
894
 
 
895
        const Real * const ogre_restrict heightData = data->getHeightData ();
 
896
        assert (heightData && "PagingLandScapeTexture::compute()");
 
897
 
 
898
        for (size_t k = textureRect.top; k < textureRect.bottom; ++k)
 
899
        {
 
900
            const unsigned int k_terrain = (unsigned int)(k * inv_scale);
 
901
            const size_t curr_row = k_terrain * heightfiledsize;
 
902
            for (size_t i = textureRect.left; i < textureRect.right; ++i)
 
903
            {             
 
904
                const unsigned int i_terrain = (unsigned int)(i * inv_scale);
 
905
 
 
906
                assert (i < textureSize && k < textureSize && 
 
907
                    "PagingLandScapeTexture::compute()");
 
908
 
 
909
                assert (i_terrain < heightfiledsize && k_terrain < heightfiledsize && 
 
910
                    "PagingLandScapeTexture::compute()");
 
911
 
 
912
                                if (mIsSplatMode)
 
913
                                        computePointAlpha(curr_image_pos,
 
914
                            heightData[i_terrain + curr_row], 
 
915
                            1.0f - data->getNormal (i_terrain, k_terrain).y);
 
916
                                if (mIsBaseMode)
 
917
                                        computePointColor (curr_image_pos,
 
918
                                                        heightData[i_terrain + curr_row], 
 
919
                                                        1.0f - data->getNormal (i_terrain, k_terrain).y);
 
920
 
 
921
                curr_image_pos += 1;
 
922
            }
 
923
            curr_image_pos += image_width;
 
924
        }  
 
925
    }
 
926
    //-----------------------------------------------------------------------
 
927
    void PagingLandScapeTexture::paint (const unsigned int xParam, 
 
928
                                                                                const unsigned int zParam, 
 
929
                                                                                const Real paintForce)
 
930
        {
 
931
                assert (mNumTexture > 0);
 
932
                assert (paintForce >= 0.0f && paintForce <= 1.0f && "PagingLandScapeTexture::paint()");
 
933
                const Real blend = paintForce;
 
934
 
 
935
        const size_t psize = mParent->getOptions()->PageSize - 1;       
 
936
        const Real textureScale = mParent->getOptions ()->TextureStretchFactor;        
 
937
        const unsigned int textureScaleCount = static_cast <unsigned int> (textureScale);
 
938
 
 
939
        assert (((xParam + zParam *  psize) < psize*psize) && "PagingLandScapeTexture::paint()");
 
940
 
 
941
        const unsigned int xScaled = xParam * textureScaleCount;
 
942
        const unsigned int zScaled = zParam * textureScaleCount;
 
943
        const size_t pSizeScaled = psize * textureScaleCount;
 
944
 
 
945
        for (unsigned int j = 0; j < textureScaleCount; j++)
 
946
        {
 
947
                        const unsigned int z = zScaled + j;
 
948
                        if (z < pSizeScaled)
 
949
                        {
 
950
                                const unsigned int zShift = z * pSizeScaled;
 
951
                                for (unsigned int k = 0; k < textureScaleCount; k++)
 
952
                                {
 
953
                                        const unsigned int x = xScaled + k;
 
954
                                        if (x < pSizeScaled)
 
955
                                        {
 
956
                                                const unsigned int curr_image_pos = x + zShift;
 
957
                                                assert (curr_image_pos < pSizeScaled*pSizeScaled);
 
958
                                                paintPoint (curr_image_pos, blend);
 
959
                                                adjustPaintRectangle (x, z); 
 
960
                                        }
 
961
                                }
 
962
                        }
 
963
        }
 
964
    }
 
965
    //-----------------------------------------------------------------------
 
966
    void PagingLandScapeTexture::update()
 
967
    {       
 
968
                assert (mNumTexture > 0);
 
969
        // at least deformed once, so need to save texture if asked by user (option)
 
970
        mIsModified = true; 
 
971
 
 
972
        Image::Box dataRect (0, 0, 0, 0, 0, 1);
 
973
        Image::Box texturerect (0, 0, 0, 0, 0, 1);
 
974
 
 
975
        // computes deformation
 
976
        PagingLandScapeData2D *data = 0;
 
977
        if (mIsDeformRectModified)
 
978
        {
 
979
                        dataRect = mDeformRect;
 
980
                        data = mParent->getSceneManager()->getData2DManager()->getData2D(mDataX, mDataZ);
 
981
 
 
982
            if (dataRect.getWidth() && dataRect.getHeight ())
 
983
            {
 
984
 
 
985
                const Real textureScale = mParent->getOptions()->TextureStretchFactor;
 
986
 
 
987
                texturerect.left = static_cast<size_t>(dataRect.left * textureScale);
 
988
                texturerect.top  = static_cast<size_t>(dataRect.top * textureScale);
 
989
                texturerect.right = static_cast<size_t>(dataRect.right * textureScale + 1);
 
990
                texturerect.bottom = static_cast<size_t>(dataRect.bottom * textureScale + 1);
 
991
 
 
992
                dataRect.right += 1;
 
993
                dataRect.bottom += 1;
 
994
                compute(data, dataRect, texturerect);
 
995
            }
 
996
        }
 
997
        // try to upload only the smallest rectangle containing modification
 
998
        if (mIsPaintRectModified)
 
999
        {
 
1000
            if (mIsDeformRectModified)
 
1001
            {
 
1002
                texturerect.left = std::min (mPaintRect.left, dataRect.left);
 
1003
                texturerect.right = std::max (mPaintRect.right, dataRect.right);
 
1004
                texturerect.top =  std::min (mPaintRect.top, dataRect.top);
 
1005
                texturerect.bottom = std::max (mPaintRect.bottom, dataRect.bottom);
 
1006
            } 
 
1007
            else
 
1008
            {
 
1009
                texturerect = mPaintRect;
 
1010
 
 
1011
                texturerect.right += 1;
 
1012
                texturerect.bottom += 1;
 
1013
            }
 
1014
        } // if (mIsRectModified)
 
1015
 
 
1016
 
 
1017
        // Upload any changes (deformation or)
 
1018
        if (texturerect.getWidth() && texturerect.getHeight ())
 
1019
        {
 
1020
            upload (texturerect);           
 
1021
        } // if (texturerect.getWidth() && texturerect.getHeight ())
 
1022
 
 
1023
        if (mIsDeformRectModified)
 
1024
            data->resetDeformationRectangle ();
 
1025
        PagingLandScapeTexture::updated ();
 
1026
    }
 
1027
    
 
1028
    //-----------------------------------------------------------------------
 
1029
    bool PagingLandScapeTexture::needUpdate () const
 
1030
    {
 
1031
        return mIsDeformRectModified || mIsPaintRectModified;
 
1032
    } 
 
1033
    //-----------------------------------------------------------------------
 
1034
        void PagingLandScapeTexture::adjustDeformationRectangle(unsigned int x, unsigned int z)
 
1035
    {
 
1036
                assert (mNumTexture > 0);
 
1037
        assert (x < (mParent->getOptions ()->PageSize));
 
1038
        assert (z < (mParent->getOptions ()->PageSize));
 
1039
 
 
1040
        if (mIsDeformRectModified)
 
1041
        {
 
1042
            if (mDeformRect.left > x)
 
1043
                mDeformRect.left = x;
 
1044
            if (mDeformRect.right < x)
 
1045
                mDeformRect.right = x;
 
1046
 
 
1047
            if (mDeformRect.top > z)
 
1048
                mDeformRect.top = z;
 
1049
            if (mDeformRect.bottom < z)
 
1050
                mDeformRect.bottom = z;
 
1051
        }
 
1052
        else
 
1053
        {
 
1054
            // first modification :
 
1055
            // deformation rectangle is the point
 
1056
            mDeformRect.left    = x;
 
1057
            mDeformRect.right   = x;
 
1058
            mDeformRect.top     = z;
 
1059
            mDeformRect.bottom  = z;
 
1060
            mIsDeformRectModified = true;
 
1061
        }
 
1062
    } 
 
1063
    //-----------------------------------------------------------------------
 
1064
        void PagingLandScapeTexture::adjustPaintRectangle(unsigned int x, unsigned int z)
 
1065
    {
 
1066
                assert (mNumTexture > 0);
 
1067
        assert (x < ((mParent->getOptions ()->PageSize - 1) * mParent->getOptions ()->TextureStretchFactor));
 
1068
        assert (z < ((mParent->getOptions ()->PageSize - 1) * mParent->getOptions ()->TextureStretchFactor));
 
1069
        
 
1070
        if (mIsPaintRectModified)
 
1071
        {
 
1072
            if (mPaintRect.left > x)
 
1073
                mPaintRect.left = x;
 
1074
            else if (mPaintRect.right < x)
 
1075
                mPaintRect.right = x;
 
1076
 
 
1077
            if (mPaintRect.top > z)
 
1078
                mPaintRect.top = z;
 
1079
            else if (mPaintRect.bottom < z)
 
1080
                mPaintRect.bottom = z;
 
1081
        }
 
1082
        else
 
1083
        {
 
1084
            // first modification :
 
1085
            // deformation rectangle is the point
 
1086
            mPaintRect.left = x;
 
1087
            mPaintRect.right = x;
 
1088
            mPaintRect.top = z;
 
1089
            mPaintRect.bottom = z;
 
1090
            mIsPaintRectModified = true;
 
1091
        }
 
1092
        }
 
1093
        //-----------------------------------------------------------------------
 
1094
        void PagingLandScapeTexture::lightUpdate()
 
1095
        {               
 
1096
                PagingLandScapeOptions * const opt = mParent->getOptions();
 
1097
                if (mIsShaderShadowed)
 
1098
                {
 
1099
                        const Real SunAngle = opt->SunAngle;
 
1100
                        const Vector3 SunDir = opt->Sun;
 
1101
 
 
1102
                        const bool positiveHorizon =  (SunDir.y > 0);// Sun is west (true), east (false);
 
1103
                        assert (fabs (SunAngle) < 1.1f);
 
1104
 
 
1105
                        const Real LightAngle =  (positiveHorizon)? SunAngle  : -SunAngle;
 
1106
                        if (positiveHorizon != mPositiveShadow)
 
1107
                        {
 
1108
                                const String texname  (opt->LandScape_filename
 
1109
                                        +
 
1110
                                        ((positiveHorizon)? String(".HSP.") : String(".HSN."))
 
1111
                                        +
 
1112
                                        StringConverter::toString(mDataZ) + 
 
1113
                                        String(".") +
 
1114
                                        StringConverter::toString(mDataX) +  "." + 
 
1115
                                        opt->TextureExtension); 
 
1116
                                mMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(2)->setTextureName (texname);                
 
1117
                                mPositiveShadow = positiveHorizon;
 
1118
                        }
 
1119
                        GpuProgramParametersSharedPtr params = mMaterial->getBestTechnique()->getPass(0)->getFragmentProgramParameters();   
 
1120
#ifdef PLSM2_EIHORT
 
1121
            params->setNamedConstant("HorizonSettings", Vector4(SunDir.x, SunDir.y, SunDir.z, LightAngle));
 
1122
#else
 
1123
                        GpuProgramParameters::RealConstantEntry * const e = params->getNamedRealConstantEntry ("HorizonSettings");
 
1124
                        assert (e);
 
1125
                        e->val[0] = static_cast <float> (SunDir.x);
 
1126
                        e->val[1] = static_cast <float> (SunDir.y); 
 
1127
                        e->val[2] = static_cast <float> (SunDir.z); 
 
1128
                        e->val[3] = static_cast <float> (LightAngle);
 
1129
                        e->isSet = true;
 
1130
#endif
 
1131
                }
 
1132
                else if (mIsShadowed)
 
1133
                {
 
1134
                        assert (mLightImage.getData ());
 
1135
                        computeLightMap ();
 
1136
 
 
1137
                        // Upload changes         
 
1138
                        const PixelBox srcBox = mLightImage.getPixelBox();      
 
1139
                        const unsigned int mTextureSize = static_cast<unsigned int>(mParent->mPageSize * opt->TextureStretchFactor);
 
1140
                        const Image::Box rect (0, 0, 0, mTextureSize, mTextureSize, 1);
 
1141
                        const PixelBox lock = mLightBuffer->lock (rect , HardwareBuffer::HBL_DISCARD); 
 
1142
                        PixelUtil::bulkPixelConversion(srcBox, lock); 
 
1143
                        mLightBuffer->unlock();
 
1144
                }
 
1145
        }
 
1146
        //-----------------------------------------------------------------------
 
1147
        void PagingLandScapeTexture::computeLightMap () const
 
1148
        {    
 
1149
                assert(mIsShadowed);
 
1150
                PagingLandScapeOptions * const opt = mParent->getOptions();
 
1151
                const Vector3 LightDir = opt->Sun;
 
1152
                const Real SunAngle = opt->SunAngle;
 
1153
 
 
1154
                const bool positiveHorizon =  (LightDir.y > 0);// Sun is west (true), east (false);
 
1155
                assert (fabs (SunAngle) < 1.1f);
 
1156
 
 
1157
                const Real LightAngle =  (positiveHorizon)? SunAngle  : -SunAngle;       
 
1158
                const size_t offsetneg = (positiveHorizon)? 0: 1;
 
1159
                //const Real LightAngle = SunAngle;
 
1160
 
 
1161
 
 
1162
                unsigned int curr_rowY = 0;
 
1163
                const uchar BScale = 255;
 
1164
                const Real uchardivider = 1.0f / BScale;
 
1165
                unsigned int curr_image_pos = 0;
 
1166
                uchar * const ogre_restrict lightmap = (uchar *) (mLightImage.getData ());
 
1167
                const uchar * const ogre_restrict HorizonAngle = mShadow.getData(); 
 
1168
 
 
1169
                const unsigned int mTextureSize = (unsigned int) mLightImage.getWidth ();
 
1170
                assert ((mShadow.getBPP ()) / 8 == 3);
 
1171
                const unsigned int rowpitch = mTextureSize*3;
 
1172
                for(unsigned int nZ = 0; nZ < mTextureSize ; nZ++) 
 
1173
                {
 
1174
                        unsigned int curr_image_posX = 0;
 
1175
                        for(unsigned int nX = 0; nX < mTextureSize; nX++)
 
1176
                        {            
 
1177
                                const unsigned int nVert = static_cast <unsigned int> (curr_rowY + curr_image_posX  + offsetneg);
 
1178
                                const Real hAngle = HorizonAngle[nVert] * uchardivider;
 
1179
                                if (hAngle < LightAngle) 
 
1180
                                {           
 
1181
                                        const Real intensity =  1 - (LightAngle - hAngle);
 
1182
                                        if (intensity > 0.0f) 
 
1183
                                        {                       
 
1184
                                                //intensity *= std::max(LightDir.dotProduct (data->getNormal (nX, nZ)), 0.0f);
 
1185
                                                lightmap[curr_image_pos] = static_cast <uchar> (intensity * BScale);
 
1186
 
 
1187
                                        }
 
1188
                                        else
 
1189
                                        {
 
1190
                                                // totally in shadow    
 
1191
                                                lightmap[curr_image_pos] = 0;    
 
1192
                                        }
 
1193
                                }
 
1194
                                else             
 
1195
                                {
 
1196
                                        // if Vertex is lighted
 
1197
                                        const Real intensity = BScale;           
 
1198
                                        //const Real intensity = BScale * std::min(1.0f, LightDir.dotProduct (data->getNormal (nX, nZ))); 
 
1199
                                        lightmap[curr_image_pos] = static_cast <uchar> (intensity);
 
1200
                                }               
 
1201
                                // if colored light should use a rgb map..
 
1202
 
 
1203
                                curr_image_pos ++;
 
1204
                                curr_image_posX += 3;
 
1205
                        }
 
1206
                        curr_rowY += rowpitch;
 
1207
                }    
 
1208
 
 
1209
        }
 
1210
        //-----------------------------------------------------------------------
 
1211
        void PagingLandScapeTexture::computePointAlpha(
 
1212
                const unsigned int imagePos,
 
1213
                const Real height, 
 
1214
                const Real slope)
 
1215
        {
 
1216
                assert (mNumTexture > 0);
 
1217
                const unsigned int numHeights = mParent->getOptions()->NumMatHeightSplat;
 
1218
                unsigned int indx = 1;
 
1219
                while (indx < (numHeights - 1) && height >= mParent->heights[indx])
 
1220
                        indx++;                                
 
1221
 
 
1222
                const unsigned int bScale = 255;
 
1223
                const unsigned int up_indx = indx;
 
1224
                const unsigned int down_indx = indx - 1;
 
1225
                const Real interpol = (height  - mParent->heights[down_indx]) 
 
1226
                        * mParent->dividers[up_indx];  
 
1227
 
 
1228
                std::vector<Real> alpha;   
 
1229
                alpha.reserve(numHeights);
 
1230
                alpha.resize(numHeights);
 
1231
                for (unsigned int ialpha = 0; ialpha < numHeights; ialpha++) 
 
1232
                {    
 
1233
                        alpha[ialpha] = 0.0f;
 
1234
                }
 
1235
 
 
1236
                if (slope < 0.05f)// speed-up as it's invisible
 
1237
                {
 
1238
                        const Real B = (1.0f - interpol);
 
1239
                        const Real C = interpol;
 
1240
 
 
1241
                        alpha[indx - 1] = B;
 
1242
                        alpha[indx] = C; 
 
1243
                }
 
1244
                else 
 
1245
                {
 
1246
                        const Real A = (1.0f - slope);
 
1247
                        const Real B = A * (1.0f - interpol);
 
1248
                        const Real C = A * interpol;
 
1249
                        const Real D = slope;
 
1250
 
 
1251
                        alpha[indx - 1] = B;
 
1252
                        alpha[indx] = C; 
 
1253
 
 
1254
                        alpha[ 2 ] = alpha[ 2 ] + slope;
 
1255
                        alpha[ 2 ] = alpha[ 2 ] > 1.0f ? 1.0f : alpha[ 2 ];
 
1256
                }
 
1257
                // save changes in textures
 
1258
 
 
1259
                unsigned int currChannel = 0;
 
1260
                for (unsigned int k = 0; k < mNumTexture; k++) 
 
1261
                {    
 
1262
                        if (mImages[k].getBPP () == 8)
 
1263
                        {
 
1264
                                uchar * const BaseData = mImages[k].getData ();
 
1265
                                assert (BaseData && "PagingLandScapeTexture::computePointAlpha()");
 
1266
                                const unsigned int curr_image_pos = imagePos*(static_cast <unsigned int>(mNumChannelperTexture[k]));
 
1267
                                assert (mNumChannelperTexture[k] == (mImages[k].getBPP ()/8));
 
1268
                                for (unsigned int j = 0; j < mNumChannelperTexture[k]; j++) 
 
1269
                                {  
 
1270
                                        BaseData[ curr_image_pos + j] = static_cast <uchar> (alpha[currChannel]*bScale);
 
1271
 
 
1272
                                        currChannel++;
 
1273
                                }
 
1274
                        }
 
1275
                }
 
1276
        }
 
1277
        //-----------------------------------------------------------------------
 
1278
        void PagingLandScapeTexture::computePointColor(
 
1279
                const unsigned int imagePos,
 
1280
                const Real height, 
 
1281
                const Real slope)
 
1282
        {
 
1283
                assert (mNumTexture > 0);
 
1284
                const unsigned int numHeights = mParent->getOptions()->NumMatHeightSplat;
 
1285
                
 
1286
                unsigned int indx = 1;
 
1287
                while (indx < (numHeights - 1) && height >= mParent->heights[indx])
 
1288
                        indx++;                                
 
1289
 
 
1290
                const unsigned int bScale = 255;
 
1291
                const unsigned int up_indx = indx;
 
1292
                const unsigned int down_indx = indx - 1;
 
1293
                const Real interpol = (height  - mParent->heights[down_indx]) 
 
1294
                        * mParent->dividers[up_indx];  
 
1295
 
 
1296
                //ColourValue color;
 
1297
                std::vector<ColourValue> color; 
 
1298
                for (unsigned int itex = 0; itex < mNumTexture; itex++) 
 
1299
                {
 
1300
                        for (unsigned int ichan = 0; ichan < mNumChannelperTexture[itex]; ichan++) 
 
1301
                        {    
 
1302
                                color.push_back (ColourValue::Black);
 
1303
                        }
 
1304
                }
 
1305
 
 
1306
 
 
1307
                indx = up_indx;
 
1308
                unsigned int currTexture = 0;
 
1309
                while (indx != 0)
 
1310
                {
 
1311
                        if (indx < mNumChannelperTexture[currTexture])
 
1312
                                break;
 
1313
                        indx = indx - mNumChannelperTexture[currTexture];
 
1314
                        currTexture++;
 
1315
                }
 
1316
                currTexture = currTexture < mNumTexture ? currTexture : mNumTexture - 1;
 
1317
 
 
1318
                if (slope < 0.05f)// speed-up as it's invisible
 
1319
                {
 
1320
                        const Real B = (1.0f - interpol);
 
1321
                        const Real C = interpol;
 
1322
                        color[currTexture] = mParent->colors[down_indx] * B + mParent->colors[up_indx] * C;
 
1323
                }
 
1324
                else 
 
1325
                {
 
1326
                        const Real A = (1.0f - slope);
 
1327
                        const Real B = A * (1.0f - interpol);
 
1328
                        const Real C = A * interpol;
 
1329
                        const Real D = slope;
 
1330
 
 
1331
                        color[currTexture] = mParent->colors[down_indx] * B + mParent->colors[up_indx] * C + mParent->colors[2] * D;
 
1332
                }
 
1333
                // save changes in textures
 
1334
                unsigned int currChannel = 0;
 
1335
                for (unsigned int k = 0; k < mNumTexture; k++) 
 
1336
                {    
 
1337
                        if (mImages[k].getBPP () > 8)
 
1338
                        {
 
1339
                                uchar * const BaseData = mImages[k].getData ();
 
1340
                                assert (BaseData && "PagingLandScapeTexture::computePointColor()");
 
1341
                                const unsigned int curr_image_pos = imagePos*(static_cast <unsigned int>(mNumChannelperTexture[k]));
 
1342
                                assert (mNumChannelperTexture[k] == (mImages[k].getBPP ()/8));
 
1343
                                 
 
1344
                                BaseData[ curr_image_pos + 0] = static_cast <uchar> (color[k].r * bScale);
 
1345
                                BaseData[ curr_image_pos + 1] = static_cast <uchar> (color[k].g * bScale);
 
1346
                                BaseData[ curr_image_pos + 2] = static_cast <uchar> (color[k].b * bScale);
 
1347
                                currChannel += 3;
 
1348
                        }                       
 
1349
                }
 
1350
        }
 
1351
        //-----------------------------------------------------------------------
 
1352
        void PagingLandScapeTexture::paintPoint (const unsigned int imagePos,
 
1353
                const Real   paintForce)
 
1354
        {
 
1355
                assert (mNumTexture > 0);
 
1356
                assert(mParent->channelModifList);
 
1357
                const std::vector<Real>  *channelModifList = mParent->channelModifList;
 
1358
                const uchar bScale = 255;
 
1359
                const Real invPaintForce = 1.0f - paintForce;
 
1360
                unsigned int currChannel = 0;
 
1361
                for (unsigned int k = 0; k < mNumTexture; k++)
 
1362
                {
 
1363
                        uchar * const BaseData = mImages[k].getData();
 
1364
                        assert (BaseData && "PagingLandScapeTexture::paint()");
 
1365
                        const unsigned int currImagePos = imagePos * mNumChannelperTexture[k];
 
1366
                        assert (currImagePos < mImages[k].getSize ());
 
1367
                        assert (mNumChannelperTexture[k]*8 == mImages[k].getBPP ());
 
1368
 
 
1369
                        for (unsigned int j = 0; j < mNumChannelperTexture[k]; j++) 
 
1370
                        {    
 
1371
                                BaseData[ currImagePos + j ] = 
 
1372
                                        static_cast <uchar> (
 
1373
                                                                ((*channelModifList)[currChannel]) * paintForce * bScale 
 
1374
                                                                + BaseData[ currImagePos + j ] * invPaintForce
 
1375
                                                                                );
 
1376
                                currChannel++;
 
1377
                        }
 
1378
                        doTextureNeedUpdate[k] = true;
 
1379
                }
 
1380
        }
 
1381
} //namespace