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