diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CD3D8Texture.cpp | 659 |
1 files changed, 659 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CD3D8Texture.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CD3D8Texture.cpp new file mode 100644 index 0000000..990efbe --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/CD3D8Texture.cpp | |||
@@ -0,0 +1,659 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | ||
2 | // This file is part of the "Irrlicht Engine". | ||
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | ||
4 | |||
5 | #include "IrrCompileConfig.h" | ||
6 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ | ||
7 | |||
8 | #define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE | ||
9 | #include "CD3D8Texture.h" | ||
10 | #include "CD3D8Driver.h" | ||
11 | #include "os.h" | ||
12 | |||
13 | |||
14 | #ifndef _IRR_COMPILE_WITH_DIRECT3D_9_ | ||
15 | // The D3DXFilterTexture function seems to get linked wrong when | ||
16 | // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. | ||
17 | // So mipmapgeneration is replaced with my own bad generation in d3d 8 when | ||
18 | // compiling with both D3D 8 and 9. | ||
19 | //#define _IRR_USE_D3DXFilterTexture_ | ||
20 | #endif // _IRR_COMPILE_WITH_DIRECT3D_9_ | ||
21 | |||
22 | #include <d3dx8tex.h> | ||
23 | |||
24 | #ifdef _IRR_USE_D3DXFilterTexture_ | ||
25 | #pragma comment (lib, "d3dx8.lib") | ||
26 | #endif // _IRR_USE_D3DXFilterTexture_ | ||
27 | |||
28 | namespace irr | ||
29 | { | ||
30 | namespace video | ||
31 | { | ||
32 | |||
33 | //! rendertarget constructor | ||
34 | CD3D8Texture::CD3D8Texture(CD3D8Driver* driver, const core::dimension2d<u32>& size, const io::path& name) | ||
35 | : ITexture(name), Texture(0), RTTSurface(0), Driver(driver), | ||
36 | TextureSize(size), ImageSize(size), Pitch(0), | ||
37 | HasMipMaps(false), IsRenderTarget(true) | ||
38 | { | ||
39 | #ifdef _DEBUG | ||
40 | setDebugName("CD3D8Texture"); | ||
41 | #endif | ||
42 | |||
43 | Device=driver->getExposedVideoData().D3D8.D3DDev8; | ||
44 | if (Device) | ||
45 | Device->AddRef(); | ||
46 | |||
47 | createRenderTarget(); | ||
48 | } | ||
49 | |||
50 | |||
51 | //! constructor | ||
52 | CD3D8Texture::CD3D8Texture(IImage* image, CD3D8Driver* driver, | ||
53 | u32 flags, const io::path& name, void* mipmapData) | ||
54 | : ITexture(name), Texture(0), RTTSurface(0), Driver(driver), | ||
55 | TextureSize(0,0), ImageSize(0,0), Pitch(0), | ||
56 | HasMipMaps(false), IsRenderTarget(false) | ||
57 | { | ||
58 | #ifdef _DEBUG | ||
59 | setDebugName("CD3D8Texture"); | ||
60 | #endif | ||
61 | |||
62 | HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); | ||
63 | |||
64 | Device=driver->getExposedVideoData().D3D8.D3DDev8; | ||
65 | if (Device) | ||
66 | Device->AddRef(); | ||
67 | |||
68 | if (image) | ||
69 | { | ||
70 | if (createTexture(flags, image)) | ||
71 | { | ||
72 | if (copyTexture(image)) | ||
73 | { | ||
74 | regenerateMipMapLevels(mipmapData); | ||
75 | } | ||
76 | } | ||
77 | else | ||
78 | os::Printer::log("Could not create DIRECT3D8 Texture.", ELL_WARNING); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | |||
83 | //! destructor | ||
84 | CD3D8Texture::~CD3D8Texture() | ||
85 | { | ||
86 | if (Texture) | ||
87 | Texture->Release(); | ||
88 | |||
89 | if (RTTSurface) | ||
90 | RTTSurface->Release(); | ||
91 | |||
92 | if (Device) | ||
93 | Device->Release(); | ||
94 | } | ||
95 | |||
96 | |||
97 | //! creates the hardware texture | ||
98 | bool CD3D8Texture::createTexture(u32 flags, video::IImage* image) | ||
99 | { | ||
100 | ImageSize = image->getDimension(); | ||
101 | |||
102 | core::dimension2d<u32> optSize = ImageSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); | ||
103 | |||
104 | D3DFORMAT format = D3DFMT_A1R5G5B5; | ||
105 | switch(getTextureFormatFromFlags(flags)) | ||
106 | { | ||
107 | case ETCF_ALWAYS_16_BIT: | ||
108 | format = D3DFMT_A1R5G5B5; break; | ||
109 | case ETCF_ALWAYS_32_BIT: | ||
110 | format = D3DFMT_A8R8G8B8; break; | ||
111 | case ETCF_OPTIMIZED_FOR_QUALITY: | ||
112 | { | ||
113 | switch(image->getColorFormat()) | ||
114 | { | ||
115 | case ECF_R8G8B8: | ||
116 | case ECF_A8R8G8B8: | ||
117 | format = D3DFMT_A8R8G8B8; break; | ||
118 | case ECF_A1R5G5B5: | ||
119 | case ECF_R5G6B5: | ||
120 | format = D3DFMT_A1R5G5B5; break; | ||
121 | } | ||
122 | } | ||
123 | break; | ||
124 | case ETCF_OPTIMIZED_FOR_SPEED: | ||
125 | format = D3DFMT_A1R5G5B5; break; | ||
126 | } | ||
127 | |||
128 | if (Driver->getTextureCreationFlag(video::ETCF_NO_ALPHA_CHANNEL)) | ||
129 | { | ||
130 | if (format == D3DFMT_A8R8G8B8) | ||
131 | |||
132 | #ifdef _IRR_XBOX_PLATFORM_ | ||
133 | format = D3DFMT_X8R8G8B8; | ||
134 | #else | ||
135 | format = D3DFMT_R8G8B8; | ||
136 | #endif | ||
137 | |||
138 | else if (format == D3DFMT_A1R5G5B5) | ||
139 | format = D3DFMT_R5G6B5; | ||
140 | } | ||
141 | |||
142 | const bool mipmaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS); | ||
143 | |||
144 | HRESULT hr = Device->CreateTexture(optSize.Width, optSize.Height, | ||
145 | mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) | ||
146 | 0, format, D3DPOOL_MANAGED, &Texture); | ||
147 | |||
148 | if (FAILED(hr)) | ||
149 | { | ||
150 | // try brute force 16 bit | ||
151 | if (format == D3DFMT_A8R8G8B8) | ||
152 | format = D3DFMT_A1R5G5B5; | ||
153 | #ifdef _IRR_XBOX_PLATFORM_ | ||
154 | else if (format == D3DFMT_X8R8G8B8) | ||
155 | format = D3DFMT_R5G6B5; | ||
156 | #else | ||
157 | else if (format == D3DFMT_R8G8B8) | ||
158 | format = D3DFMT_R5G6B5; | ||
159 | #endif | ||
160 | else | ||
161 | return false; | ||
162 | |||
163 | hr = Device->CreateTexture(optSize.Width, optSize.Height, | ||
164 | mipmaps ? 0 : 1, // number of mipmaplevels (0 = automatic all) | ||
165 | 0, format, D3DPOOL_MANAGED, &Texture); | ||
166 | } | ||
167 | |||
168 | ColorFormat = getColorFormatFromD3DFormat(format); | ||
169 | return (SUCCEEDED(hr)); | ||
170 | } | ||
171 | |||
172 | |||
173 | //! copies the image to the texture | ||
174 | bool CD3D8Texture::copyTexture(video::IImage* image) | ||
175 | { | ||
176 | if (Texture && image) | ||
177 | { | ||
178 | D3DSURFACE_DESC desc; | ||
179 | Texture->GetLevelDesc(0, &desc); | ||
180 | |||
181 | TextureSize.Width = desc.Width; | ||
182 | TextureSize.Height = desc.Height; | ||
183 | |||
184 | D3DLOCKED_RECT rect; | ||
185 | HRESULT hr = Texture->LockRect(0, &rect, 0, 0); | ||
186 | if (FAILED(hr)) | ||
187 | { | ||
188 | os::Printer::log("Could not lock D3D8 Texture.", ELL_ERROR); | ||
189 | return false; | ||
190 | } | ||
191 | |||
192 | Pitch = rect.Pitch; | ||
193 | image->copyToScaling(rect.pBits, TextureSize.Width, TextureSize.Height, ColorFormat, Pitch); | ||
194 | |||
195 | hr = Texture->UnlockRect(0); | ||
196 | if (FAILED(hr)) | ||
197 | { | ||
198 | os::Printer::log("Could not unlock D3D8 Texture.", ELL_ERROR); | ||
199 | return false; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | return true; | ||
204 | } | ||
205 | |||
206 | |||
207 | //! lock function | ||
208 | void* CD3D8Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) | ||
209 | { | ||
210 | if (!Texture) | ||
211 | return 0; | ||
212 | |||
213 | MipLevelLocked=mipmapLevel; | ||
214 | HRESULT hr; | ||
215 | D3DLOCKED_RECT rect; | ||
216 | if(!IsRenderTarget) | ||
217 | { | ||
218 | hr = Texture->LockRect(mipmapLevel, &rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); | ||
219 | if (FAILED(hr)) | ||
220 | { | ||
221 | os::Printer::log("Could not lock DIRECT3D9 Texture.", ELL_ERROR); | ||
222 | return 0; | ||
223 | } | ||
224 | } | ||
225 | else | ||
226 | { | ||
227 | if (!RTTSurface) | ||
228 | { | ||
229 | // Make RTT surface large enough for all miplevels (including 0) | ||
230 | D3DSURFACE_DESC desc; | ||
231 | Texture->GetLevelDesc(0, &desc); | ||
232 | hr = Device->CreateImageSurface(desc.Width, desc.Height, desc.Format, &RTTSurface); | ||
233 | if (FAILED(hr)) | ||
234 | { | ||
235 | os::Printer::log("Could not lock DIRECT3D8 Texture.", ELL_ERROR); | ||
236 | return 0; | ||
237 | } | ||
238 | } | ||
239 | |||
240 | IDirect3DSurface8 *surface = 0; | ||
241 | hr = Texture->GetSurfaceLevel(mipmapLevel, &surface); | ||
242 | if (FAILED(hr)) | ||
243 | { | ||
244 | os::Printer::log("Could not lock DIRECT3D8 Texture.", "Could not get surface.", ELL_ERROR); | ||
245 | return 0; | ||
246 | } | ||
247 | hr = Device->CopyRects(surface, 0, 0, RTTSurface, 0); | ||
248 | surface->Release(); | ||
249 | if(FAILED(hr)) | ||
250 | { | ||
251 | os::Printer::log("Could not lock DIRECT3D8 Texture.", "Data copy failed.", ELL_ERROR); | ||
252 | return 0; | ||
253 | } | ||
254 | hr = RTTSurface->LockRect(&rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0); | ||
255 | if(FAILED(hr)) | ||
256 | { | ||
257 | os::Printer::log("Could not lock DIRECT3D8 Texture.", "LockRect failed.", ELL_ERROR); | ||
258 | return 0; | ||
259 | } | ||
260 | } | ||
261 | return rect.pBits; | ||
262 | } | ||
263 | |||
264 | |||
265 | //! unlock function | ||
266 | void CD3D8Texture::unlock() | ||
267 | { | ||
268 | if (!Texture) | ||
269 | return; | ||
270 | |||
271 | if (!IsRenderTarget) | ||
272 | Texture->UnlockRect(MipLevelLocked); | ||
273 | else if (RTTSurface) | ||
274 | RTTSurface->UnlockRect(); | ||
275 | } | ||
276 | |||
277 | |||
278 | //! Returns original size of the texture. | ||
279 | const core::dimension2d<u32>& CD3D8Texture::getOriginalSize() const | ||
280 | { | ||
281 | return ImageSize; | ||
282 | } | ||
283 | |||
284 | |||
285 | //! Returns (=size) of the texture. | ||
286 | const core::dimension2d<u32>& CD3D8Texture::getSize() const | ||
287 | { | ||
288 | return TextureSize; | ||
289 | } | ||
290 | |||
291 | |||
292 | //! returns driver type of texture (=the driver, who created the texture) | ||
293 | E_DRIVER_TYPE CD3D8Texture::getDriverType() const | ||
294 | { | ||
295 | return EDT_DIRECT3D8; | ||
296 | } | ||
297 | |||
298 | |||
299 | //! returns color format of texture | ||
300 | ECOLOR_FORMAT CD3D8Texture::getColorFormat() const | ||
301 | { | ||
302 | return ColorFormat; | ||
303 | } | ||
304 | |||
305 | |||
306 | //! returns pitch of texture (in bytes) | ||
307 | u32 CD3D8Texture::getPitch() const | ||
308 | { | ||
309 | return Pitch; | ||
310 | } | ||
311 | |||
312 | |||
313 | //! returns the DIRECT3D8 Texture | ||
314 | IDirect3DTexture8* CD3D8Texture::getDX8Texture() const | ||
315 | { | ||
316 | return Texture; | ||
317 | } | ||
318 | |||
319 | |||
320 | //! returns if texture has mipmap levels | ||
321 | bool CD3D8Texture::hasMipMaps() const | ||
322 | { | ||
323 | return HasMipMaps; | ||
324 | } | ||
325 | |||
326 | |||
327 | // The D3DXFilterTexture function seems to get linked wrong when | ||
328 | // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. | ||
329 | // So mipmapgeneration is replaced with my own bad generation in d3d 8 when | ||
330 | // compiling with both D3D 8 and 9. | ||
331 | bool CD3D8Texture::createMipMaps(u32 level) | ||
332 | { | ||
333 | if (level==0) | ||
334 | return true; | ||
335 | |||
336 | IDirect3DSurface8* upperSurface = 0; | ||
337 | IDirect3DSurface8* lowerSurface = 0; | ||
338 | |||
339 | // get upper level | ||
340 | HRESULT hr = Texture->GetSurfaceLevel(level-1, &upperSurface); | ||
341 | if (FAILED(hr) || !upperSurface) | ||
342 | { | ||
343 | os::Printer::log("Could not get upper surface level for mip map generation", ELL_WARNING); | ||
344 | return false; | ||
345 | } | ||
346 | |||
347 | // get lower level | ||
348 | hr = Texture->GetSurfaceLevel(level, &lowerSurface); | ||
349 | if (FAILED(hr) || !lowerSurface) | ||
350 | { | ||
351 | os::Printer::log("Could not get lower surface level for mip map generation", ELL_WARNING); | ||
352 | upperSurface->Release(); | ||
353 | return false; | ||
354 | } | ||
355 | |||
356 | D3DSURFACE_DESC upperDesc, lowerDesc; | ||
357 | upperSurface->GetDesc(&upperDesc); | ||
358 | lowerSurface->GetDesc(&lowerDesc); | ||
359 | |||
360 | D3DLOCKED_RECT upperlr; | ||
361 | D3DLOCKED_RECT lowerlr; | ||
362 | |||
363 | // lock upper surface | ||
364 | if (FAILED(upperSurface->LockRect(&upperlr, NULL, 0))) | ||
365 | { | ||
366 | os::Printer::log("Could not lock upper texture for mip map generation", ELL_WARNING); | ||
367 | upperSurface->Release(); | ||
368 | lowerSurface->Release(); | ||
369 | return false; | ||
370 | } | ||
371 | |||
372 | // lock lower surface | ||
373 | if (FAILED(lowerSurface->LockRect(&lowerlr, NULL, 0))) | ||
374 | { | ||
375 | os::Printer::log("Could not lock lower texture for mip map generation", ELL_WARNING); | ||
376 | upperSurface->UnlockRect(); | ||
377 | upperSurface->Release(); | ||
378 | lowerSurface->Release(); | ||
379 | return false; | ||
380 | } | ||
381 | |||
382 | if (upperDesc.Format != lowerDesc.Format) | ||
383 | { | ||
384 | os::Printer::log("Cannot copy mip maps with different formats.", ELL_WARNING); | ||
385 | } | ||
386 | else | ||
387 | { | ||
388 | if (upperDesc.Format == D3DFMT_A1R5G5B5) | ||
389 | copy16BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, | ||
390 | lowerDesc.Width, lowerDesc.Height, | ||
391 | upperlr.Pitch, lowerlr.Pitch); | ||
392 | else | ||
393 | if (upperDesc.Format == D3DFMT_A8R8G8B8) | ||
394 | copy32BitMipMap((char*)upperlr.pBits, (char*)lowerlr.pBits, | ||
395 | lowerDesc.Width, lowerDesc.Height, | ||
396 | upperlr.Pitch, lowerlr.Pitch); | ||
397 | else | ||
398 | os::Printer::log("Unsupported mipmap format, cannot copy.", ELL_WARNING); | ||
399 | } | ||
400 | |||
401 | bool result=true; | ||
402 | // unlock | ||
403 | if (FAILED(upperSurface->UnlockRect())) | ||
404 | result=false; | ||
405 | if (FAILED(lowerSurface->UnlockRect())) | ||
406 | result=false; | ||
407 | |||
408 | // release | ||
409 | upperSurface->Release(); | ||
410 | lowerSurface->Release(); | ||
411 | |||
412 | if (!result || upperDesc.Width < 3 || upperDesc.Height < 3) | ||
413 | return result; // stop generating levels | ||
414 | |||
415 | // generate next level | ||
416 | return createMipMaps(level+1); | ||
417 | } | ||
418 | |||
419 | |||
420 | ECOLOR_FORMAT CD3D8Texture::getColorFormatFromD3DFormat(D3DFORMAT format) | ||
421 | { | ||
422 | switch(format) | ||
423 | { | ||
424 | case D3DFMT_X1R5G5B5: | ||
425 | case D3DFMT_A1R5G5B5: | ||
426 | Pitch = TextureSize.Width * 2; | ||
427 | return ECF_A1R5G5B5; | ||
428 | break; | ||
429 | case D3DFMT_A8R8G8B8: | ||
430 | case D3DFMT_X8R8G8B8: | ||
431 | Pitch = TextureSize.Width * 4; | ||
432 | return ECF_A8R8G8B8; | ||
433 | break; | ||
434 | case D3DFMT_R5G6B5: | ||
435 | Pitch = TextureSize.Width * 2; | ||
436 | return ECF_R5G6B5; | ||
437 | break; | ||
438 | default: | ||
439 | return (ECOLOR_FORMAT)0; | ||
440 | }; | ||
441 | } | ||
442 | |||
443 | |||
444 | |||
445 | void CD3D8Texture::copy16BitMipMap(char* src, char* tgt, | ||
446 | s32 width, s32 height, | ||
447 | s32 pitchsrc, s32 pitchtgt) const | ||
448 | { | ||
449 | u16 c; | ||
450 | |||
451 | for (int x=0; x<width; ++x) | ||
452 | { | ||
453 | for (int y=0; y<height; ++y) | ||
454 | { | ||
455 | s32 a=0, r=0, g=0, b=0; | ||
456 | |||
457 | for (int dx=0; dx<2; ++dx) | ||
458 | { | ||
459 | for (int dy=0; dy<2; ++dy) | ||
460 | { | ||
461 | int tgx = (x*2)+dx; | ||
462 | int tgy = (y*2)+dy; | ||
463 | |||
464 | c = *(u16*)((void*)&src[(tgx*2)+(tgy*pitchsrc)]); | ||
465 | |||
466 | a += getAlpha(c); | ||
467 | r += getRed(c); | ||
468 | g += getGreen(c); | ||
469 | b += getBlue(c); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | a /= 4; | ||
474 | r /= 4; | ||
475 | g /= 4; | ||
476 | b /= 4; | ||
477 | |||
478 | c = ((a & 0x1) <<15) | ((r & 0x1F)<<10) | ((g & 0x1F)<<5) | (b & 0x1F); | ||
479 | *(u16*)((void*)&tgt[(x*2)+(y*pitchtgt)]) = c; | ||
480 | } | ||
481 | } | ||
482 | } | ||
483 | |||
484 | |||
485 | void CD3D8Texture::copy32BitMipMap(char* src, char* tgt, | ||
486 | s32 width, s32 height, | ||
487 | s32 pitchsrc, s32 pitchtgt) const | ||
488 | { | ||
489 | SColor c; | ||
490 | |||
491 | for (int x=0; x<width; ++x) | ||
492 | { | ||
493 | for (int y=0; y<height; ++y) | ||
494 | { | ||
495 | s32 a=0, r=0, g=0, b=0; | ||
496 | |||
497 | for (int dx=0; dx<2; ++dx) | ||
498 | { | ||
499 | for (int dy=0; dy<2; ++dy) | ||
500 | { | ||
501 | int tgx = (x*2)+dx; | ||
502 | int tgy = (y*2)+dy; | ||
503 | |||
504 | c = *(u32*)((void*)&src[(tgx<<2)+(tgy*pitchsrc)]); | ||
505 | |||
506 | a += c.getAlpha(); | ||
507 | r += c.getRed(); | ||
508 | g += c.getGreen(); | ||
509 | b += c.getBlue(); | ||
510 | } | ||
511 | } | ||
512 | |||
513 | a >>= 2; | ||
514 | r >>= 2; | ||
515 | g >>= 2; | ||
516 | b >>= 2; | ||
517 | |||
518 | c = ((a & 0xff)<<24) | ((r & 0xff)<<16) | ((g & 0xff)<<8) | (b & 0xff); | ||
519 | *(u32*)((void*)&tgt[(x*4)+(y*pitchtgt)]) = c.color; | ||
520 | } | ||
521 | } | ||
522 | } | ||
523 | |||
524 | |||
525 | void CD3D8Texture::createRenderTarget() | ||
526 | { | ||
527 | TextureSize = TextureSize.getOptimalSize(!Driver->queryFeature(EVDF_TEXTURE_NPOT), !Driver->queryFeature(EVDF_TEXTURE_NSQUARE), true, Driver->Caps.MaxTextureWidth); | ||
528 | |||
529 | // get backbuffer format to create the render target in the | ||
530 | // same format | ||
531 | |||
532 | IDirect3DSurface8* bb; | ||
533 | D3DFORMAT d3DFormat = D3DFMT_A8R8G8B8; | ||
534 | |||
535 | if (!FAILED(Device->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &bb))) | ||
536 | { | ||
537 | D3DSURFACE_DESC desc; | ||
538 | bb->GetDesc(&desc); | ||
539 | d3DFormat = desc.Format; | ||
540 | |||
541 | if (d3DFormat == D3DFMT_X8R8G8B8) | ||
542 | d3DFormat = D3DFMT_A8R8G8B8; | ||
543 | |||
544 | bb->Release(); | ||
545 | } | ||
546 | else | ||
547 | { | ||
548 | os::Printer::log("Could not create RenderTarget texture: could not get BackBuffer.", | ||
549 | ELL_WARNING); | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | // create texture | ||
554 | HRESULT hr; | ||
555 | |||
556 | hr = Device->CreateTexture( | ||
557 | TextureSize.Width, | ||
558 | TextureSize.Height, | ||
559 | 1, // mip map level count, we don't want mipmaps here | ||
560 | D3DUSAGE_RENDERTARGET, | ||
561 | d3DFormat, | ||
562 | D3DPOOL_DEFAULT, | ||
563 | &Texture); | ||
564 | |||
565 | // get irrlicht format from D3D format | ||
566 | ColorFormat = getColorFormatFromD3DFormat(d3DFormat); | ||
567 | |||
568 | if (FAILED(hr)) | ||
569 | os::Printer::log("Could not create render target texture"); | ||
570 | } | ||
571 | |||
572 | |||
573 | //! Regenerates the mip map levels of the texture. Useful after locking and | ||
574 | //! modifying the texture | ||
575 | void CD3D8Texture::regenerateMipMapLevels(void* mipmapData) | ||
576 | { | ||
577 | if (mipmapData) | ||
578 | { | ||
579 | core::dimension2du size = TextureSize; | ||
580 | u32 level=0; | ||
581 | do | ||
582 | { | ||
583 | if (size.Width>1) | ||
584 | size.Width /=2; | ||
585 | if (size.Height>1) | ||
586 | size.Height /=2; | ||
587 | ++level; | ||
588 | IDirect3DSurface8* mipSurface = 0; | ||
589 | HRESULT hr = Texture->GetSurfaceLevel(level, &mipSurface); | ||
590 | if (FAILED(hr) || !mipSurface) | ||
591 | { | ||
592 | os::Printer::log("Could not get mipmap level", ELL_WARNING); | ||
593 | return; | ||
594 | } | ||
595 | D3DSURFACE_DESC mipDesc; | ||
596 | mipSurface->GetDesc(&mipDesc); | ||
597 | D3DLOCKED_RECT miplr; | ||
598 | |||
599 | // lock mipmap surface | ||
600 | if (FAILED(mipSurface->LockRect(&miplr, NULL, 0))) | ||
601 | { | ||
602 | mipSurface->Release(); | ||
603 | os::Printer::log("Could not lock texture", ELL_WARNING); | ||
604 | return; | ||
605 | } | ||
606 | |||
607 | memcpy(miplr.pBits, mipmapData, size.getArea()*getPitch()/TextureSize.Width); | ||
608 | mipmapData = (u8*)mipmapData+size.getArea()*getPitch()/TextureSize.Width; | ||
609 | // unlock | ||
610 | mipSurface->UnlockRect(); | ||
611 | // release | ||
612 | mipSurface->Release(); | ||
613 | } while (size.Width != 1 || size.Height != 1); | ||
614 | } | ||
615 | else if (HasMipMaps) | ||
616 | { | ||
617 | // create mip maps. | ||
618 | #ifndef _IRR_USE_D3DXFilterTexture_ | ||
619 | // The D3DXFilterTexture function seems to get linked wrong when | ||
620 | // compiling with both D3D8 and 9, causing it not to work in the D3D9 device. | ||
621 | // So mipmapgeneration is replaced with my own bad generation in d3d 8 when | ||
622 | // compiling with both D3D 8 and 9. | ||
623 | HRESULT hr = D3DXFilterTexture(Texture, NULL, D3DX_DEFAULT , D3DX_DEFAULT ); | ||
624 | if (FAILED(hr)) | ||
625 | #endif | ||
626 | createMipMaps(); | ||
627 | } | ||
628 | } | ||
629 | |||
630 | |||
631 | //! returns if it is a render target | ||
632 | bool CD3D8Texture::isRenderTarget() const | ||
633 | { | ||
634 | return IsRenderTarget; | ||
635 | } | ||
636 | |||
637 | |||
638 | //! Returns pointer to the render target surface | ||
639 | IDirect3DSurface8* CD3D8Texture::getRenderTargetSurface() | ||
640 | { | ||
641 | if (!IsRenderTarget) | ||
642 | return 0; | ||
643 | |||
644 | IDirect3DSurface8 *pRTTSurface = 0; | ||
645 | if (Texture) | ||
646 | Texture->GetSurfaceLevel(0, &pRTTSurface); | ||
647 | |||
648 | if (pRTTSurface) | ||
649 | pRTTSurface->Release(); | ||
650 | |||
651 | return pRTTSurface; | ||
652 | } | ||
653 | |||
654 | |||
655 | } // end namespace video | ||
656 | } // end namespace irr | ||
657 | |||
658 | #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ | ||
659 | |||