source: OGRE/trunk/ogrenew/RenderSystems/Direct3D9/src/OgreD3D9Texture.cpp @ 657

Revision 657, 41.0 KB checked in by mattausch, 19 years ago (diff)

added ogre dependencies and patched ogre sources

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