source: OGRE/trunk/ogrenew/RenderSystems/Direct3D7/src/OgreD3D7Texture.cpp @ 657

Revision 657, 25.7 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 "OgreD3D7Texture.h"
26#include "OgreException.h"
27#include "OgreImage.h"
28#include "OgreLogManager.h"
29#include "OgreHardwarePixelBuffer.h"
30#include "OgreRoot.h"
31
32namespace Ogre {
33
34    D3DX_SURFACEFORMAT D3DTexture::OgreFormat_to_D3DXFormat( PixelFormat format )
35    {
36                switch( format )
37                {
38                case PF_R8G8B8:
39                        return D3DX_SF_R8G8B8;
40                case PF_A8R8G8B8:
41                        return D3DX_SF_A8R8G8B8;
42                case PF_X8R8G8B8:
43                return D3DX_SF_X8R8G8B8;
44                case PF_R5G6B5:
45                return D3DX_SF_R5G6B5;
46                case PF_A4R4G4B4:
47                return D3DX_SF_A4R4G4B4;
48                case PF_L8:
49                return D3DX_SF_L8;
50                case PF_BYTE_LA: // Assume little endian
51                return D3DX_SF_A8L8;
52                case PF_DXT1:
53                return D3DX_SF_DXT1;
54                case PF_DXT3:
55                return D3DX_SF_DXT3;
56                case PF_DXT5:
57                return D3DX_SF_DXT5;
58                case PF_A8:
59                return D3DX_SF_A8;
60                default:
61                        return D3DX_SF_UNKNOWN;
62                }
63    }
64
65        PixelFormat D3DTexture::closestD3DXFormat( PixelFormat format )
66        {
67                if(OgreFormat_to_D3DXFormat(format) != D3DX_SF_UNKNOWN)
68                {
69                        // Format is directly supported -- great!
70                        return format;
71                }
72                switch(format)
73                {
74                case PF_B5G6R5:
75                        return PF_R5G6B5;
76                case PF_B8G8R8:
77                        return PF_R8G8B8;
78                case PF_B8G8R8A8:
79                        return PF_A8R8G8B8;
80                default:
81                        return PF_A8R8G8B8;
82                }
83        }
84
85    bool D3DTexture::OgreFormat_to_DDPixelFormat( PixelFormat format, DDPIXELFORMAT & out )
86    {
87                D3DX_SURFACEFORMAT fmt = OgreFormat_to_D3DXFormat(format);
88                if(fmt != D3DX_SF_UNKNOWN)
89                {
90                        D3DXMakeDDPixelFormat(fmt, &out);
91                        return true;
92                }
93                return false;
94#if 0
95        memset( &out, 0, sizeof( DDPIXELFORMAT ) );
96        out.dwSize = sizeof( DDPIXELFORMAT );
97                if(PixelUtil::isNativeEndian(format))
98                {
99                        int depths[4];
100                        uint32 masks[4];
101                        size_t elemBits = PixelUtil::getNumElemBits(format);
102                        PixelUtil::getBitDepths(format, depths);
103                        PixelUtil::getBitMasks(format, masks);
104
105                        if(PixelUtil::isLuminance(format))
106                        {
107                                out.dwFlags = DDPF_LUMINANCE;
108                                out.dwLuminanceBitCount = elemBits;
109                                out.dwLuminanceBitMask = masks[0];
110                                if(PixelUtil::hasAlpha(format))
111                                {
112                                        out.dwFlags |= DDPF_ALPHAPIXELS;
113                                        out.dwLuminanceAlphaBitMask = masks[3];
114                                }
115                        }
116                        else if(depths[0]==0 && depths[1]==0 && depths[2] == 0 && depths[3] != 0)
117                        {
118                                // Alpha only format
119                                out.dwFlags = DDPF_ALPHA;
120                                out.dwAlphaBitDepth = elemBits;
121                        }
122                        else
123                        {
124                                // RGB[A] format
125                                out.dwFlags = DDPF_RGB;
126                                out.dwRGBBitCount = elemBits;
127                                out.dwRBitMask = masks[0];
128                                out.dwGBitMask = masks[1];
129                                out.dwBBitMask = masks[2];
130                               
131                                if(PixelUtil::hasAlpha(format))
132                                {
133                                        out.dwFlags |= DDPF_ALPHAPIXELS;
134                                        out.dwRGBAlphaBitMask = masks[3];
135                                }
136                        }
137                }
138                else
139                {
140                        switch( format )
141                        {
142                        case PF_BYTE_LA:
143                                // Assume little endian
144                                out.dwFlags = DDPF_LUMINANCE | DDPF_ALPHAPIXELS;
145                                out.dwLuminanceBitCount = 16;
146
147                                out.dwLuminanceAlphaBitMask = 0xff00;
148                                out.dwLuminanceBitMask = 0x00ff;
149                                break;
150                        default:
151                                // Error unknown format
152                                return false;
153                        }
154                }
155                return true;
156#endif
157        }
158
159    //---------------------------------------------------------------------------------------------
160    D3DTexture::D3DTexture(ResourceManager* creator, const String& name,
161        ResourceHandle handle, const String& group, bool isManual,
162        ManualResourceLoader* loader, IDirect3DDevice7 * lpDirect3dDevice)
163        :Texture(creator, name, handle, group, isManual, loader),
164        mD3DDevice(lpDirect3dDevice), mRestoring(false)
165    {
166        mD3DDevice->AddRef();
167    }
168    //---------------------------------------------------------------------------------------------
169    D3DTexture::~D3DTexture()
170    {
171        __safeRelease( &mD3DDevice );
172        // have to call this here reather than in Resource destructor
173        // since calling virtual methods in base destructors causes crash
174                if (mIsLoaded)
175                {
176            unload();
177                }
178                else
179                {
180                        freeInternalResources();
181                }
182    }
183       
184    //---------------------------------------------------------------------------------------------
185    void D3DTexture::loadImage( const Image & img )
186    {
187        // Use OGRE its own codecs
188                std::vector<const Image*> imagePtrs;
189                imagePtrs.push_back(&img);
190                _loadImages( imagePtrs );
191        }
192    //---------------------------------------------------------------------------------------------
193    void D3DTexture::loadImage3D( const Image imgs[] )
194    {
195        // Use OGRE its own codecs
196                std::vector<const Image*> imagePtrs;
197                imagePtrs.push_back(&imgs[0]);
198                imagePtrs.push_back(&imgs[1]);
199                imagePtrs.push_back(&imgs[2]);
200                imagePtrs.push_back(&imgs[3]);
201                imagePtrs.push_back(&imgs[4]);
202                imagePtrs.push_back(&imgs[5]);
203                _loadImages( imagePtrs );
204        }
205    //---------------------------------------------------------------------------------------------
206    void D3DTexture::createInternalResourcesImpl(void)
207    {
208                // Skip this if we're restoring device
209                // We're using the generic load() but skipping init since DD can restore that
210                if (!mRestoring)
211                {
212                        if (mTextureType == TEX_TYPE_CUBE_MAP)
213                        {
214                                createSurface3D();
215                        }
216                        else if(mTextureType == TEX_TYPE_2D)
217                        {
218                                createSurface2D();
219                        }
220                        else
221                        {
222                                OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3DTexture::createInternalResources" );
223                        }
224                        _createSurfaceList();
225                }
226    }
227        //---------------------------------------------------------------------------------------------
228        void D3DTexture::restoreFromLostDevice(void)
229        {
230                if (mIsLoaded && !(mUsage & TU_RENDERTARGET))
231                {
232                        mRestoring = true;
233                        // Mark as unloaded even though we're not so we can reload content
234                        mIsLoaded = false;
235                        load();
236                        mRestoring = false;
237                }
238        }
239    //---------------------------------------------------------------------------------------------
240    void D3DTexture::loadImpl(void)
241    {
242                if (mTextureType == TEX_TYPE_CUBE_MAP)
243                {
244                        _constructCubeFaceNames(mName);
245                        Image imgs[6];
246                        for (int face = 0; face < 6; ++face)
247                        {
248                                imgs[face].load(mCubeFaceNames[face], mGroup);
249                        }
250                        loadImage3D(imgs);
251
252                }
253                else if(mTextureType == TEX_TYPE_2D)
254                {
255                        Image img;
256                        img.load(mName, mGroup);
257                       
258                        loadImage( img );
259                }
260                else
261                {
262                        OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Unknown texture type", "D3DTexture::loadImpl" );
263                }
264
265    }
266        //---------------------------------------------------------------------------------------------
267        void D3DTexture::copyToTexture(TexturePtr& target )
268        {
269                HRESULT hr;
270        if( FAILED( hr = ((D3DTexture*)(target.get()))->getDDSurface()->Blt( NULL, mSurface, NULL, DDBLT_WAIT, NULL ) ) )
271        {
272                        if(hr != DDERR_SURFACELOST)
273                                OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR, "Couldn't blit!", "D3DTexture::copyToTexture" );
274        }
275        }
276
277    //---------------------------------------------------------------------------------------------
278    void D3DTexture::freeInternalResourcesImpl()
279    {
280        __safeRelease( &mSurface );
281    }
282        //---------------------------------------------------------------------------------------------
283        void D3DTexture::_chooseD3DFormat(DDPIXELFORMAT &ddpf)
284        {
285                //mFormat = closestD3DXFormat(mFormat);
286                //OgreFormat_to_DDPixelFormat(mFormat, ddpf);
287                /* The pixel format is always RGB */
288        ddpf.dwFlags = DDPF_RGB;
289        ddpf.dwRGBBitCount = mFinalBpp;
290       
291        if( mHasAlpha )
292        {
293            ddpf.dwFlags |= DDPF_ALPHAPIXELS;
294        }
295
296        /* Compute the bit masks */
297        if( mFinalBpp == 16 )
298        {
299            if( mHasAlpha )
300            {
301                /* 4-4-4-4 ARGB */
302                ddpf.dwRGBAlphaBitMask = 0xf000;
303                ddpf.dwRBitMask        = 0x0f00;
304                ddpf.dwGBitMask        = 0x00f0;
305                ddpf.dwBBitMask        = 0x000f;
306                                mFormat = PF_A4R4G4B4;
307            }
308            else
309            {
310                /* 5-6-5 RGB */
311                ddpf.dwRBitMask = 0xf800;
312                ddpf.dwGBitMask = 0x07e0;
313                ddpf.dwBBitMask = 0x001f;
314                                mFormat = PF_R5G6B5;
315            }
316        }
317        else
318        {
319            if( mHasAlpha )
320            {
321                /* 8-8-8-8 ARGB */
322                ddpf.dwRGBAlphaBitMask = 0xff000000;
323                ddpf.dwRBitMask        = 0x00ff0000;
324                ddpf.dwGBitMask        = 0x0000ff00;
325                ddpf.dwBBitMask        = 0x000000ff;
326                                mFormat = PF_A8R8G8B8;
327            }
328            else
329            {
330                /* 8-8-8 RGB */
331                ddpf.dwRBitMask        = 0xff0000;
332                ddpf.dwGBitMask        = 0x00ff00;
333                ddpf.dwBBitMask        = 0x0000ff;
334                                mFormat = PF_X8R8G8B8;
335            }
336        }
337        }
338        //---------------------------------------------------------------------------------------------
339        void D3DTexture::createSurface2D(void)
340        {
341        D3DDEVICEDESC7 ddDesc;
342        ZeroMemory( &ddDesc, sizeof(D3DDEVICEDESC7) );
343
344        if( FAILED( mD3DDevice->GetCaps( &ddDesc ) ) )
345            OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR,
346                    "Could not retrieve Direct3D Device caps.",
347                    "D3DTexture::createSurfaces" );
348
349        // Create a surface descriptor.
350        DDSURFACEDESC2 ddsd;
351        D3DUtil_InitSurfaceDesc( ddsd );
352
353        ddsd.dwSize          = sizeof(DDSURFACEDESC2);
354        ddsd.dwFlags         = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
355        ddsd.ddsCaps.dwCaps  = DDSCAPS_TEXTURE;
356        ddsd.ddsCaps.dwCaps2 = 0;
357        ddsd.dwWidth         = mSrcWidth;
358        ddsd.dwHeight        = mSrcHeight;
359
360        /* If the texture is a render target, set the corresponding flags */
361        if( mUsage & TU_RENDERTARGET )
362        {
363            ddsd.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
364            ddsd.ddsCaps.dwCaps2 = 0;
365            mNumRequestedMipmaps = 0;
366        }
367        else
368        {
369            ddsd.ddsCaps.dwCaps2 = DDSCAPS2_D3DTEXTUREMANAGE;
370        }
371       
372        /* If we want to have mip-maps, set the flags. Note that if the
373           texture is the render target type mip-maps are automatically
374           disabled. */
375        if( mNumRequestedMipmaps )
376        {
377            ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
378            ddsd.dwMipMapCount = mNumRequestedMipmaps;
379
380            ddsd.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;           
381        }
382
383        _chooseD3DFormat(ddsd.ddpfPixelFormat);
384
385        /* Change texture size so that it is a power of 2, if needed. */
386        if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 )
387        {
388            for( ddsd.dwWidth = 1; mSrcWidth > ddsd.dwWidth; ddsd.dwWidth <<= 1 );
389            for( ddsd.dwHeight = 1; mSrcHeight > ddsd.dwHeight; ddsd.dwHeight <<= 1 );
390        }
391
392        /* Change texture size so that it is square, if needed. Note that we made it a
393           power of 2 in the above test, so here we just have to find the bigger dimension
394           and make it the side length. */
395        if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY )
396        {
397            if( ddsd.dwWidth > ddsd.dwHeight )
398                ddsd.dwHeight = ddsd.dwWidth;
399            else                               
400                ddsd.dwWidth  = ddsd.dwHeight;
401        }
402
403        /* Register the possibly modified dimensions. */
404        mWidth = ddsd.dwWidth;
405        mHeight = ddsd.dwHeight;
406        mIsLoaded = true;
407
408        LPDIRECTDRAWSURFACE7 pddsRender;
409        LPDIRECTDRAW7        pDD;
410
411        /* Get a DirectDraw interface. */
412        mD3DDevice->GetRenderTarget( &pddsRender );
413        pddsRender->GetDDInterface( (VOID**)&pDD );
414        pddsRender->Release();
415
416        if( mUsage & TU_RENDERTARGET )
417        {
418            /* Get the pixel format of the primary surface - we need it because
419               render target surfaces need to have the same pixel format. */
420            IDirectDrawSurface7 * pddsPrimarySurface;
421            pDD->GetGDISurface( &pddsPrimarySurface );
422            pddsPrimarySurface->GetPixelFormat( &( ddsd.ddpfPixelFormat ) );
423            pddsPrimarySurface->Release();
424        }
425
426        HRESULT hr;
427
428                /* Now create the surface. */
429        if( FAILED( hr = pDD->CreateSurface( &ddsd, &mSurface, NULL ) ) )
430        {
431            pDD->Release();
432            OGRE_EXCEPT( hr,
433                "Could not create DirectDraw surface.",
434                "D3DTexture::createSurfaces" );
435        }
436
437        if( mUsage & TU_RENDERTARGET )
438        {
439            LPDIRECTDRAWSURFACE7 pddsZBuffer, pddsBackBuffer, pddsTexZBuffer;
440
441            DDSCAPS2 ZBuffDDSCaps;
442            DDSURFACEDESC2 ZBuffDDSD;
443
444            ZBuffDDSCaps.dwCaps = DDSCAPS_ZBUFFER;
445            ZBuffDDSCaps.dwCaps2 = ZBuffDDSCaps.dwCaps3 = ZBuffDDSCaps.dwCaps4 = 0;
446
447            memset( &ZBuffDDSD, 0, sizeof( DDSURFACEDESC2 ) );
448            ZBuffDDSD.dwSize = sizeof( DDSURFACEDESC2 );
449
450            /* If the primary surface has an attached z-buffer, we need one for our texture
451               too. Here, we get the primary surface's z-buffer format and we create a new
452               Z-buffer that we attach to the our texture. */
453            if( SUCCEEDED( mD3DDevice->GetRenderTarget( &pddsBackBuffer ) ) )
454            {
455                if( SUCCEEDED( pddsBackBuffer->GetAttachedSurface( &ZBuffDDSCaps, &pddsZBuffer ) ) )
456                {
457                    pddsZBuffer->GetSurfaceDesc( &ZBuffDDSD );
458
459                    /* Our new Z-buffer should have the size of the new render target. */
460                    ZBuffDDSD.dwWidth = ddsd.dwWidth;
461                    ZBuffDDSD.dwHeight = ddsd.dwHeight;
462
463                    hr = pDD->CreateSurface( &ZBuffDDSD, &pddsTexZBuffer, NULL );
464                    hr = mSurface->AddAttachedSurface( pddsTexZBuffer );
465
466                    pddsBackBuffer->Release();
467                    pddsZBuffer->Release();
468                    pddsTexZBuffer->Release();
469                }
470            }
471        }
472
473        /* Release the DirectDraw interface used in the surface creation */
474        pDD->Release();
475    }
476        //---------------------------------------------------------------------------------------------
477        void D3DTexture::createSurface3D(void)
478        {
479        D3DDEVICEDESC7 ddDesc;
480        ZeroMemory( &ddDesc, sizeof(D3DDEVICEDESC7) );
481
482        if( FAILED( mD3DDevice->GetCaps( &ddDesc ) ) )
483            OGRE_EXCEPT( Exception::ERR_RENDERINGAPI_ERROR,
484                    "Could not retrieve Direct3D Device caps.",
485                    "D3DTexture::createSurfaces" );
486
487        // Create a surface descriptor.
488        DDSURFACEDESC2 ddsd;
489        D3DUtil_InitSurfaceDesc( ddsd );
490
491        ddsd.dwSize          = sizeof(DDSURFACEDESC2);
492        ddsd.dwFlags         = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
493        ddsd.ddsCaps.dwCaps  = DDSCAPS_COMPLEX | DDSCAPS_TEXTURE;
494        ddsd.ddsCaps.dwCaps2 = DDSCAPS2_CUBEMAP|DDSCAPS2_CUBEMAP_ALLFACES;
495        ddsd.dwWidth         = mSrcWidth;
496        ddsd.dwHeight        = mSrcHeight;
497
498        /* If the texture is a render target, set the corresponding flags */
499        if( mUsage & TU_RENDERTARGET )
500        {
501            ddsd.ddsCaps.dwCaps |= DDSCAPS_3DDEVICE | DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY;
502            mNumRequestedMipmaps = 0;
503        }
504        else
505        {
506            ddsd.ddsCaps.dwCaps2 |= DDSCAPS2_D3DTEXTUREMANAGE;
507        }
508       
509        /* If we want to have mip-maps, set the flags. Note that if the
510           texture is the render target type mip-maps are automatically
511           disabled. */
512        if( mNumRequestedMipmaps )
513        {
514            ddsd.dwFlags |= DDSD_MIPMAPCOUNT;
515            ddsd.dwMipMapCount = mNumRequestedMipmaps;
516
517            ddsd.ddsCaps.dwCaps |= DDSCAPS_MIPMAP;           
518        }
519
520        _chooseD3DFormat(ddsd.ddpfPixelFormat);
521
522        /* Change texture size so that it is a power of 2, if needed. */
523        if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 )
524        {
525            for( ddsd.dwWidth = 1; mSrcWidth > ddsd.dwWidth; ddsd.dwWidth <<= 1 );
526            for( ddsd.dwHeight = 1; mSrcHeight > ddsd.dwHeight; ddsd.dwHeight <<= 1 );
527        }
528
529        /* Change texture size so that it is square, if needed. Note that we made it a
530           power of 2 in the above test, so here we just have to find the bigger dimension
531           and make it the side length. */
532        if( ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY )
533        {
534            if( ddsd.dwWidth > ddsd.dwHeight )
535                ddsd.dwHeight = ddsd.dwWidth;
536            else                               
537                ddsd.dwWidth  = ddsd.dwHeight;
538        }
539
540        /* Register the possibly modified dimensions. */
541        mWidth = ddsd.dwWidth;
542        mHeight = ddsd.dwHeight;
543        mIsLoaded = true;
544
545
546        LPDIRECTDRAWSURFACE7 pddsRender;
547        LPDIRECTDRAW7        pDD;
548
549        /* Get a DirectDraw interface. */
550        mD3DDevice->GetRenderTarget( &pddsRender );
551        pddsRender->GetDDInterface( (VOID**)&pDD );
552        pddsRender->Release();
553
554        if( mUsage & TU_RENDERTARGET )
555        {
556            /* Get the pixel format of the primary surface - we need it because
557               render target surfaces need to have the same pixel format. */
558            IDirectDrawSurface7 * pddsPrimarySurface;
559            pDD->GetGDISurface( &pddsPrimarySurface );
560            pddsPrimarySurface->GetPixelFormat( &( ddsd.ddpfPixelFormat ) );
561            pddsPrimarySurface->Release();
562        }
563
564        HRESULT hr;
565
566        /* Now create the surface. */
567        if( FAILED( hr = pDD->CreateSurface( &ddsd, &mSurface, NULL ) ) )
568        {
569            pDD->Release();
570            OGRE_EXCEPT( hr,
571                "Could not create DirectDraw surface.",
572                "D3DTexture::createSurfaces" );
573        }
574
575
576        if( mUsage & TU_RENDERTARGET )
577        {
578            LPDIRECTDRAWSURFACE7 pddsZBuffer, pddsBackBuffer, pddsTexZBuffer;
579
580            DDSCAPS2 ZBuffDDSCaps;
581            DDSURFACEDESC2 ZBuffDDSD;
582
583            ZBuffDDSCaps.dwCaps = DDSCAPS_ZBUFFER;
584            ZBuffDDSCaps.dwCaps2 = ZBuffDDSCaps.dwCaps3 = ZBuffDDSCaps.dwCaps4 = 0;
585
586            memset( &ZBuffDDSD, 0, sizeof( DDSURFACEDESC2 ) );
587            ZBuffDDSD.dwSize = sizeof( DDSURFACEDESC2 );
588
589            /* If the primary surface has an attached z-buffer, we need one for our texture
590               too. Here, we get the primary surface's z-buffer format and we create a new
591               Z-buffer that we attach to the our texture. */
592            if( SUCCEEDED( mD3DDevice->GetRenderTarget( &pddsBackBuffer ) ) )
593            {
594                if( SUCCEEDED( pddsBackBuffer->GetAttachedSurface( &ZBuffDDSCaps, &pddsZBuffer ) ) )
595                {
596                    pddsZBuffer->GetSurfaceDesc( &ZBuffDDSD );
597
598                    /* Our new Z-buffer should have the size of the new render target. */
599                    ZBuffDDSD.dwWidth = ddsd.dwWidth;
600                    ZBuffDDSD.dwHeight = ddsd.dwHeight;
601
602                    hr = pDD->CreateSurface( &ZBuffDDSD, &pddsTexZBuffer, NULL );
603                    hr = mSurface->AddAttachedSurface( pddsTexZBuffer );
604
605                    pddsBackBuffer->Release();
606                    pddsZBuffer->Release();
607                    pddsTexZBuffer->Release();
608                }
609            }
610        }
611
612        /* Release the DirectDraw interface used in the surface creation */
613        pDD->Release();
614        }
615    //---------------------------------------------------------------------------------------------
616    LPDIRECTDRAWSURFACE7 D3DTexture::getDDSurface(void)
617    {
618        return mSurface;
619    }
620        void D3DTexture::_constructCubeFaceNames(const String name)
621        {
622                // the suffixes
623                String suffixes[6] = {"_rt", "_lf", "_up", "_dn", "_fr", "_bk"};
624                size_t pos = -1;
625
626                String ext; // the extension
627                String baseName; // the base name
628                String fakeName = name; // the 'fake' name, temp. holder
629
630                // first find the base name
631                pos = fakeName.find_last_of(".");
632                if (pos == -1)
633                {
634                        OGRE_EXCEPT( Exception::ERR_INTERNAL_ERROR, "Invalid cube texture base name", "D3D9Texture::_constructCubeFaceNames" );
635                }
636
637                baseName = fakeName.substr(0, pos);
638                ext = fakeName.substr(pos);
639
640                // construct the full 6 faces file names from the baseName, suffixes and extension
641                for (size_t i = 0; i < 6; ++i)
642                        mCubeFaceNames[i] = baseName + suffixes[i] + ext;
643        }
644        //---------------------------------------------------------------------------------------------
645        HardwarePixelBufferSharedPtr D3DTexture::getBuffer(size_t face, size_t mipmap)
646        {
647                if(face >= getNumFaces())
648                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "A three dimensional cube has six faces",
649                                        "D3D9Texture::getBuffer");
650                if(mipmap > getNumMipmaps())
651                        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Mipmap index out of range",
652                                        "D3D9Texture::getBuffer");
653                int idx = face*(mNumMipmaps+1) + mipmap;
654                assert(idx < mSurfaceList.size());
655                return mSurfaceList[idx];
656        }
657
658    //---------------------------------------------------------------------------------------------
659        // Macro to hide ugly cast
660        #define GETLEVEL(face,mip) \
661                static_cast<D3D7HardwarePixelBuffer*>(mSurfaceList[face*(mNumMipmaps+1)+mip].get())
662        void D3DTexture::_createSurfaceList()
663        {
664                HRESULT hr;
665                size_t face;
666                mSurfaceList.clear();
667
668                // Get real number of mipmaps
669                DDSURFACEDESC2 desc;
670                desc.dwSize = sizeof(DDSURFACEDESC2);
671                if(mSurface->GetSurfaceDesc(&desc) != D3D_OK)
672                        OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Could not get surface information",
673                        "D3DTexture::_createSurfaceList()");
674                if(desc.dwFlags & DDSD_MIPMAPCOUNT)
675                        mNumMipmaps = desc.dwMipMapCount;
676                else
677                        mNumMipmaps = 0;
678
679                // Create the list
680                HardwareBuffer::Usage bufusage;
681                if ((mUsage & TU_DYNAMIC))
682                {
683                        bufusage = HardwareBuffer::HBU_DYNAMIC;
684                }
685                else
686                {
687                        bufusage = HardwareBuffer::HBU_STATIC;
688                }
689                for(face=0; face < getNumFaces(); ++face)
690                {
691                        for(size_t mip=0; mip<=mNumMipmaps; ++mip)
692                        {
693                                mSurfaceList.push_back(
694                                        HardwarePixelBufferSharedPtr(
695                                                new D3D7HardwarePixelBuffer(bufusage, mD3DDevice)
696                                        )
697                                );
698                        }
699                }
700
701                // Enumerate all surfaces
702        for (face = 0; face < getNumFaces(); ++face)
703                {
704                        LPDIRECTDRAWSURFACE7 pCubeFace;
705                        if(mTextureType == TEX_TYPE_CUBE_MAP)
706                        {
707                                // Get cube map face to blit to
708                                DDSCAPS2 cubeCaps;
709                                ZeroMemory(&cubeCaps, sizeof(DDSCAPS2));
710                                switch (face)
711                                {
712                                case 0:
713                                        // left
714                                        cubeCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX;
715                                        break;
716                                case 1:
717                                        // right
718                                        cubeCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX;
719                                        break;
720                                case 2:
721                                        // up
722                                        cubeCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY;
723                                        break;
724                                case 3:
725                                        // down
726                                        cubeCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY;
727                                        break;
728                                case 4:
729                                        // front - NB DirectX is backwards
730                                        cubeCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ;
731                                        break;
732                                case 5:
733                                        // back - NB DirectX is backwards
734                                        cubeCaps.dwCaps2 = DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ;
735                                        break;
736                                }
737
738                                if (FAILED(hr = mSurface->GetAttachedSurface( &cubeCaps, &pCubeFace)))
739                                {
740                                        OGRE_EXCEPT( hr, "Error getting cube face surface.", "D3DTexture::_createSurfaceList" );
741                                }       
742                        }
743                        else
744                        {
745                                pCubeFace = mSurface;
746                                pCubeFace->AddRef();
747                        }
748
749                        GETLEVEL(face, 0)->bind(pCubeFace, mFormat);
750
751                        LPDIRECTDRAWSURFACE7 ddsMipLevel, ddsNextLevel;
752                        DDSCAPS2 ddsCaps;
753                        HRESULT mipRes = DD_OK;
754                        size_t mipLevel = 1;
755
756                        ZeroMemory(&ddsCaps, sizeof(DDSCAPS2));
757                        ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP;
758
759                        // Get the base level and increae the reference count.
760                        ddsMipLevel = pCubeFace;
761                        ddsMipLevel->AddRef();
762
763                        /// While we can get a next level in the mip-map chain.
764                        while( ddsMipLevel->GetAttachedSurface( &ddsCaps, &ddsNextLevel ) == DD_OK )
765                        {
766                                GETLEVEL(face, mipLevel)->bind(ddsNextLevel, mFormat);
767                                // Release the current level and get the next one, incrementing the mip depth.
768                                ddsMipLevel->Release();
769                                ddsMipLevel = ddsNextLevel;
770                                mipLevel++;
771                        }
772
773                        // Release the last mip-map level surface.
774                        ddsMipLevel->Release();
775                        // Release face reference
776                        pCubeFace->Release();
777                }
778
779                // Set autogeneration of mipmaps for each face of the texture, if it is enabled
780                if(mNumMipmaps>0 && (mUsage & TU_AUTOMIPMAP))
781                {
782                        for(size_t face=0; face<getNumFaces(); ++face)
783                        {
784                                GETLEVEL(face, 0)->_setMipmapping(true);
785                        }
786                }
787        }
788        #undef GETLEVEL
789}
Note: See TracBrowser for help on using the repository browser.