diff options
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CD3D9Texture.cpp')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CD3D9Texture.cpp | 1398 |
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 | ||
27 | namespace irr | 27 | namespace irr |
28 | { | 28 | { |
29 | namespace video | 29 | namespace video |
30 | { | 30 | { |
31 | 31 | ||
32 | //! rendertarget constructor | 32 | //! rendertarget constructor |
33 | CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size, | 33 | CD3D9Texture::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 |
52 | CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, | 52 | CD3D9Texture::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 |
84 | CD3D9Texture::~CD3D9Texture() | 84 | CD3D9Texture::~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 | ||
106 | void CD3D9Texture::createRenderTarget(const ECOLOR_FORMAT format) | 106 | void 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 | ||
167 | bool CD3D9Texture::createMipMaps(u32 level) | 167 | bool 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 |
265 | bool CD3D9Texture::createTexture(u32 flags, IImage * image) | 265 | bool 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 |
352 | bool CD3D9Texture::copyTexture(IImage * image) | 352 | bool 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 |
386 | void* CD3D9Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel) | 386 | void* 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 |
444 | void CD3D9Texture::unlock() | 444 | void 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. |
457 | const core::dimension2d<u32>& CD3D9Texture::getOriginalSize() const | 457 | const 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. |
464 | const core::dimension2d<u32>& CD3D9Texture::getSize() const | 464 | const 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) |
471 | E_DRIVER_TYPE CD3D9Texture::getDriverType() const | 471 | E_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 |
478 | ECOLOR_FORMAT CD3D9Texture::getColorFormat() const | 478 | ECOLOR_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) |
485 | u32 CD3D9Texture::getPitch() const | 485 | u32 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 |
492 | IDirect3DBaseTexture9* CD3D9Texture::getDX9Texture() const | 492 | IDirect3DBaseTexture9* 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 |
499 | bool CD3D9Texture::hasMipMaps() const | 499 | bool CD3D9Texture::hasMipMaps() const |
500 | { | 500 | { |
501 | return HasMipMaps; | 501 | return HasMipMaps; |
502 | } | 502 | } |
503 | 503 | ||
504 | 504 | ||
505 | void CD3D9Texture::copy16BitMipMap(char* src, char* tgt, | 505 | void 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 | ||
551 | void CD3D9Texture::copy32BitMipMap(char* src, char* tgt, | 551 | void 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 |
592 | void CD3D9Texture::regenerateMipMapLevels(void* mipmapData) | 592 | void 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 |
648 | bool CD3D9Texture::isRenderTarget() const | 648 | bool 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 |
655 | IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface() | 655 | IDirect3DSurface9* 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 | ||
671 | void CD3D9Texture::setPitch(D3DFORMAT d3dformat) | 671 | void 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_ |