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