Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/RenderSystems/Direct3D9/src/OgreD3D9Texture.cpp @ 3

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

=update

File size: 39.9 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#include "OgreD3D9Texture.h"
30#include "OgreD3D9HardwarePixelBuffer.h"
31#include "OgreException.h"
32#include "OgreLogManager.h"
33#include "OgreStringConverter.h"
34#include "OgreBitwise.h"
35#include "OgreD3D9Mappings.h"
36#include "OgreD3D9RenderSystem.h"
37#include "OgreRoot.h"
38
39#include "OgreNoMemoryMacros.h"
40#include <d3dx9.h>
41#include <dxerr9.h>
42#include "OgreMemoryMacros.h"
43
44namespace Ogre
45{
46        /****************************************************************************************/
47    D3D9Texture::D3D9Texture(ResourceManager* creator, const String& name, 
48        ResourceHandle handle, const String& group, bool isManual, 
49        ManualResourceLoader* loader, IDirect3DDevice9 *pD3DDevice)
50        :Texture(creator, name, handle, group, isManual, loader),
51        mpDev(pD3DDevice), 
52        mpD3D(NULL), 
53        mpNormTex(NULL),
54        mpCubeTex(NULL),
55                mpVolumeTex(NULL),
56        mpTex(NULL),
57        mD3DPool(D3DPOOL_MANAGED),
58                mDynamicTextures(false)
59        {
60        _initDevice();
61        }
62        /****************************************************************************************/
63        D3D9Texture::~D3D9Texture()
64        {
65        // have to call this here reather than in Resource destructor
66        // since calling virtual methods in base destructors causes crash
67                if (isLoaded())
68                {
69                        unload(); 
70                }
71                else
72                {
73                        freeInternalResources();
74                }
75        }
76        /****************************************************************************************/
77        void D3D9Texture::copyToTexture(TexturePtr& target)
78        {
79        // check if this & target are the same format and type
80                // blitting from or to cube textures is not supported yet
81                if (target->getUsage() != this->getUsage() ||
82                        target->getTextureType() != this->getTextureType())
83                {
84                        OGRE_EXCEPT( Exception::ERR_INVALIDPARAMS, 
85                                        "Src. and dest. textures must be of same type and must have the same usage !!!", 
86                                        "D3D9Texture::copyToTexture" );
87                }
88
89        HRESULT hr;
90        D3D9Texture *other;
91                // get the target
92                other = reinterpret_cast< D3D9Texture * >( target.get() );
93                // target rectangle (whole surface)
94                RECT dstRC = {0, 0, other->getWidth(), other->getHeight()};
95
96                // do it plain for normal texture
97                if (this->getTextureType() == TEX_TYPE_2D)
98                {
99                        // get our source surface
100                        IDirect3DSurface9 *pSrcSurface = 0;
101                        if( FAILED( hr = mpNormTex->GetSurfaceLevel(0, &pSrcSurface) ) )
102                        {
103                                String msg = DXGetErrorDescription9(hr);
104                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
105                        }
106
107                        // get our target surface
108                        IDirect3DSurface9 *pDstSurface = 0;
109                        IDirect3DTexture9 *pOthTex = other->getNormTexture();
110                        if( FAILED( hr = pOthTex->GetSurfaceLevel(0, &pDstSurface) ) )
111                        {
112                                String msg = DXGetErrorDescription9(hr);
113                                SAFE_RELEASE(pSrcSurface);
114                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
115                        }
116
117                        // do the blit, it's called StretchRect in D3D9 :)
118                        if( FAILED( hr = mpDev->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) )
119                        {
120                                String msg = DXGetErrorDescription9(hr);
121                                SAFE_RELEASE(pSrcSurface);
122                                SAFE_RELEASE(pDstSurface);
123                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
124                        }
125
126                        // release temp. surfaces
127                        SAFE_RELEASE(pSrcSurface);
128                        SAFE_RELEASE(pDstSurface);
129                }
130                else if (this->getTextureType() == TEX_TYPE_CUBE_MAP)
131                {
132                        // get the target cube texture
133                        IDirect3DCubeTexture9 *pOthTex = other->getCubeTexture();
134                        // blit to 6 cube faces
135                        for (size_t face = 0; face < 6; face++)
136                        {
137                                // get our source surface
138                                IDirect3DSurface9 *pSrcSurface = 0;
139                                if( FAILED( hr = mpCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pSrcSurface) ) )
140                                {
141                                        String msg = DXGetErrorDescription9(hr);
142                                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
143                                }
144
145                                // get our target surface
146                                IDirect3DSurface9 *pDstSurface = 0;
147                                if( FAILED( hr = pOthTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, 0, &pDstSurface) ) )
148                                {
149                                        String msg = DXGetErrorDescription9(hr);
150                                        SAFE_RELEASE(pSrcSurface);
151                                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
152                                }
153
154                                // do the blit, it's called StretchRect in D3D9 :)
155                                if( FAILED( hr = mpDev->StretchRect( pSrcSurface, NULL, pDstSurface, &dstRC, D3DTEXF_NONE) ) )
156                                {
157                                        String msg = DXGetErrorDescription9(hr);
158                                        SAFE_RELEASE(pSrcSurface);
159                                        SAFE_RELEASE(pDstSurface);
160                                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit : " + msg, "D3D9Texture::copyToTexture" );
161                                }
162
163                                // release temp. surfaces
164                                SAFE_RELEASE(pSrcSurface);
165                                SAFE_RELEASE(pDstSurface);
166                        }
167                }
168                else
169                {
170                        OGRE_EXCEPT( Exception::ERR_NOT_IMPLEMENTED, 
171                                        "Copy to texture is implemented only for 2D and cube textures !!!", 
172                                        "D3D9Texture::copyToTexture" );
173                }
174        }
175        /****************************************************************************************/
176        void D3D9Texture::loadImpl()
177        {
178                if (mUsage & TU_RENDERTARGET)
179                {
180                        createInternalResources();
181                        return;
182                }
183
184        if (!mInternalResourcesCreated)
185        {
186            // NB: Need to initialise pool to some value other than D3DPOOL_DEFAULT,
187            // otherwise, if the texture loading failed, it might re-create as empty
188            // texture when device lost/restore. The actual pool will determine later.
189            mD3DPool = D3DPOOL_MANAGED;
190        }
191
192                // load based on tex.type
193                switch (this->getTextureType())
194                {
195                case TEX_TYPE_1D:
196                case TEX_TYPE_2D:
197                        this->_loadNormTex();
198                        break;
199                case TEX_TYPE_3D:
200            this->_loadVolumeTex();
201            break;
202                case TEX_TYPE_CUBE_MAP:
203                        this->_loadCubeTex();
204                        break;
205                default:
206                        OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::loadImpl" );
207                }
208
209        }
210        /****************************************************************************************/
211        void D3D9Texture::freeInternalResourcesImpl()
212        {
213                SAFE_RELEASE(mpTex);
214                SAFE_RELEASE(mpNormTex);
215                SAFE_RELEASE(mpCubeTex);
216                SAFE_RELEASE(mpVolumeTex);
217        }
218        /****************************************************************************************/
219        void D3D9Texture::_loadCubeTex()
220        {
221                assert(this->getTextureType() == TEX_TYPE_CUBE_MAP);
222
223        // DDS load?
224                if (StringUtil::endsWith(getName(), ".dds"))
225        {
226            // find & load resource data
227                        DataStreamPtr dstream = 
228                                ResourceGroupManager::getSingleton().openResource(
229                                        mName, mGroup, true, this);
230            MemoryDataStream stream( dstream );
231
232                        DWORD usage = 0;
233                        UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
234                                D3DX_DEFAULT : mNumRequestedMipmaps + 1;
235                        // check if mip map volume textures are supported
236                        if (!(mDevCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
237                        {
238                                // no mip map support for this kind of textures :(
239                                mNumMipmaps = 0;
240                                numMips = 1;
241                        }
242
243            // Determine D3D pool to use
244            D3DPOOL pool;
245            if (mUsage & TU_DYNAMIC)
246            {
247                pool = D3DPOOL_DEFAULT;
248            }
249            else
250            {
251                pool = D3DPOOL_MANAGED;
252            }
253
254                        HRESULT hr = D3DXCreateCubeTextureFromFileInMemoryEx(
255                                mpDev,
256                                stream.getPtr(),
257                                stream.size(),
258                                D3DX_DEFAULT, // dims (square)
259                                numMips,
260                                usage,
261                                D3DFMT_UNKNOWN,
262                                pool,
263                                D3DX_DEFAULT,
264                                D3DX_DEFAULT,
265                                0,  // colour key
266                                NULL, // src box
267                                NULL, // palette
268                                &mpCubeTex); 
269
270            if (FAILED(hr))
271                    {
272                                this->freeInternalResources();
273                            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't create cube texture", "D3D9Texture::_loadCubeTex" );
274                    }
275
276            hr = mpCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&mpTex);
277
278            if (FAILED(hr))
279                    {
280                                this->freeInternalResources();
281                            OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture", "D3D9Texture::_loadCubeTex" );
282                    }
283
284            D3DSURFACE_DESC texDesc;
285            mpCubeTex->GetLevelDesc(0, &texDesc);
286            mD3DPool = texDesc.Pool;
287            // set src and dest attributes to the same, we can't know
288            _setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
289            _setFinalAttributes(texDesc.Width, texDesc.Height, 1,  D3D9Mappings::_getPF(texDesc.Format));
290                        mInternalResourcesCreated = true;
291        }
292        else
293        {
294                        // Load from 6 separate files
295                        // Use OGRE its own codecs
296                        String baseName, ext;
297                        size_t pos = mName.find_last_of(".");
298                        baseName = mName.substr(0, pos);
299                        ext = mName.substr(pos+1);
300                        std::vector<Image> images(6);
301                        ConstImagePtrList imagePtrs;
302                        static const String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"};
303
304                        for(size_t i = 0; i < 6; i++)
305                        {
306                                String fullName = baseName + suffixes[i] + "." + ext;
307
308                // find & load resource data intro stream to allow resource
309                                // group changes if required
310                                DataStreamPtr dstream = 
311                                        ResourceGroupManager::getSingleton().openResource(
312                                                fullName, mGroup, true, this);
313       
314                                images[i].load(dstream, ext);
315
316                                imagePtrs.push_back(&images[i]);
317                        }
318
319            _loadImages( imagePtrs );
320        }
321        }
322        /****************************************************************************************/
323        void D3D9Texture::_loadVolumeTex()
324        {
325                assert(this->getTextureType() == TEX_TYPE_3D);
326                // DDS load?
327                if (StringUtil::endsWith(getName(), ".dds"))
328                {
329                        // find & load resource data
330                        DataStreamPtr dstream = 
331                                ResourceGroupManager::getSingleton().openResource(
332                                        mName, mGroup, true, this);
333                        MemoryDataStream stream(dstream);
334       
335                        DWORD usage = 0;
336                        UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
337                                D3DX_DEFAULT : mNumRequestedMipmaps + 1;
338                        // check if mip map volume textures are supported
339                        if (!(mDevCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
340                        {
341                                // no mip map support for this kind of textures :(
342                                mNumMipmaps = 0;
343                                numMips = 1;
344                        }
345
346            // Determine D3D pool to use
347            D3DPOOL pool;
348            if (mUsage & TU_DYNAMIC)
349            {
350                pool = D3DPOOL_DEFAULT;
351            }
352            else
353            {
354                pool = D3DPOOL_MANAGED;
355            }
356
357                        HRESULT hr = D3DXCreateVolumeTextureFromFileInMemoryEx(
358                                mpDev,
359                                stream.getPtr(),
360                                stream.size(),
361                                D3DX_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT, // dims
362                                numMips,
363                                usage,
364                                D3DFMT_UNKNOWN,
365                                pool,
366                                D3DX_DEFAULT,
367                                D3DX_DEFAULT,
368                                0,  // colour key
369                                NULL, // src box
370                                NULL, // palette
371                                &mpVolumeTex); 
372       
373                        if (FAILED(hr))
374                        {
375                                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
376                                        "Unable to load volume texture from " + this->getName(),
377                                        "D3D9Texture::_loadVolumeTex");
378                        }
379       
380                        hr = mpVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&mpTex);
381       
382                        if (FAILED(hr))
383                        {
384                                this->freeInternalResources();
385                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture", "D3D9Texture::_loadVolumeTex" );
386                        }
387       
388                        D3DVOLUME_DESC texDesc;
389                        hr = mpVolumeTex->GetLevelDesc(0, &texDesc);
390            mD3DPool = texDesc.Pool;
391                        // set src and dest attributes to the same, we can't know
392                        _setSrcAttributes(texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format));
393                        _setFinalAttributes(texDesc.Width, texDesc.Height, texDesc.Depth, D3D9Mappings::_getPF(texDesc.Format));
394                        mInternalResourcesCreated = true;
395        }
396                else
397                {
398                        Image img;
399                // find & load resource data intro stream to allow resource
400                        // group changes if required
401                        DataStreamPtr dstream = 
402                                ResourceGroupManager::getSingleton().openResource(
403                                        mName, mGroup, true, this);
404                        size_t pos = mName.find_last_of(".");
405                        String ext = mName.substr(pos+1);
406       
407                        img.load(dstream, ext);
408                        // Call internal _loadImages, not loadImage since that's external and
409                        // will determine load status etc again
410                        ConstImagePtrList imagePtrs;
411                        imagePtrs.push_back(&img);
412                        _loadImages( imagePtrs );
413                }
414    }
415        /****************************************************************************************/
416        void D3D9Texture::_loadNormTex()
417        {
418                assert(this->getTextureType() == TEX_TYPE_1D || this->getTextureType() == TEX_TYPE_2D);
419                // DDS load?
420                if (StringUtil::endsWith(getName(), ".dds"))
421                {
422                        // Use D3DX
423                        // find & load resource data
424                        DataStreamPtr dstream = 
425                                ResourceGroupManager::getSingleton().openResource(
426                                        mName, mGroup, true, this);
427                        MemoryDataStream stream(dstream);
428       
429                        DWORD usage = 0;
430                        UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ?
431                                D3DX_DEFAULT : mNumRequestedMipmaps + 1;
432                        // check if mip map volume textures are supported
433                        if (!(mDevCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP))
434                        {
435                                // no mip map support for this kind of textures :(
436                                mNumMipmaps = 0;
437                                numMips = 1;
438                        }
439
440            // Determine D3D pool to use
441            D3DPOOL pool;
442            if (mUsage & TU_DYNAMIC)
443            {
444                pool = D3DPOOL_DEFAULT;
445            }
446            else
447            {
448                pool = D3DPOOL_MANAGED;
449            }
450
451                        HRESULT hr = D3DXCreateTextureFromFileInMemoryEx(
452                                mpDev,
453                                stream.getPtr(),
454                                stream.size(),
455                                D3DX_DEFAULT, D3DX_DEFAULT, // dims
456                                numMips,
457                                usage,
458                                D3DFMT_UNKNOWN,
459                                pool,
460                                D3DX_DEFAULT,
461                                D3DX_DEFAULT,
462                                0,  // colour key
463                                NULL, // src box
464                                NULL, // palette
465                                &mpNormTex); 
466       
467                        if (FAILED(hr))
468                        {
469                                OGRE_EXCEPT(Exception::ERR_INTERNAL_ERROR, 
470                                        "Unable to load texture from " + this->getName(),
471                                        "D3D9Texture::_loadNormTex");
472                        }
473       
474                        hr = mpNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&mpTex);
475       
476                        if (FAILED(hr))
477                        {
478                                this->freeInternalResources();
479                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture", "D3D9Texture::_loadNormTex" );
480                        }
481       
482                        D3DSURFACE_DESC texDesc;
483                        mpNormTex->GetLevelDesc(0, &texDesc);
484            mD3DPool = texDesc.Pool;
485                        // set src and dest attributes to the same, we can't know
486                        _setSrcAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
487                        _setFinalAttributes(texDesc.Width, texDesc.Height, 1, D3D9Mappings::_getPF(texDesc.Format));
488                        mInternalResourcesCreated = true;
489        }
490                else
491                {
492                        Image img;
493                // find & load resource data intro stream to allow resource
494                        // group changes if required
495                        DataStreamPtr dstream = 
496                                ResourceGroupManager::getSingleton().openResource(
497                                        mName, mGroup, true, this);
498       
499                        size_t pos = mName.find_last_of(".");
500                        String ext = mName.substr(pos+1);
501                       
502                        img.load(dstream, ext);
503                        // Call internal _loadImages, not loadImage since that's external and
504                        // will determine load status etc again
505                        ConstImagePtrList imagePtrs;
506                        imagePtrs.push_back(&img);
507                        _loadImages( imagePtrs );
508                }
509        }
510        /****************************************************************************************/
511    void D3D9Texture::createInternalResourcesImpl(void)
512        {
513                // If mSrcWidth and mSrcHeight are zero, the requested extents have probably been set
514                // through setWidth and setHeight, which set mWidth and mHeight. Take those values.
515                if(mSrcWidth == 0 || mSrcHeight == 0) {
516                        mSrcWidth = mWidth;
517                        mSrcHeight = mHeight;
518                }
519               
520                // Determine D3D pool to use
521                // Use managed unless we're a render target or user has asked for
522                // a dynamic texture
523                if ((mUsage & TU_RENDERTARGET) ||
524                        (mUsage & TU_DYNAMIC))
525                {
526                        mD3DPool = D3DPOOL_DEFAULT;
527                }
528                else
529                {
530                        mD3DPool = D3DPOOL_MANAGED;
531                }
532                // load based on tex.type
533                switch (this->getTextureType())
534                {
535                case TEX_TYPE_1D:
536                case TEX_TYPE_2D:
537                        this->_createNormTex();
538                        break;
539                case TEX_TYPE_CUBE_MAP:
540                        this->_createCubeTex();
541                        break;
542                case TEX_TYPE_3D:
543                        this->_createVolumeTex();
544                        break;
545                default:
546                        this->freeInternalResources();
547                        OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::createInternalResources" );
548                }
549        }
550        /****************************************************************************************/
551        void D3D9Texture::_createNormTex()
552        {
553                // we must have those defined here
554                assert(mSrcWidth > 0 || mSrcHeight > 0);
555
556                // determine wich D3D9 pixel format we'll use
557                HRESULT hr;
558                D3DFORMAT d3dPF = this->_chooseD3DFormat();
559                // let's D3DX check the corrected pixel format
560                hr = D3DXCheckTextureRequirements(mpDev, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
561
562                // Use D3DX to help us create the texture, this way it can adjust any relevant sizes
563                DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
564                UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? 
565                                D3DX_DEFAULT : mNumRequestedMipmaps + 1;
566                // Check dynamic textures
567                if (mUsage & TU_DYNAMIC)
568                {
569                        if (_canUseDynamicTextures(usage, D3DRTYPE_TEXTURE, d3dPF))
570                        {
571                                usage |= D3DUSAGE_DYNAMIC;
572                                mDynamicTextures = true;
573                        }
574                        else
575                        {
576                                mDynamicTextures = false;
577                        }
578                }
579                // check if mip maps are supported on hardware
580                mMipmapsHardwareGenerated = false;
581                if (mDevCaps.TextureCaps & D3DPTEXTURECAPS_MIPMAP)
582                {
583                        if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0)
584                        {
585                                // use auto.gen. if available, and if desired
586                                mMipmapsHardwareGenerated = this->_canAutoGenMipmaps(usage, D3DRTYPE_TEXTURE, d3dPF);
587                                if (mMipmapsHardwareGenerated)
588                                {
589                                        usage |= D3DUSAGE_AUTOGENMIPMAP;
590                                        numMips = 0;
591                                }
592                        }
593                }
594                else
595                {
596                        // no mip map support for this kind of textures :(
597                        mNumMipmaps = 0;
598                        numMips = 1;
599                }
600
601                // create the texture
602                hr = D3DXCreateTexture( 
603                                mpDev,                                                          // device
604                                mSrcWidth,                                                      // width
605                                mSrcHeight,                                                     // height
606                                numMips,                                                        // number of mip map levels
607                                usage,                                                          // usage
608                                d3dPF,                                                          // pixel format
609                                mD3DPool,
610                                &mpNormTex);                                            // data pointer
611                // check result and except if failed
612                if (FAILED(hr))
613                {
614                        this->freeInternalResources();
615                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture", "D3D9Texture::_createNormTex" );
616                }
617               
618                // set the base texture we'll use in the render system
619                hr = mpNormTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&mpTex);
620                if (FAILED(hr))
621                {
622                        this->freeInternalResources();
623                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture", "D3D9Texture::_createNormTex" );
624                }
625               
626                // set final tex. attributes from tex. description
627                // they may differ from the source image !!!
628                D3DSURFACE_DESC desc;
629                hr = mpNormTex->GetLevelDesc(0, &desc);
630                if (FAILED(hr))
631                {
632                        this->freeInternalResources();
633                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description", "D3D9Texture::_createNormTex" );
634                }
635                this->_setFinalAttributes(desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format));
636               
637                // Set best filter type
638                if(mMipmapsHardwareGenerated)
639                {
640                        hr = mpTex->SetAutoGenFilterType(_getBestFilterMethod());
641                        if(FAILED(hr))
642                        {
643                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type", "D3D9Texture::_createNormTex" );
644                        }
645                }
646        }
647        /****************************************************************************************/
648        void D3D9Texture::_createCubeTex()
649        {
650                // we must have those defined here
651                assert(mSrcWidth > 0 || mSrcHeight > 0);
652
653                // determine wich D3D9 pixel format we'll use
654                HRESULT hr;
655                D3DFORMAT d3dPF = this->_chooseD3DFormat();
656                // let's D3DX check the corrected pixel format
657                hr = D3DXCheckCubeTextureRequirements(mpDev, NULL, NULL, 0, &d3dPF, mD3DPool);
658
659                // Use D3DX to help us create the texture, this way it can adjust any relevant sizes
660                DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
661                UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? 
662                        D3DX_DEFAULT : mNumRequestedMipmaps + 1;
663                // Check dynamic textures
664                if (mUsage & TU_DYNAMIC)
665                {
666                        if (_canUseDynamicTextures(usage, D3DRTYPE_CUBETEXTURE, d3dPF))
667                        {
668                                usage |= D3DUSAGE_DYNAMIC;
669                                mDynamicTextures = true;
670                        }
671                        else
672                        {
673                                mDynamicTextures = false;
674                        }
675                }
676                // check if mip map cube textures are supported
677                mMipmapsHardwareGenerated = false;
678                if (mDevCaps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP)
679                {
680                        if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0)
681                        {
682                                // use auto.gen. if available
683                                mMipmapsHardwareGenerated = this->_canAutoGenMipmaps(usage, D3DRTYPE_CUBETEXTURE, d3dPF);
684                                if (mMipmapsHardwareGenerated)
685                                {
686                                        usage |= D3DUSAGE_AUTOGENMIPMAP;
687                                        numMips = 0;
688                                }
689                        }
690                }
691                else
692                {
693                        // no mip map support for this kind of textures :(
694                        mNumMipmaps = 0;
695                        numMips = 1;
696                }
697
698                // create the texture
699                hr = D3DXCreateCubeTexture(     
700                                mpDev,                                                          // device
701                                mSrcWidth,                                                      // dimension
702                                numMips,                                                        // number of mip map levels
703                                usage,                                                          // usage
704                                d3dPF,                                                          // pixel format
705                                mD3DPool,
706                                &mpCubeTex);                                            // data pointer
707                // check result and except if failed
708                if (FAILED(hr))
709                {
710                        this->freeInternalResources();
711                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture", "D3D9Texture::_createCubeTex" );
712                }
713
714                // set the base texture we'll use in the render system
715                hr = mpCubeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&mpTex);
716                if (FAILED(hr))
717                {
718                        this->freeInternalResources();
719                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture", "D3D9Texture::_createCubeTex" );
720                }
721               
722                // set final tex. attributes from tex. description
723                // they may differ from the source image !!!
724                D3DSURFACE_DESC desc;
725                hr = mpCubeTex->GetLevelDesc(0, &desc);
726                if (FAILED(hr))
727                {
728                        this->freeInternalResources();
729                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description", "D3D9Texture::_createCubeTex" );
730                }
731                this->_setFinalAttributes(desc.Width, desc.Height, 1, D3D9Mappings::_getPF(desc.Format));
732
733                // Set best filter type
734                if(mMipmapsHardwareGenerated)
735                {
736                        hr = mpTex->SetAutoGenFilterType(_getBestFilterMethod());
737                        if(FAILED(hr))
738                        {
739                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type", "D3D9Texture::_createCubeTex" );
740                        }
741                }
742        }
743        /****************************************************************************************/
744        void D3D9Texture::_createVolumeTex()
745        {
746                // we must have those defined here
747                assert(mWidth > 0 && mHeight > 0 && mDepth>0);
748
749                // determine wich D3D9 pixel format we'll use
750                HRESULT hr;
751                D3DFORMAT d3dPF = this->_chooseD3DFormat();
752                // let's D3DX check the corrected pixel format
753                hr = D3DXCheckVolumeTextureRequirements(mpDev, NULL, NULL, NULL, NULL, 0, &d3dPF, mD3DPool);
754
755                // Use D3DX to help us create the texture, this way it can adjust any relevant sizes
756                DWORD usage = (mUsage & TU_RENDERTARGET) ? D3DUSAGE_RENDERTARGET : 0;
757                UINT numMips = (mNumRequestedMipmaps == MIP_UNLIMITED) ? 
758                        D3DX_DEFAULT : mNumRequestedMipmaps + 1;
759                // Check dynamic textures
760                if (mUsage & TU_DYNAMIC)
761                {
762                        if (_canUseDynamicTextures(usage, D3DRTYPE_VOLUMETEXTURE, d3dPF))
763                        {
764                                usage |= D3DUSAGE_DYNAMIC;
765                                mDynamicTextures = true;
766                        }
767                        else
768                        {
769                                mDynamicTextures = false;
770                        }
771                }
772                // check if mip map volume textures are supported
773                mMipmapsHardwareGenerated = false;
774                if (mDevCaps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP)
775                {
776                        if (mUsage & TU_AUTOMIPMAP && mNumRequestedMipmaps != 0)
777                        {
778                                // use auto.gen. if available
779                                mMipmapsHardwareGenerated = this->_canAutoGenMipmaps(usage, D3DRTYPE_VOLUMETEXTURE, d3dPF);
780                                if (mMipmapsHardwareGenerated)
781                                {
782                                        usage |= D3DUSAGE_AUTOGENMIPMAP;
783                                        numMips = 0;
784                                }
785                        }
786                }
787                else
788                {
789                        // no mip map support for this kind of textures :(
790                        mNumMipmaps = 0;
791                        numMips = 1;
792                }
793
794                // create the texture
795                hr = D3DXCreateVolumeTexture(   
796                                mpDev,                                                          // device
797                                mWidth,                                                         // dimension
798                                mHeight,
799                                mDepth,
800                                numMips,                                                        // number of mip map levels
801                                usage,                                                          // usage
802                                d3dPF,                                                          // pixel format
803                                mD3DPool,
804                                &mpVolumeTex);                                          // data pointer
805                // check result and except if failed
806                if (FAILED(hr))
807                {
808                        this->freeInternalResources();
809                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Error creating texture", "D3D9Texture::_createVolumeTex" );
810                }
811
812                // set the base texture we'll use in the render system
813                hr = mpVolumeTex->QueryInterface(IID_IDirect3DBaseTexture9, (void **)&mpTex);
814                if (FAILED(hr))
815                {
816                        this->freeInternalResources();
817                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get base texture", "D3D9Texture::_createVolumeTex" );
818                }
819               
820                // set final tex. attributes from tex. description
821                // they may differ from the source image !!!
822                D3DVOLUME_DESC desc;
823                hr = mpVolumeTex->GetLevelDesc(0, &desc);
824                if (FAILED(hr))
825                {
826                        this->freeInternalResources();
827                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Can't get texture description", "D3D9Texture::_createVolumeTex" );
828                }
829                this->_setFinalAttributes(desc.Width, desc.Height, desc.Depth, D3D9Mappings::_getPF(desc.Format));
830               
831                // Set best filter type
832                if(mMipmapsHardwareGenerated)
833                {
834                        hr = mpTex->SetAutoGenFilterType(_getBestFilterMethod());
835                        if(FAILED(hr))
836                        {
837                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not set best autogen filter type", "D3D9Texture::_createCubeTex" );
838                        }
839                }
840        }
841        /****************************************************************************************/
842        void D3D9Texture::_initDevice(void)
843        { 
844                assert(mpDev);
845                HRESULT hr;
846
847                // get device caps
848                hr = mpDev->GetDeviceCaps(&mDevCaps);
849                if (FAILED(hr))
850                        OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Can't get device description", "D3D9Texture::_setDevice" );
851
852                // get D3D pointer
853                hr = mpDev->GetDirect3D(&mpD3D);
854                // decrement reference count
855                mpD3D->Release();
856                if (FAILED(hr))
857                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to get D3D9 pointer", "D3D9Texture::_setDevice" );
858
859                // get our device creation parameters
860                hr = mpDev->GetCreationParameters(&mDevCreParams);
861                if (FAILED(hr))
862                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to get D3D9 device creation parameters", "D3D9Texture::_setDevice" );
863
864                // get our back buffer pixel format
865                IDirect3DSurface9 *pSrf;
866                D3DSURFACE_DESC srfDesc;
867                hr = mpDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSrf);
868                // decrement reference count
869                pSrf->Release();
870                if (FAILED(hr))
871                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to get D3D9 device pixel format", "D3D9Texture::_setDevice" );
872
873                hr = pSrf->GetDesc(&srfDesc);
874                if (FAILED(hr))
875                {
876                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Failed to get D3D9 device pixel format", "D3D9Texture::_setDevice" );
877                }
878
879                mBBPixelFormat = srfDesc.Format;
880        }
881        /****************************************************************************************/
882        void D3D9Texture::_setFinalAttributes(unsigned long width, unsigned long height, 
883        unsigned long depth, PixelFormat format)
884        { 
885                // set target texture attributes
886                mHeight = height; 
887                mWidth = width; 
888        mDepth = depth;
889                mFormat = format; 
890
891                // Update size (the final size, including temp space because in consumed memory)
892                // this is needed in Resource class
893                mSize = calculateSize();
894
895                // say to the world what we are doing
896                if (mWidth != mSrcWidth ||
897                        mHeight != mSrcHeight)
898                {
899                        LogManager::getSingleton().logMessage("D3D9 : ***** Dimensions altered by the render system");
900                        LogManager::getSingleton().logMessage("D3D9 : ***** Source image dimensions : " + StringConverter::toString(mSrcWidth) + "x" + StringConverter::toString(mSrcHeight));
901                        LogManager::getSingleton().logMessage("D3D9 : ***** Texture dimensions : " + StringConverter::toString(mWidth) + "x" + StringConverter::toString(mHeight));
902                }
903               
904                // Create list of subsurfaces for getBuffer()
905                _createSurfaceList();
906        }
907        /****************************************************************************************/
908        void D3D9Texture::_setSrcAttributes(unsigned long width, unsigned long height, 
909        unsigned long depth, PixelFormat format)
910        { 
911                // set source image attributes
912                mSrcWidth = width; 
913                mSrcHeight = height; 
914                mSrcDepth = depth;
915        mSrcFormat = format;
916                // say to the world what we are doing
917                switch (this->getTextureType())
918                {
919                case TEX_TYPE_1D:
920                        if (mUsage & TU_RENDERTARGET)
921                                LogManager::getSingleton().logMessage("D3D9 : Creating 1D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
922                        else
923                                LogManager::getSingleton().logMessage("D3D9 : Loading 1D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
924                        break;
925                case TEX_TYPE_2D:
926                        if (mUsage & TU_RENDERTARGET)
927                                LogManager::getSingleton().logMessage("D3D9 : Creating 2D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
928                        else
929                                LogManager::getSingleton().logMessage("D3D9 : Loading 2D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
930                        break;
931                case TEX_TYPE_3D:
932                        if (mUsage & TU_RENDERTARGET)
933                                LogManager::getSingleton().logMessage("D3D9 : Creating 3D RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
934                        else
935                                LogManager::getSingleton().logMessage("D3D9 : Loading 3D Texture, image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
936                        break;
937                case TEX_TYPE_CUBE_MAP:
938                        if (mUsage & TU_RENDERTARGET)
939                                LogManager::getSingleton().logMessage("D3D9 : Creating Cube map RenderTarget, name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
940                        else
941                                LogManager::getSingleton().logMessage("D3D9 : Loading Cube Texture, base image name : '" + this->getName() + "' with " + StringConverter::toString(mNumMipmaps) + " mip map levels");
942                        break;
943                default:
944                        this->freeInternalResources();
945                        OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3D9Texture::_setSrcAttributes" );
946                }
947        }
948        /****************************************************************************************/
949        D3DTEXTUREFILTERTYPE D3D9Texture::_getBestFilterMethod()
950        {
951                // those MUST be initialized !!!
952                assert(mpDev);
953                assert(mpD3D);
954                assert(mpTex);
955               
956                DWORD filterCaps = 0;
957                // Minification filter is used for mipmap generation
958                // Pick the best one supported for this tex type
959                switch (this->getTextureType())
960                {
961                case TEX_TYPE_1D:               // Same as 2D
962                case TEX_TYPE_2D:               filterCaps = mDevCaps.TextureFilterCaps;        break;
963                case TEX_TYPE_3D:               filterCaps = mDevCaps.VolumeTextureFilterCaps;  break;
964                case TEX_TYPE_CUBE_MAP: filterCaps = mDevCaps.CubeTextureFilterCaps;    break;
965                }
966                if(filterCaps & D3DPTFILTERCAPS_MINFGAUSSIANQUAD)
967                        return D3DTEXF_GAUSSIANQUAD;
968               
969                if(filterCaps & D3DPTFILTERCAPS_MINFPYRAMIDALQUAD)
970                        return D3DTEXF_PYRAMIDALQUAD;
971               
972                if(filterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC)
973                        return D3DTEXF_ANISOTROPIC;
974               
975                if(filterCaps & D3DPTFILTERCAPS_MINFLINEAR)
976                        return D3DTEXF_LINEAR;
977               
978                if(filterCaps & D3DPTFILTERCAPS_MINFPOINT)
979                        return D3DTEXF_POINT;
980               
981                return D3DTEXF_POINT;
982        }
983        /****************************************************************************************/
984        bool D3D9Texture::_canUseDynamicTextures(DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat)
985        {
986                // those MUST be initialized !!!
987                assert(mpDev);
988                assert(mpD3D);
989
990                // Check for dynamic texture support
991                HRESULT hr;
992                // check for auto gen. mip maps support
993                hr = mpD3D->CheckDeviceFormat(
994                        mDevCreParams.AdapterOrdinal, 
995                        mDevCreParams.DeviceType, 
996                        mBBPixelFormat, 
997                        srcUsage | D3DUSAGE_DYNAMIC,
998                        srcType,
999                        srcFormat);
1000                if (hr == D3D_OK)
1001                        return true;
1002                else
1003                        return false;
1004        }
1005        /****************************************************************************************/
1006        bool D3D9Texture::_canAutoGenMipmaps(DWORD srcUsage, D3DRESOURCETYPE srcType, D3DFORMAT srcFormat)
1007        {
1008                // those MUST be initialized !!!
1009                assert(mpDev);
1010                assert(mpD3D);
1011
1012                // Hacky override - many (all?) cards seem to not be able to autogen on
1013                // textures which are not a power of two
1014                // Can we even mipmap on 3D textures? Well
1015                if ((mWidth & mWidth-1) || (mHeight & mHeight-1) || (mDepth & mDepth-1))
1016                        return false;
1017
1018                if (mDevCaps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP)
1019                {
1020                        HRESULT hr;
1021                        // check for auto gen. mip maps support
1022                        hr = mpD3D->CheckDeviceFormat(
1023                                        mDevCreParams.AdapterOrdinal, 
1024                                        mDevCreParams.DeviceType, 
1025                                        mBBPixelFormat, 
1026                                        srcUsage | D3DUSAGE_AUTOGENMIPMAP,
1027                                        srcType,
1028                                        srcFormat);
1029                        // this HR could a SUCCES
1030                        // but mip maps will not be generated
1031                        if (hr == D3D_OK)
1032                                return true;
1033                        else
1034                                return false;
1035                }
1036                else
1037                        return false;
1038        }
1039        /****************************************************************************************/
1040        D3DFORMAT D3D9Texture::_chooseD3DFormat()
1041        {
1042                // Choose frame buffer pixel format in case PF_UNKNOWN was requested
1043                if(mFormat == PF_UNKNOWN)
1044                        return mBBPixelFormat;
1045                // Choose closest supported D3D format as a D3D format
1046                return D3D9Mappings::_getPF(D3D9Mappings::_getClosestSupportedPF(mFormat));
1047
1048        }
1049        /****************************************************************************************/
1050        // Macro to hide ugly cast
1051        #define GETLEVEL(face,mip) \
1052                static_cast<D3D9HardwarePixelBuffer*>(mSurfaceList[face*(mNumMipmaps+1)+mip].get())
1053        void D3D9Texture::_createSurfaceList(void)
1054        {
1055                IDirect3DSurface9 *surface;
1056                IDirect3DVolume9 *volume;
1057                D3D9HardwarePixelBuffer *buffer;
1058                size_t mip, face;
1059                assert(mpTex);
1060                // Make sure number of mips is right
1061                mNumMipmaps = mpTex->GetLevelCount() - 1;
1062                // Need to know static / dynamic
1063                unsigned int bufusage;
1064                if ((mUsage & TU_DYNAMIC) && mDynamicTextures)
1065                {
1066                        bufusage = HardwareBuffer::HBU_DYNAMIC;
1067                }
1068                else
1069                {
1070                        bufusage = HardwareBuffer::HBU_STATIC;
1071                }
1072                if (mUsage & TU_RENDERTARGET)
1073                {
1074                        bufusage |= TU_RENDERTARGET;
1075                }
1076               
1077                bool updateOldList = mSurfaceList.size() == (getNumFaces() * (mNumMipmaps + 1));
1078                if(!updateOldList)
1079                {
1080                        // Create new list of surfaces
1081                        mSurfaceList.clear();
1082                        for(size_t face=0; face<getNumFaces(); ++face)
1083                        {
1084                                for(size_t mip=0; mip<=mNumMipmaps; ++mip)
1085                                {
1086                                        buffer = new D3D9HardwarePixelBuffer((HardwareBuffer::Usage)bufusage);
1087                                        mSurfaceList.push_back(
1088                                                HardwarePixelBufferSharedPtr(buffer)
1089                                        );
1090                                }
1091                        }
1092                }
1093
1094                switch(getTextureType()) {
1095                case TEX_TYPE_2D:
1096                case TEX_TYPE_1D:
1097                        assert(mpNormTex);
1098                        // For all mipmaps, store surfaces as HardwarePixelBufferSharedPtr
1099                        for(mip=0; mip<=mNumMipmaps; ++mip)
1100                        {
1101                                if(mpNormTex->GetSurfaceLevel(mip, &surface) != D3D_OK)
1102                                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get surface level failed",
1103                                                "D3D9Texture::_createSurfaceList");
1104                                // decrement reference count, the GetSurfaceLevel call increments this
1105                                // this is safe because the texture keeps a reference as well
1106                                surface->Release();
1107
1108                                GETLEVEL(0, mip)->bind(mpDev, surface, updateOldList);
1109                        }
1110                        break;
1111                case TEX_TYPE_CUBE_MAP:
1112                        assert(mpCubeTex);
1113                        // For all faces and mipmaps, store surfaces as HardwarePixelBufferSharedPtr
1114                        for(face=0; face<6; ++face)
1115                        {
1116                                for(mip=0; mip<=mNumMipmaps; ++mip)
1117                                {
1118                                        if(mpCubeTex->GetCubeMapSurface((D3DCUBEMAP_FACES)face, mip, &surface) != D3D_OK)
1119                                                OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get cubemap surface failed",
1120                                                "D3D9Texture::getBuffer");
1121                                        // decrement reference count, the GetSurfaceLevel call increments this
1122                                        // this is safe because the texture keeps a reference as well
1123                                        surface->Release();
1124                                       
1125                                        GETLEVEL(face, mip)->bind(mpDev, surface, updateOldList);
1126                                }
1127                        }
1128                        break;
1129                case TEX_TYPE_3D:
1130                        assert(mpVolumeTex);
1131                        // For all mipmaps, store surfaces as HardwarePixelBufferSharedPtr
1132                        for(mip=0; mip<=mNumMipmaps; ++mip)
1133                        {
1134                                if(mpVolumeTex->GetVolumeLevel(mip, &volume) != D3D_OK)
1135                                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Get volume level failed",
1136                                                "D3D9Texture::getBuffer");     
1137                                // decrement reference count, the GetSurfaceLevel call increments this
1138                                // this is safe because the texture keeps a reference as well
1139                                volume->Release();
1140                                               
1141                                GETLEVEL(0, mip)->bind(mpDev, volume, updateOldList);
1142                        }
1143                        break;
1144                };
1145               
1146                // Set autogeneration of mipmaps for each face of the texture, if it is enabled
1147                if(mNumRequestedMipmaps != 0 && (mUsage & TU_AUTOMIPMAP)) 
1148                {
1149                        for(face=0; face<getNumFaces(); ++face)
1150                        {
1151                                GETLEVEL(face, 0)->_setMipmapping(true, mMipmapsHardwareGenerated, mpTex);
1152                        }
1153                }
1154        }
1155        #undef GETLEVEL
1156        /****************************************************************************************/
1157        HardwarePixelBufferSharedPtr D3D9Texture::getBuffer(size_t face, size_t mipmap) 
1158        {
1159                if(face >= getNumFaces())
1160                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "A three dimensional cube has six faces",
1161                                        "D3D9Texture::getBuffer");
1162                if(mipmap > mNumMipmaps)
1163                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range",
1164                                        "D3D9Texture::getBuffer");
1165                size_t idx = face*(mNumMipmaps+1) + mipmap;
1166                assert(idx < mSurfaceList.size());
1167                return mSurfaceList[idx];
1168        }
1169       
1170       
1171        /****************************************************************************************/
1172        bool D3D9Texture::releaseIfDefaultPool(void)
1173        {
1174                if(mD3DPool == D3DPOOL_DEFAULT)
1175                {
1176                        LogManager::getSingleton().logMessage(
1177                                "Releasing D3D9 default pool texture: " + mName);
1178                        // Just free any internal resources, don't call unload() here
1179                        // because we want the un-touched resource to keep its unloaded status
1180                        // after device reset.
1181                        freeInternalResources();
1182                        LogManager::getSingleton().logMessage(
1183                                "Released D3D9 default pool texture: " + mName);
1184                        return true;
1185                }
1186                return false;
1187        }
1188        /****************************************************************************************/
1189        bool D3D9Texture::recreateIfDefaultPool(LPDIRECT3DDEVICE9 pDev)
1190        {
1191                bool ret = false;
1192                if(mD3DPool == D3DPOOL_DEFAULT)
1193                {
1194                        ret = true;
1195                        LogManager::getSingleton().logMessage(
1196                                "Recreating D3D9 default pool texture: " + mName);
1197                        // We just want to create the texture resources if:
1198                        // 1. This is a render texture, or
1199                        // 2. This is a manual texture with no loader, or
1200                        // 3. This was an unloaded regular texture (preserve unloaded state)
1201                        if ((mIsManual && !mLoader) || (mUsage & TU_RENDERTARGET) || !isLoaded())
1202                        {
1203                                // just recreate any internal resources
1204                                createInternalResources();
1205                        }
1206                        // Otherwise, this is a regular loaded texture, or a manual texture with a loader
1207                        else
1208                        {
1209                                // The internal resources already freed, need unload/load here:
1210                                // 1. Make sure resource memory usage statistic correction.
1211                                // 2. Don't call unload() in releaseIfDefaultPool() because we want
1212                                //    the un-touched resource keep unload status after device reset.
1213                                unload();
1214                                // if manual, we need to recreate internal resources since load() won't do that
1215                                if (mIsManual)
1216                                        createInternalResources();
1217                                load();
1218                        }
1219                        LogManager::getSingleton().logMessage(
1220                                "Recreated D3D9 default pool texture: " + mName);
1221                }
1222
1223                return ret;
1224
1225        }
1226
1227
1228        /****************************************************************************************/
1229    void D3D9RenderTexture::update(void)
1230    {
1231        D3D9RenderSystem* rs = static_cast<D3D9RenderSystem*>(
1232            Root::getSingleton().getRenderSystem());
1233        if (rs->isDeviceLost())
1234            return;
1235
1236        RenderTexture::update();
1237    }
1238}
Note: See TracBrowser for help on using the repository browser.