1 /***********************************************************************
2 created: Mon Feb 9 2009
3 author: Paul D Turner
4 *************************************************************************/
5 /***************************************************************************
6 * Copyright (C) 2004 - 2011 Paul D Turner & The CEGUI Development Team
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining
9 * a copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sublicense, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be
17 * included in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
22 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 ***************************************************************************/
27 #include <d3dx9.h>
28 #include "CEGUI/RendererModules/Direct3D9/Texture.h"
29 #include "CEGUI/Exceptions.h"
30 #include "CEGUI/System.h"
31 #include "CEGUI/ImageCodec.h"
32
33 // Start of CEGUI namespace section
34 namespace CEGUI
35 {
36 //----------------------------------------------------------------------------//
37 // helper to convert cegui pixel format enum to equivalent D3D format.
toD3DPixelFormat(const Texture::PixelFormat fmt)38 static D3DFORMAT toD3DPixelFormat(const Texture::PixelFormat fmt)
39 {
40 switch (fmt)
41 {
42 case Texture::PF_RGBA: return D3DFMT_A8R8G8B8;
43 case Texture::PF_RGB: return D3DFMT_X8R8G8B8;
44 case Texture::PF_RGB_565: return D3DFMT_R5G6B5;
45 case Texture::PF_RGBA_4444: return D3DFMT_A4R4G4B4;
46 case Texture::PF_RGBA_DXT1: return D3DFMT_DXT1;
47 case Texture::PF_RGBA_DXT3: return D3DFMT_DXT3;
48 case Texture::PF_RGBA_DXT5: return D3DFMT_DXT5;
49 default: return D3DFMT_UNKNOWN;
50 }
51 }
52
53 //----------------------------------------------------------------------------//
54 // helper function to return byte width of given pixel width in given format
calculateDataWidth(const size_t width,Texture::PixelFormat fmt)55 static size_t calculateDataWidth(const size_t width, Texture::PixelFormat fmt)
56 {
57 switch (fmt)
58 {
59 case Texture::PF_RGBA:
60 return width * 4;
61
62 case Texture::PF_RGB:
63 return width * 3;
64
65 case Texture::PF_RGB_565:
66 case Texture::PF_RGBA_4444:
67 return width * 2;
68
69 case Texture::PF_RGBA_DXT1:
70 return ((width + 3) / 4) * 8;
71
72 case Texture::PF_RGBA_DXT3:
73 case Texture::PF_RGBA_DXT5:
74 return ((width + 3) / 4) * 16;
75
76 default:
77 return 0;
78 }
79 }
80
81 //----------------------------------------------------------------------------//
82 // Helper utility function that copies an RGB buffer into a region of a second
83 // buffer as BGR data values (i.e swap red and blue)
blitRGBToBGRSurface(const uchar * src,uchar * dst,const Sizef & sz)84 static void blitRGBToBGRSurface(const uchar* src, uchar* dst, const Sizef& sz)
85 {
86 for (uint i = 0; i < sz.d_height; ++i)
87 {
88 for (uint j = 0; j < sz.d_width; ++j)
89 {
90 *dst++ = src[2];
91 *dst++ = src[1];
92 *dst++ = src[0];
93 src += 3;
94 }
95 }
96 }
97
98 //----------------------------------------------------------------------------//
99 // Helper utility function that copies an RGBA buffer into a region of a second
100 // buffer as D3DCOLOR data values
blitRGBAToD3DCOLORSurface(const uint32 * src,uint32 * dst,const Sizef & sz,size_t dest_pitch)101 static void blitRGBAToD3DCOLORSurface(const uint32* src, uint32* dst,
102 const Sizef& sz, size_t dest_pitch)
103 {
104 for (uint i = 0; i < sz.d_height; ++i)
105 {
106 for (uint j = 0; j < sz.d_width; ++j)
107 {
108 const uint32 pixel = src[j];
109 const uint32 tmp = pixel & 0x00FF00FF;
110 dst[j] = (pixel & 0xFF00FF00) | (tmp << 16) | (tmp >> 16);
111 }
112
113 dst += dest_pitch / sizeof(uint32);
114 src += static_cast<uint32>(sz.d_width);
115 }
116 }
117
118 //----------------------------------------------------------------------------//
119 // Helper utility function that copies a region of a buffer containing D3DCOLOR
120 // values into a second buffer as RGBA values.
blitD3DCOLORSurfaceToRGBA(const uint32 * src,uint32 * dst,const Sizef & sz,size_t source_pitch)121 static void blitD3DCOLORSurfaceToRGBA(const uint32* src, uint32* dst,
122 const Sizef& sz, size_t source_pitch)
123 {
124 for (uint i = 0; i < sz.d_height; ++i)
125 {
126 for (uint j = 0; j < sz.d_width; ++j)
127 {
128 const uint32 pixel = src[j];
129 const uint32 tmp = pixel & 0x00FF00FF;
130 dst[j] = (pixel & 0xFF00FF00) | (tmp << 16) | (tmp >> 16);
131 }
132
133 src += source_pitch / sizeof(uint32);
134 dst += static_cast<uint32>(sz.d_width);
135 }
136 }
137
138 //----------------------------------------------------------------------------//
139 // Helper class to wrap an image pixel buffer. The main purpose of this is
140 // to prevent the need to have lots of conditionals and raw pointers that need
141 // managing in places where exceptions are used (i.e this prevents leaks while
142 // keeping code clean).
143 class PixelBuffer
144 {
145 const uchar* d_sourceBuffer;
146 uchar* d_workBuffer;
147 size_t d_pitch;
148
149 public:
150 //------------------------------------------------------------------------//
PixelBuffer(const void * data,const Sizef & size,Texture::PixelFormat format)151 PixelBuffer(const void* data, const Sizef& size, Texture::PixelFormat format) :
152 d_sourceBuffer(static_cast<const uchar*>(data)),
153 d_workBuffer(0),
154 d_pitch(calculateDataWidth(static_cast<size_t>(size.d_width), format))
155 {
156 if (format != Texture::PF_RGBA && format != Texture::PF_RGB)
157 return;
158
159 d_workBuffer = new uchar[d_pitch * static_cast<size_t>(size.d_height)];
160
161 if (format == Texture::PF_RGBA)
162 blitRGBAToD3DCOLORSurface(reinterpret_cast<const uint32*>(d_sourceBuffer),
163 reinterpret_cast<uint32*>(d_workBuffer),
164 size, d_pitch);
165 else
166 blitRGBToBGRSurface(d_sourceBuffer, d_workBuffer, size);
167 }
168
169 //------------------------------------------------------------------------//
~PixelBuffer()170 ~PixelBuffer()
171 {
172 delete[] d_workBuffer;
173 }
174
175 //------------------------------------------------------------------------//
getPitch() const176 size_t getPitch() const
177 {
178 return d_pitch;
179 }
180
181 //------------------------------------------------------------------------//
getPixelDataPtr() const182 const uchar* getPixelDataPtr() const
183 {
184 return d_workBuffer ? d_workBuffer : d_sourceBuffer;
185 }
186
187 //------------------------------------------------------------------------//
188 };
189
190 //----------------------------------------------------------------------------//
191 // Internal helper class to wrap the internal handling needed to copy data to
192 // and from a D3D9 texture.
193 class D3DSurfaceBlitter
194 {
195 public:
196 //------------------------------------------------------------------------//
D3DSurfaceBlitter(LPDIRECT3DDEVICE9 d3d_device,LPDIRECT3DTEXTURE9 tex)197 D3DSurfaceBlitter(LPDIRECT3DDEVICE9 d3d_device, LPDIRECT3DTEXTURE9 tex) :
198 d_device(d3d_device),
199 d_texture(tex),
200 d_renderTarget(0),
201 d_offscreen(0)
202 {
203 populateTextureSurfaceDescription();
204 }
205
206 //------------------------------------------------------------------------//
~D3DSurfaceBlitter()207 ~D3DSurfaceBlitter()
208 {
209 cleanupSurfaces();
210 }
211
212 //------------------------------------------------------------------------//
blitFromMemory(const uint32 * source,const Rectf & area)213 void blitFromMemory(const uint32* source, const Rectf& area)
214 {
215 if (!d_texture)
216 return;
217
218 RECT target_rect = {static_cast<LONG>(area.left()), static_cast<LONG>(area.top()),
219 static_cast<LONG>(area.right()), static_cast<LONG>(area.bottom())};
220
221 lockRect(&target_rect);
222
223 blitRGBAToD3DCOLORSurface(
224 source, static_cast<uint32*>(d_lockedRect.pBits),
225 area.getSize(), d_lockedRect.Pitch);
226
227 unlockRect(&target_rect, true);
228 }
229
230 //------------------------------------------------------------------------//
blitToMemory(uint32 * dest)231 void blitToMemory(uint32* dest)
232 {
233 if (!d_texture)
234 return;
235
236 lockRect(0, true);
237
238 blitD3DCOLORSurfaceToRGBA(
239 static_cast<uint32*>(d_lockedRect.pBits), dest,
240 Sizef(static_cast<float>(d_surfDesc.Width), static_cast<float>(d_surfDesc.Height)),
241 d_lockedRect.Pitch);
242
243 unlockRect();
244 }
245
246 //------------------------------------------------------------------------//
isRenderTarget() const247 bool isRenderTarget() const
248 {
249 return d_surfDesc.Usage == D3DUSAGE_RENDERTARGET;
250 }
251
252 //------------------------------------------------------------------------//
253
254 private:
255 LPDIRECT3DDEVICE9 d_device;
256 LPDIRECT3DTEXTURE9 d_texture;
257 LPDIRECT3DSURFACE9 d_renderTarget;
258 LPDIRECT3DSURFACE9 d_offscreen;
259 D3DSURFACE_DESC d_surfDesc;
260 D3DLOCKED_RECT d_lockedRect;
261 RECT d_fullArea;
262
263 //------------------------------------------------------------------------//
initialiseSurfaces()264 void initialiseSurfaces()
265 {
266 if (!d_offscreen)
267 createOffscreenSurface();
268
269 if (!d_renderTarget)
270 getTextureSurface();
271 }
272
273 //------------------------------------------------------------------------//
cleanupSurfaces()274 void cleanupSurfaces()
275 {
276 if (d_renderTarget)
277 {
278 d_renderTarget->Release();
279 d_renderTarget = 0;
280 }
281
282 if (d_offscreen)
283 {
284 d_offscreen->Release();
285 d_offscreen = 0;
286 }
287 }
288
289 //------------------------------------------------------------------------//
lockRect(RECT * area=0,bool for_reading=false)290 void lockRect(RECT* area = 0, bool for_reading = false)
291 {
292 if (isRenderTarget())
293 {
294 initialiseSurfaces();
295
296 if (for_reading)
297 getRenderTargetData();
298
299 lockSurfaceRect(area);
300 }
301 else
302 {
303 lockTextureRect(area);
304 }
305 }
306
307 //------------------------------------------------------------------------//
unlockRect(RECT * area=0,bool needs_update=false)308 void unlockRect(RECT* area = 0, bool needs_update = false)
309 {
310 if (isRenderTarget())
311 {
312 d_offscreen->UnlockRect();
313
314 if (needs_update)
315 updateRenderTarget(area);
316 }
317 else
318 d_texture->UnlockRect(0);
319 }
320
321 //------------------------------------------------------------------------//
populateTextureSurfaceDescription()322 void populateTextureSurfaceDescription()
323 {
324 if (FAILED(d_texture->GetLevelDesc(0, &d_surfDesc)))
325 CEGUI_THROW(RendererException(
326 "IDirect3DTexture9::GetLevelDesc failed."));
327
328 d_fullArea.left = 0;
329 d_fullArea.top = 0;
330 d_fullArea.right = d_surfDesc.Width;
331 d_fullArea.bottom = d_surfDesc.Height;
332 }
333
334 //------------------------------------------------------------------------//
createOffscreenSurface()335 void createOffscreenSurface()
336 {
337 if (FAILED(d_device->CreateOffscreenPlainSurface(
338 d_surfDesc.Width, d_surfDesc.Height, d_surfDesc.Format,
339 D3DPOOL_SYSTEMMEM, &d_offscreen, 0)))
340 {
341 CEGUI_THROW(RendererException(
342 "IDirect3DDevice9::CreateOffscreenPlainSurface failed."));
343 }
344 }
345
346 //------------------------------------------------------------------------//
getTextureSurface()347 void getTextureSurface()
348 {
349 if (FAILED(d_texture->GetSurfaceLevel(0, &d_renderTarget)))
350 CEGUI_THROW(RendererException(
351 "IDirect3DTexture9::GetSurfaceLevel failed."));
352 }
353
354 //------------------------------------------------------------------------//
lockSurfaceRect(RECT * area)355 void lockSurfaceRect(RECT* area)
356 {
357 if (FAILED(d_offscreen->LockRect(&d_lockedRect, area, 0)))
358 CEGUI_THROW(RendererException(
359 "IDirect3DSurface9::LockRect failed."));
360 }
361
362 //------------------------------------------------------------------------//
lockTextureRect(RECT * area)363 void lockTextureRect(RECT* area)
364 {
365 if (FAILED(d_texture->LockRect(0, &d_lockedRect, area, 0)))
366 CEGUI_THROW(RendererException(
367 "IDirect3DTexture9::LockRect failed."));
368 }
369
370 //------------------------------------------------------------------------//
updateRenderTarget(RECT * area)371 void updateRenderTarget(RECT* area)
372 {
373 POINT pt = {area ? area->left : 0, area ? area->top : 0};
374 if (FAILED(d_device->UpdateSurface(d_offscreen,
375 area ? area : &d_fullArea,
376 d_renderTarget, &pt)))
377 {
378 CEGUI_THROW(RendererException(
379 "IDirect3DDevice9::UpdateSurface failed."));
380 }
381 }
382
383 //------------------------------------------------------------------------//
getRenderTargetData()384 void getRenderTargetData()
385 {
386 if (FAILED(d_device->GetRenderTargetData(d_renderTarget, d_offscreen)))
387 CEGUI_THROW(RendererException(
388 "IDirect3DDevice9::GetRenderTargetData failed."));
389 }
390
391 //------------------------------------------------------------------------//
392 };
393
394 //----------------------------------------------------------------------------//
Direct3D9Texture(Direct3D9Renderer & owner,const String & name)395 Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
396 const String& name) :
397 d_owner(owner),
398 d_texture(0),
399 d_size(0, 0),
400 d_dataSize(0, 0),
401 d_texelScaling(0, 0),
402 d_savedSurfaceDescValid(false),
403 d_name(name)
404 {
405 }
406
407 //----------------------------------------------------------------------------//
Direct3D9Texture(Direct3D9Renderer & owner,const String & name,const String & filename,const String & resourceGroup)408 Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
409 const String& name,
410 const String& filename,
411 const String& resourceGroup) :
412 d_owner(owner),
413 d_texture(0),
414 d_size(0, 0),
415 d_dataSize(0, 0),
416 d_texelScaling(0, 0),
417 d_savedSurfaceDescValid(false),
418 d_name(name)
419 {
420 loadFromFile(filename, resourceGroup);
421 }
422
423 //----------------------------------------------------------------------------//
Direct3D9Texture(Direct3D9Renderer & owner,const String & name,const Sizef & sz)424 Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
425 const String& name, const Sizef& sz) :
426 d_owner(owner),
427 d_texture(0),
428 d_size(0, 0),
429 d_dataSize(sz),
430 d_texelScaling(0, 0),
431 d_savedSurfaceDescValid(false),
432 d_name(name)
433 {
434 createDirect3D9Texture(sz, D3DFMT_A8R8G8B8);
435 }
436
437 //----------------------------------------------------------------------------//
Direct3D9Texture(Direct3D9Renderer & owner,const String & name,LPDIRECT3DTEXTURE9 tex)438 Direct3D9Texture::Direct3D9Texture(Direct3D9Renderer& owner,
439 const String& name,
440 LPDIRECT3DTEXTURE9 tex) :
441 d_owner(owner),
442 d_texture(0),
443 d_size(0, 0),
444 d_dataSize(0, 0),
445 d_texelScaling(0, 0),
446 d_savedSurfaceDescValid(false),
447 d_name(name)
448 {
449 setDirect3D9Texture(tex);
450 }
451
452 //----------------------------------------------------------------------------//
~Direct3D9Texture()453 Direct3D9Texture::~Direct3D9Texture()
454 {
455 cleanupDirect3D9Texture();
456 }
457
458 //----------------------------------------------------------------------------//
setDirect3D9Texture(LPDIRECT3DTEXTURE9 tex)459 void Direct3D9Texture::setDirect3D9Texture(LPDIRECT3DTEXTURE9 tex)
460 {
461 if (d_texture != tex)
462 {
463 cleanupDirect3D9Texture();
464 d_dataSize.d_width = d_dataSize.d_height = 0;
465
466 d_texture = tex;
467 if (d_texture)
468 d_texture->AddRef();
469 }
470
471 updateTextureSize();
472 d_dataSize = d_size;
473 updateCachedScaleValues();
474 }
475
476 //----------------------------------------------------------------------------//
getDirect3D9Texture() const477 LPDIRECT3DTEXTURE9 Direct3D9Texture::getDirect3D9Texture() const
478 {
479 return d_texture;
480 }
481
482 //----------------------------------------------------------------------------//
getName() const483 const String& Direct3D9Texture::getName() const
484 {
485 return d_name;
486 }
487
488 //----------------------------------------------------------------------------//
getSize() const489 const Sizef& Direct3D9Texture::getSize() const
490 {
491 return d_size;
492 }
493
494 //----------------------------------------------------------------------------//
getOriginalDataSize() const495 const Sizef& Direct3D9Texture::getOriginalDataSize() const
496 {
497 return d_dataSize;
498 }
499
500 //----------------------------------------------------------------------------//
getTexelScaling() const501 const Vector2f& Direct3D9Texture::getTexelScaling() const
502 {
503 return d_texelScaling;
504 }
505
506 //----------------------------------------------------------------------------//
loadFromFile(const String & filename,const String & resourceGroup)507 void Direct3D9Texture::loadFromFile(const String& filename,
508 const String& resourceGroup)
509 {
510 // get and check existence of CEGUI::System object
511 System* sys = System::getSingletonPtr();
512 if (!sys)
513 CEGUI_THROW(RendererException(
514 "CEGUI::System object has not been created!"));
515
516 // load file to memory via resource provider
517 RawDataContainer texFile;
518 sys->getResourceProvider()->loadRawDataContainer(filename, texFile,
519 resourceGroup);
520
521 Texture* res = sys->getImageCodec().load(texFile, this);
522
523 // unload file data buffer
524 sys->getResourceProvider()->unloadRawDataContainer(texFile);
525
526 if (!res)
527 // It's an error
528 CEGUI_THROW(RendererException(
529 sys->getImageCodec().getIdentifierString() +
530 " failed to load image '" + filename + "'."));
531 }
532
533 //----------------------------------------------------------------------------//
loadFromMemory(const void * buffer,const Sizef & buffer_size,PixelFormat pixel_format)534 void Direct3D9Texture::loadFromMemory(const void* buffer,
535 const Sizef& buffer_size,
536 PixelFormat pixel_format)
537 {
538 if (!isPixelFormatSupported(pixel_format))
539 CEGUI_THROW(InvalidRequestException(
540 "Data was supplied in an unsupported pixel format."));
541
542 const D3DFORMAT pixfmt = toD3DPixelFormat(pixel_format);
543 createDirect3D9Texture(buffer_size, pixfmt);
544
545 LPDIRECT3DSURFACE9 surface = getTextureSurface();
546 const PixelBuffer pixel_buffer(buffer, buffer_size, pixel_format);
547
548 const RECT src_rect = { 0, 0,
549 static_cast<LONG>(buffer_size.d_width),
550 static_cast<LONG>(buffer_size.d_height) };
551
552 HRESULT hr = D3DXLoadSurfaceFromMemory(
553 surface, 0, 0, pixel_buffer.getPixelDataPtr(),
554 pixfmt == D3DFMT_X8R8G8B8 ? D3DFMT_R8G8B8 : pixfmt,
555 pixel_buffer.getPitch(), 0, &src_rect, D3DX_FILTER_NONE, 0);
556
557 surface->Release();
558
559 if (FAILED(hr))
560 CEGUI_THROW(RendererException(
561 "D3DXLoadSurfaceFromMemory failed."));
562 }
563
564 //----------------------------------------------------------------------------//
createDirect3D9Texture(const Sizef sz,D3DFORMAT format)565 void Direct3D9Texture::createDirect3D9Texture(const Sizef sz, D3DFORMAT format)
566 {
567 cleanupDirect3D9Texture();
568
569 const Sizef tex_sz(d_owner.getAdjustedSize(sz));
570
571 HRESULT hr = D3DXCreateTexture(d_owner.getDevice(),
572 static_cast<UINT>(tex_sz.d_width),
573 static_cast<UINT>(tex_sz.d_height),
574 1, 0, format, D3DPOOL_MANAGED, &d_texture);
575
576 if (FAILED(hr))
577 CEGUI_THROW(RendererException("D3DXCreateTexture failed."));
578
579 d_dataSize = sz;
580 updateTextureSize();
581 updateCachedScaleValues();
582 }
583
584 //----------------------------------------------------------------------------//
getTextureSurface() const585 IDirect3DSurface9* Direct3D9Texture::getTextureSurface() const
586 {
587 LPDIRECT3DSURFACE9 surface;
588 HRESULT hr = d_texture->GetSurfaceLevel(0, &surface);
589
590 if (FAILED(hr))
591 CEGUI_THROW(RendererException(
592 "IDirect3DTexture9::GetSurfaceLevel failed."));
593
594 return surface;
595 }
596
597 //----------------------------------------------------------------------------//
blitFromMemory(const void * sourceData,const Rectf & area)598 void Direct3D9Texture::blitFromMemory(const void* sourceData, const Rectf& area)
599 {
600 D3DSurfaceBlitter blitter(d_owner.getDevice(), d_texture);
601 blitter.blitFromMemory(static_cast<const uint32*>(sourceData), area);
602 }
603
604 //----------------------------------------------------------------------------//
blitToMemory(void * targetData)605 void Direct3D9Texture::blitToMemory(void* targetData)
606 {
607 D3DSurfaceBlitter blitter(d_owner.getDevice(), d_texture);
608 blitter.blitToMemory(static_cast<uint32*>(targetData));
609 }
610
611 //----------------------------------------------------------------------------//
cleanupDirect3D9Texture()612 void Direct3D9Texture::cleanupDirect3D9Texture()
613 {
614 if (d_texture)
615 {
616 d_texture->Release();
617 d_texture = 0;
618 }
619 }
620
621 //----------------------------------------------------------------------------//
updateCachedScaleValues()622 void Direct3D9Texture::updateCachedScaleValues()
623 {
624 //
625 // calculate what to use for x scale
626 //
627 const float orgW = d_dataSize.d_width;
628 const float texW = d_size.d_width;
629
630 // if texture and original data width are the same, scale is based
631 // on the original size.
632 // if texture is wider (and source data was not stretched), scale
633 // is based on the size of the resulting texture.
634 d_texelScaling.d_x = 1.0f / ((orgW == texW) ? orgW : texW);
635
636 //
637 // calculate what to use for y scale
638 //
639 const float orgH = d_dataSize.d_height;
640 const float texH = d_size.d_height;
641
642 // if texture and original data height are the same, scale is based
643 // on the original size.
644 // if texture is taller (and source data was not stretched), scale
645 // is based on the size of the resulting texture.
646 d_texelScaling.d_y = 1.0f / ((orgH == texH) ? orgH : texH);
647 }
648
649 //----------------------------------------------------------------------------//
updateTextureSize()650 void Direct3D9Texture::updateTextureSize()
651 {
652 D3DSURFACE_DESC surfDesc;
653
654 // obtain details of the size of the texture
655 if (d_texture && SUCCEEDED(d_texture->GetLevelDesc(0, &surfDesc)))
656 {
657 d_size.d_width = static_cast<float>(surfDesc.Width);
658 d_size.d_height = static_cast<float>(surfDesc.Height);
659 }
660 // use the original size if query failed.
661 // NB: This should probably be an exception.
662 else
663 d_size = d_dataSize;
664 }
665
666 //----------------------------------------------------------------------------//
setOriginalDataSize(const Sizef & sz)667 void Direct3D9Texture::setOriginalDataSize(const Sizef& sz)
668 {
669 d_dataSize = sz;
670 updateCachedScaleValues();
671 }
672
673 //----------------------------------------------------------------------------//
preD3DReset()674 void Direct3D9Texture::preD3DReset()
675 {
676 // if already saved surface info, or we have no texture, do nothing
677 if (d_savedSurfaceDescValid || !d_texture)
678 return;
679
680 // get info about our texture
681 d_texture->GetLevelDesc(0, &d_savedSurfaceDesc);
682
683 // if texture is managed, we have nothing more to do
684 if (d_savedSurfaceDesc.Pool == D3DPOOL_MANAGED)
685 return;
686
687 // otherwise release texture.
688 d_texture->Release();
689 d_texture = 0;
690 d_savedSurfaceDescValid = true;
691 }
692
693 //----------------------------------------------------------------------------//
postD3DReset()694 void Direct3D9Texture::postD3DReset()
695 {
696 // if texture has no saved surface info, we do nothing.
697 if (!d_savedSurfaceDescValid)
698 return;
699
700 // otherwise, create a new texture using saved details.
701 d_owner.getDevice()->
702 CreateTexture(d_savedSurfaceDesc.Width,
703 d_savedSurfaceDesc.Height,
704 1, d_savedSurfaceDesc.Usage, d_savedSurfaceDesc.Format,
705 d_savedSurfaceDesc.Pool, &d_texture, 0);
706
707 d_savedSurfaceDescValid = false;
708 }
709
710 //----------------------------------------------------------------------------//
isPixelFormatSupported(const PixelFormat fmt) const711 bool Direct3D9Texture::isPixelFormatSupported(const PixelFormat fmt) const
712 {
713 D3DDEVICE_CREATION_PARAMETERS dev_params;
714 d_owner.getDevice()->GetCreationParameters(&dev_params);
715
716 LPDIRECT3D9 d3d;
717 d_owner.getDevice()->GetDirect3D(&d3d);
718
719 D3DDISPLAYMODE dmode;
720 d3d->GetAdapterDisplayMode(dev_params.AdapterOrdinal, &dmode);
721
722 const D3DFORMAT d3d_format = toD3DPixelFormat(fmt);
723
724 if (d3d_format == D3DFMT_UNKNOWN)
725 return false;
726
727 return SUCCEEDED(d3d->CheckDeviceFormat(
728 dev_params.AdapterOrdinal, dev_params.DeviceType,
729 dmode.Format, 0, D3DRTYPE_TEXTURE, d3d_format));
730 }
731
732 //----------------------------------------------------------------------------//
733
734 } // End of CEGUI namespace section
735