aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CD3D9Driver.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/CD3D9Driver.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 '')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CD3D9Driver.cpp7266
1 files changed, 3633 insertions, 3633 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CD3D9Driver.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CD3D9Driver.cpp
index 7404894..473f352 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CD3D9Driver.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CD3D9Driver.cpp
@@ -1,3633 +1,3633 @@
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#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE 5#define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE
6#include "CD3D9Driver.h" 6#include "CD3D9Driver.h"
7 7
8#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ 8#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
9 9
10#include "os.h" 10#include "os.h"
11#include "S3DVertex.h" 11#include "S3DVertex.h"
12#include "CD3D9Texture.h" 12#include "CD3D9Texture.h"
13#include "CD3D9MaterialRenderer.h" 13#include "CD3D9MaterialRenderer.h"
14#include "CD3D9ShaderMaterialRenderer.h" 14#include "CD3D9ShaderMaterialRenderer.h"
15#include "CD3D9NormalMapRenderer.h" 15#include "CD3D9NormalMapRenderer.h"
16#include "CD3D9ParallaxMapRenderer.h" 16#include "CD3D9ParallaxMapRenderer.h"
17#include "CD3D9HLSLMaterialRenderer.h" 17#include "CD3D9HLSLMaterialRenderer.h"
18#include "CD3D9CgMaterialRenderer.h" 18#include "CD3D9CgMaterialRenderer.h"
19#include "SIrrCreationParameters.h" 19#include "SIrrCreationParameters.h"
20 20
21namespace irr 21namespace irr
22{ 22{
23namespace video 23namespace video
24{ 24{
25 25
26namespace 26namespace
27{ 27{
28 inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); } 28 inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
29} 29}
30 30
31//! constructor 31//! constructor
32CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) 32CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io)
33 : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), 33 : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE),
34 ResetRenderStates(true), Transformation3DChanged(false), 34 ResetRenderStates(true), Transformation3DChanged(false),
35 D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), 35 D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
36 WindowId(0), SceneSourceRect(0), 36 WindowId(0), SceneSourceRect(0),
37 LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0), 37 LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0),
38 MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1), 38 MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1),
39 MaxLightDistance(0.f), LastSetLight(-1), 39 MaxLightDistance(0.f), LastSetLight(-1),
40 ColorFormat(ECF_A8R8G8B8), DeviceLost(false), 40 ColorFormat(ECF_A8R8G8B8), DeviceLost(false),
41 DriverWasReset(true), OcclusionQuerySupport(false), 41 DriverWasReset(true), OcclusionQuerySupport(false),
42 AlphaToCoverageSupport(false), Params(params) 42 AlphaToCoverageSupport(false), Params(params)
43{ 43{
44 #ifdef _DEBUG 44 #ifdef _DEBUG
45 setDebugName("CD3D9Driver"); 45 setDebugName("CD3D9Driver");
46 #endif 46 #endif
47 47
48 printVersion(); 48 printVersion();
49 49
50 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) 50 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
51 { 51 {
52 CurrentTexture[i] = 0; 52 CurrentTexture[i] = 0;
53 LastTextureMipMapsAvailable[i] = false; 53 LastTextureMipMapsAvailable[i] = false;
54 } 54 }
55 MaxLightDistance = sqrtf(FLT_MAX); 55 MaxLightDistance = sqrtf(FLT_MAX);
56 // create sphere map matrix 56 // create sphere map matrix
57 57
58 SphereMapMatrixD3D9._11 = 0.5f; SphereMapMatrixD3D9._12 = 0.0f; 58 SphereMapMatrixD3D9._11 = 0.5f; SphereMapMatrixD3D9._12 = 0.0f;
59 SphereMapMatrixD3D9._13 = 0.0f; SphereMapMatrixD3D9._14 = 0.0f; 59 SphereMapMatrixD3D9._13 = 0.0f; SphereMapMatrixD3D9._14 = 0.0f;
60 SphereMapMatrixD3D9._21 = 0.0f; SphereMapMatrixD3D9._22 =-0.5f; 60 SphereMapMatrixD3D9._21 = 0.0f; SphereMapMatrixD3D9._22 =-0.5f;
61 SphereMapMatrixD3D9._23 = 0.0f; SphereMapMatrixD3D9._24 = 0.0f; 61 SphereMapMatrixD3D9._23 = 0.0f; SphereMapMatrixD3D9._24 = 0.0f;
62 SphereMapMatrixD3D9._31 = 0.0f; SphereMapMatrixD3D9._32 = 0.0f; 62 SphereMapMatrixD3D9._31 = 0.0f; SphereMapMatrixD3D9._32 = 0.0f;
63 SphereMapMatrixD3D9._33 = 1.0f; SphereMapMatrixD3D9._34 = 0.0f; 63 SphereMapMatrixD3D9._33 = 1.0f; SphereMapMatrixD3D9._34 = 0.0f;
64 SphereMapMatrixD3D9._41 = 0.5f; SphereMapMatrixD3D9._42 = 0.5f; 64 SphereMapMatrixD3D9._41 = 0.5f; SphereMapMatrixD3D9._42 = 0.5f;
65 SphereMapMatrixD3D9._43 = 0.0f; SphereMapMatrixD3D9._44 = 1.0f; 65 SphereMapMatrixD3D9._43 = 0.0f; SphereMapMatrixD3D9._44 = 1.0f;
66 66
67 core::matrix4 mat; 67 core::matrix4 mat;
68 UnitMatrixD3D9 = *(D3DMATRIX*)((void*)mat.pointer()); 68 UnitMatrixD3D9 = *(D3DMATRIX*)((void*)mat.pointer());
69 69
70 #ifdef _IRR_COMPILE_WITH_CG_ 70 #ifdef _IRR_COMPILE_WITH_CG_
71 CgContext = 0; 71 CgContext = 0;
72 #endif 72 #endif
73 73
74 // init direct 3d is done in the factory function 74 // init direct 3d is done in the factory function
75} 75}
76 76
77 77
78//! destructor 78//! destructor
79CD3D9Driver::~CD3D9Driver() 79CD3D9Driver::~CD3D9Driver()
80{ 80{
81 deleteMaterialRenders(); 81 deleteMaterialRenders();
82 deleteAllTextures(); 82 deleteAllTextures();
83 removeAllOcclusionQueries(); 83 removeAllOcclusionQueries();
84 removeAllHardwareBuffers(); 84 removeAllHardwareBuffers();
85 for (u32 i=0; i<DepthBuffers.size(); ++i) 85 for (u32 i=0; i<DepthBuffers.size(); ++i)
86 { 86 {
87 DepthBuffers[i]->drop(); 87 DepthBuffers[i]->drop();
88 } 88 }
89 DepthBuffers.clear(); 89 DepthBuffers.clear();
90 90
91 // drop d3d9 91 // drop d3d9
92 92
93 if (pID3DDevice) 93 if (pID3DDevice)
94 pID3DDevice->Release(); 94 pID3DDevice->Release();
95 95
96 if (pID3D) 96 if (pID3D)
97 pID3D->Release(); 97 pID3D->Release();
98 98
99 #ifdef _IRR_COMPILE_WITH_CG_ 99 #ifdef _IRR_COMPILE_WITH_CG_
100 cgD3D9SetDevice(0); 100 cgD3D9SetDevice(0);
101 101
102 if(CgContext) 102 if(CgContext)
103 { 103 {
104 cgDestroyContext(CgContext); 104 cgDestroyContext(CgContext);
105 } 105 }
106 #endif 106 #endif
107} 107}
108 108
109 109
110void CD3D9Driver::createMaterialRenderers() 110void CD3D9Driver::createMaterialRenderers()
111{ 111{
112 // create D3D9 material renderers 112 // create D3D9 material renderers
113 113
114 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID(pID3DDevice, this)); 114 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID(pID3DDevice, this));
115 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); 115 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this));
116 116
117 // add the same renderer for all lightmap types 117 // add the same renderer for all lightmap types
118 118
119 CD3D9MaterialRenderer_LIGHTMAP* lmr = new CD3D9MaterialRenderer_LIGHTMAP(pID3DDevice, this); 119 CD3D9MaterialRenderer_LIGHTMAP* lmr = new CD3D9MaterialRenderer_LIGHTMAP(pID3DDevice, this);
120 addMaterialRenderer(lmr); // for EMT_LIGHTMAP: 120 addMaterialRenderer(lmr); // for EMT_LIGHTMAP:
121 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: 121 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD:
122 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: 122 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2:
123 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: 123 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4:
124 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: 124 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING:
125 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: 125 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2:
126 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: 126 addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4:
127 lmr->drop(); 127 lmr->drop();
128 128
129 // add remaining fixed function pipeline material renderers 129 // add remaining fixed function pipeline material renderers
130 130
131 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); 131 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_DETAIL_MAP(pID3DDevice, this));
132 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); 132 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_SPHERE_MAP(pID3DDevice, this));
133 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); 133 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this));
134 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); 134 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this));
135 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); 135 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this));
136 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); 136 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this));
137 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); 137 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this));
138 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); 138 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this));
139 139
140 // add normal map renderers 140 // add normal map renderers
141 141
142 s32 tmp = 0; 142 s32 tmp = 0;
143 video::IMaterialRenderer* renderer = 0; 143 video::IMaterialRenderer* renderer = 0;
144 144
145 renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, 145 renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp,
146 MaterialRenderers[EMT_SOLID].Renderer); 146 MaterialRenderers[EMT_SOLID].Renderer);
147 renderer->drop(); 147 renderer->drop();
148 148
149 renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, 149 renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp,
150 MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); 150 MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer);
151 renderer->drop(); 151 renderer->drop();
152 152
153 renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp, 153 renderer = new CD3D9NormalMapRenderer(pID3DDevice, this, tmp,
154 MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); 154 MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer);
155 renderer->drop(); 155 renderer->drop();
156 156
157 // add parallax map renderers 157 // add parallax map renderers
158 158
159 renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, 159 renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp,
160 MaterialRenderers[EMT_SOLID].Renderer); 160 MaterialRenderers[EMT_SOLID].Renderer);
161 renderer->drop(); 161 renderer->drop();
162 162
163 renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, 163 renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp,
164 MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); 164 MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer);
165 renderer->drop(); 165 renderer->drop();
166 166
167 renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp, 167 renderer = new CD3D9ParallaxMapRenderer(pID3DDevice, this, tmp,
168 MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); 168 MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer);
169 renderer->drop(); 169 renderer->drop();
170 170
171 // add basic 1 texture blending 171 // add basic 1 texture blending
172 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); 172 addAndDropMaterialRenderer(new CD3D9MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this));
173} 173}
174 174
175 175
176//! initialises the Direct3D API 176//! initialises the Direct3D API
177bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware) 177bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
178{ 178{
179 if (!pID3D) 179 if (!pID3D)
180 { 180 {
181 D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") ); 181 D3DLibrary = LoadLibrary( __TEXT("d3d9.dll") );
182 182
183 if (!D3DLibrary) 183 if (!D3DLibrary)
184 { 184 {
185 os::Printer::log("Error, could not load d3d9.dll.", ELL_ERROR); 185 os::Printer::log("Error, could not load d3d9.dll.", ELL_ERROR);
186 return false; 186 return false;
187 } 187 }
188 188
189 typedef IDirect3D9 * (__stdcall *D3DCREATETYPE)(UINT); 189 typedef IDirect3D9 * (__stdcall *D3DCREATETYPE)(UINT);
190 D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate9"); 190 D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate9");
191 191
192 if (!d3dCreate) 192 if (!d3dCreate)
193 { 193 {
194 os::Printer::log("Error, could not get proc adress of Direct3DCreate9.", ELL_ERROR); 194 os::Printer::log("Error, could not get proc adress of Direct3DCreate9.", ELL_ERROR);
195 return false; 195 return false;
196 } 196 }
197 197
198 //just like pID3D = Direct3DCreate9(D3D_SDK_VERSION); 198 //just like pID3D = Direct3DCreate9(D3D_SDK_VERSION);
199 pID3D = (*d3dCreate)(D3D_SDK_VERSION); 199 pID3D = (*d3dCreate)(D3D_SDK_VERSION);
200 200
201 if (!pID3D) 201 if (!pID3D)
202 { 202 {
203 os::Printer::log("Error initializing D3D.", ELL_ERROR); 203 os::Printer::log("Error initializing D3D.", ELL_ERROR);
204 return false; 204 return false;
205 } 205 }
206 } 206 }
207 207
208 // print device information 208 // print device information
209 D3DADAPTER_IDENTIFIER9 dai; 209 D3DADAPTER_IDENTIFIER9 dai;
210 if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, 0, &dai))) 210 if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, 0, &dai)))
211 { 211 {
212 char tmp[512]; 212 char tmp[512];
213 213
214 s32 Product = HIWORD(dai.DriverVersion.HighPart); 214 s32 Product = HIWORD(dai.DriverVersion.HighPart);
215 s32 Version = LOWORD(dai.DriverVersion.HighPart); 215 s32 Version = LOWORD(dai.DriverVersion.HighPart);
216 s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); 216 s32 SubVersion = HIWORD(dai.DriverVersion.LowPart);
217 s32 Build = LOWORD(dai.DriverVersion.LowPart); 217 s32 Build = LOWORD(dai.DriverVersion.LowPart);
218 218
219 sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, 219 sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version,
220 SubVersion, Build); 220 SubVersion, Build);
221 os::Printer::log(tmp, ELL_INFORMATION); 221 os::Printer::log(tmp, ELL_INFORMATION);
222 222
223 // Assign vendor name based on vendor id. 223 // Assign vendor name based on vendor id.
224 VendorID= static_cast<u16>(dai.VendorId); 224 VendorID= static_cast<u16>(dai.VendorId);
225 switch(dai.VendorId) 225 switch(dai.VendorId)
226 { 226 {
227 case 0x1002 : VendorName = "ATI Technologies Inc."; break; 227 case 0x1002 : VendorName = "ATI Technologies Inc."; break;
228 case 0x10DE : VendorName = "NVIDIA Corporation"; break; 228 case 0x10DE : VendorName = "NVIDIA Corporation"; break;
229 case 0x102B : VendorName = "Matrox Electronic Systems Ltd."; break; 229 case 0x102B : VendorName = "Matrox Electronic Systems Ltd."; break;
230 case 0x121A : VendorName = "3dfx Interactive Inc"; break; 230 case 0x121A : VendorName = "3dfx Interactive Inc"; break;
231 case 0x5333 : VendorName = "S3 Graphics Co., Ltd."; break; 231 case 0x5333 : VendorName = "S3 Graphics Co., Ltd."; break;
232 case 0x8086 : VendorName = "Intel Corporation"; break; 232 case 0x8086 : VendorName = "Intel Corporation"; break;
233 default: VendorName = "Unknown VendorId: ";VendorName += (u32)dai.VendorId; break; 233 default: VendorName = "Unknown VendorId: ";VendorName += (u32)dai.VendorId; break;
234 } 234 }
235 } 235 }
236 236
237 D3DDISPLAYMODE d3ddm; 237 D3DDISPLAYMODE d3ddm;
238 if (FAILED(pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm))) 238 if (FAILED(pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm)))
239 { 239 {
240 os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); 240 os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR);
241 return false; 241 return false;
242 } 242 }
243 243
244 ZeroMemory(&present, sizeof(present)); 244 ZeroMemory(&present, sizeof(present));
245 245
246 present.BackBufferCount = 1; 246 present.BackBufferCount = 1;
247 present.EnableAutoDepthStencil = TRUE; 247 present.EnableAutoDepthStencil = TRUE;
248 if (Params.Vsync) 248 if (Params.Vsync)
249 present.PresentationInterval = D3DPRESENT_INTERVAL_ONE; 249 present.PresentationInterval = D3DPRESENT_INTERVAL_ONE;
250 else 250 else
251 present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; 251 present.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
252 252
253 if (Params.Fullscreen) 253 if (Params.Fullscreen)
254 { 254 {
255 present.BackBufferWidth = Params.WindowSize.Width; 255 present.BackBufferWidth = Params.WindowSize.Width;
256 present.BackBufferHeight = Params.WindowSize.Height; 256 present.BackBufferHeight = Params.WindowSize.Height;
257 // request 32bit mode if user specified 32 bit, added by Thomas Stuefe 257 // request 32bit mode if user specified 32 bit, added by Thomas Stuefe
258 if (Params.Bits == 32) 258 if (Params.Bits == 32)
259 present.BackBufferFormat = D3DFMT_X8R8G8B8; 259 present.BackBufferFormat = D3DFMT_X8R8G8B8;
260 else 260 else
261 present.BackBufferFormat = D3DFMT_R5G6B5; 261 present.BackBufferFormat = D3DFMT_R5G6B5;
262 present.SwapEffect = D3DSWAPEFFECT_FLIP; 262 present.SwapEffect = D3DSWAPEFFECT_FLIP;
263 present.Windowed = FALSE; 263 present.Windowed = FALSE;
264 present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; 264 present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
265 } 265 }
266 else 266 else
267 { 267 {
268 present.BackBufferFormat = d3ddm.Format; 268 present.BackBufferFormat = d3ddm.Format;
269 present.SwapEffect = D3DSWAPEFFECT_DISCARD; 269 present.SwapEffect = D3DSWAPEFFECT_DISCARD;
270 present.Windowed = TRUE; 270 present.Windowed = TRUE;
271 } 271 }
272 272
273 UINT adapter = Params.DisplayAdapter; 273 UINT adapter = Params.DisplayAdapter;
274 D3DDEVTYPE devtype = D3DDEVTYPE_HAL; 274 D3DDEVTYPE devtype = D3DDEVTYPE_HAL;
275 #ifndef _IRR_D3D_NO_SHADER_DEBUGGING 275 #ifndef _IRR_D3D_NO_SHADER_DEBUGGING
276 devtype = D3DDEVTYPE_REF; 276 devtype = D3DDEVTYPE_REF;
277 #elif defined(_IRR_USE_NVIDIA_PERFHUD_) 277 #elif defined(_IRR_USE_NVIDIA_PERFHUD_)
278 for (UINT adapter_i = 0; adapter_i < pID3D->GetAdapterCount(); ++adapter_i) 278 for (UINT adapter_i = 0; adapter_i < pID3D->GetAdapterCount(); ++adapter_i)
279 { 279 {
280 D3DADAPTER_IDENTIFIER9 identifier; 280 D3DADAPTER_IDENTIFIER9 identifier;
281 pID3D->GetAdapterIdentifier(adapter_i,0,&identifier); 281 pID3D->GetAdapterIdentifier(adapter_i,0,&identifier);
282 if (strstr(identifier.Description,"PerfHUD") != 0) 282 if (strstr(identifier.Description,"PerfHUD") != 0)
283 { 283 {
284 adapter = adapter_i; 284 adapter = adapter_i;
285 devtype = D3DDEVTYPE_REF; 285 devtype = D3DDEVTYPE_REF;
286 break; 286 break;
287 } 287 }
288 } 288 }
289 #endif 289 #endif
290 290
291 // enable anti alias if possible and desired 291 // enable anti alias if possible and desired
292 if (Params.AntiAlias > 0) 292 if (Params.AntiAlias > 0)
293 { 293 {
294 if (Params.AntiAlias > 32) 294 if (Params.AntiAlias > 32)
295 Params.AntiAlias = 32; 295 Params.AntiAlias = 32;
296 296
297 DWORD qualityLevels = 0; 297 DWORD qualityLevels = 0;
298 298
299 while(Params.AntiAlias > 0) 299 while(Params.AntiAlias > 0)
300 { 300 {
301 if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter, 301 if(SUCCEEDED(pID3D->CheckDeviceMultiSampleType(adapter,
302 devtype, present.BackBufferFormat, !Params.Fullscreen, 302 devtype, present.BackBufferFormat, !Params.Fullscreen,
303 (D3DMULTISAMPLE_TYPE)Params.AntiAlias, &qualityLevels))) 303 (D3DMULTISAMPLE_TYPE)Params.AntiAlias, &qualityLevels)))
304 { 304 {
305 present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias; 305 present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias;
306 present.MultiSampleQuality = qualityLevels-1; 306 present.MultiSampleQuality = qualityLevels-1;
307 present.SwapEffect = D3DSWAPEFFECT_DISCARD; 307 present.SwapEffect = D3DSWAPEFFECT_DISCARD;
308 break; 308 break;
309 } 309 }
310 --Params.AntiAlias; 310 --Params.AntiAlias;
311 } 311 }
312 312
313 if (Params.AntiAlias==0) 313 if (Params.AntiAlias==0)
314 { 314 {
315 os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); 315 os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING);
316 } 316 }
317 } 317 }
318 318
319 // check stencil buffer compatibility 319 // check stencil buffer compatibility
320 if (Params.Stencilbuffer) 320 if (Params.Stencilbuffer)
321 { 321 {
322 present.AutoDepthStencilFormat = D3DFMT_D24S8; 322 present.AutoDepthStencilFormat = D3DFMT_D24S8;
323 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, 323 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
324 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, 324 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
325 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) 325 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
326 { 326 {
327 present.AutoDepthStencilFormat = D3DFMT_D24X4S4; 327 present.AutoDepthStencilFormat = D3DFMT_D24X4S4;
328 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, 328 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
329 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, 329 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
330 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) 330 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
331 { 331 {
332 present.AutoDepthStencilFormat = D3DFMT_D15S1; 332 present.AutoDepthStencilFormat = D3DFMT_D15S1;
333 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, 333 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
334 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, 334 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
335 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) 335 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
336 { 336 {
337 os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); 337 os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING);
338 Params.Stencilbuffer = false; 338 Params.Stencilbuffer = false;
339 } 339 }
340 } 340 }
341 } 341 }
342 else 342 else
343 if(FAILED(pID3D->CheckDepthStencilMatch(adapter, devtype, 343 if(FAILED(pID3D->CheckDepthStencilMatch(adapter, devtype,
344 present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) 344 present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat)))
345 { 345 {
346 os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); 346 os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING);
347 Params.Stencilbuffer = false; 347 Params.Stencilbuffer = false;
348 } 348 }
349 } 349 }
350 // do not use else here to cope with flag change in previous block 350 // do not use else here to cope with flag change in previous block
351 if (!Params.Stencilbuffer) 351 if (!Params.Stencilbuffer)
352 { 352 {
353 present.AutoDepthStencilFormat = D3DFMT_D32; 353 present.AutoDepthStencilFormat = D3DFMT_D32;
354 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, 354 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
355 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, 355 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
356 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) 356 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
357 { 357 {
358 present.AutoDepthStencilFormat = D3DFMT_D24X8; 358 present.AutoDepthStencilFormat = D3DFMT_D24X8;
359 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, 359 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
360 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, 360 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
361 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) 361 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
362 { 362 {
363 present.AutoDepthStencilFormat = D3DFMT_D16; 363 present.AutoDepthStencilFormat = D3DFMT_D16;
364 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype, 364 if(FAILED(pID3D->CheckDeviceFormat(adapter, devtype,
365 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, 365 present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL,
366 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) 366 D3DRTYPE_SURFACE, present.AutoDepthStencilFormat)))
367 { 367 {
368 os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); 368 os::Printer::log("Device does not support required depth buffer.", ELL_WARNING);
369 return false; 369 return false;
370 } 370 }
371 } 371 }
372 } 372 }
373 } 373 }
374 374
375 // create device 375 // create device
376 376
377 DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; 377 DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0;
378 DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0; 378 DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0;
379 if (pureSoftware) 379 if (pureSoftware)
380 { 380 {
381 if (FAILED(pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd, 381 if (FAILED(pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd,
382 fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice))) 382 fpuPrecision | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice)))
383 os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR); 383 os::Printer::log("Was not able to create Direct3D9 software device.", ELL_ERROR);
384 } 384 }
385 else 385 else
386 { 386 {
387 HRESULT hr = pID3D->CreateDevice(adapter, devtype, hwnd, 387 HRESULT hr = pID3D->CreateDevice(adapter, devtype, hwnd,
388 fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); 388 fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice);
389 389
390 if(FAILED(hr)) 390 if(FAILED(hr))
391 hr = pID3D->CreateDevice(adapter, devtype, hwnd, 391 hr = pID3D->CreateDevice(adapter, devtype, hwnd,
392 fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); 392 fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice);
393 393
394 if(FAILED(hr)) 394 if(FAILED(hr))
395 hr = pID3D->CreateDevice(adapter, devtype, hwnd, 395 hr = pID3D->CreateDevice(adapter, devtype, hwnd,
396 fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); 396 fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice);
397 397
398 if (FAILED(hr)) 398 if (FAILED(hr))
399 os::Printer::log("Was not able to create Direct3D9 device.", ELL_ERROR); 399 os::Printer::log("Was not able to create Direct3D9 device.", ELL_ERROR);
400 } 400 }
401 401
402 if (!pID3DDevice) 402 if (!pID3DDevice)
403 { 403 {
404 os::Printer::log("Was not able to create DIRECT3D9 device.", ELL_ERROR); 404 os::Printer::log("Was not able to create DIRECT3D9 device.", ELL_ERROR);
405 return false; 405 return false;
406 } 406 }
407 407
408 // get caps 408 // get caps
409 pID3DDevice->GetDeviceCaps(&Caps); 409 pID3DDevice->GetDeviceCaps(&Caps);
410 410
411 os::Printer::log("Currently available Video Memory (kB)", core::stringc(pID3DDevice->GetAvailableTextureMem()/1024).c_str()); 411 os::Printer::log("Currently available Video Memory (kB)", core::stringc(pID3DDevice->GetAvailableTextureMem()/1024).c_str());
412 412
413 // disable stencilbuffer if necessary 413 // disable stencilbuffer if necessary
414 if (Params.Stencilbuffer && 414 if (Params.Stencilbuffer &&
415 (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || 415 (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) ||
416 !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || 416 !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) ||
417 !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) 417 !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP)))
418 { 418 {
419 os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); 419 os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING);
420 Params.Stencilbuffer = false; 420 Params.Stencilbuffer = false;
421 } 421 }
422 422
423 // set default vertex shader 423 // set default vertex shader
424 setVertexShader(EVT_STANDARD); 424 setVertexShader(EVT_STANDARD);
425 425
426 // set fog mode 426 // set fog mode
427 setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); 427 setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog);
428 428
429 // set exposed data 429 // set exposed data
430 ExposedData.D3D9.D3D9 = pID3D; 430 ExposedData.D3D9.D3D9 = pID3D;
431 ExposedData.D3D9.D3DDev9 = pID3DDevice; 431 ExposedData.D3D9.D3DDev9 = pID3DDevice;
432 ExposedData.D3D9.HWnd = hwnd; 432 ExposedData.D3D9.HWnd = hwnd;
433 433
434 ResetRenderStates = true; 434 ResetRenderStates = true;
435 435
436 // create materials 436 // create materials
437 createMaterialRenderers(); 437 createMaterialRenderers();
438 438
439 MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); 439 MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES);
440 MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; 440 MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes;
441 MaxMRTs = (s32)Caps.NumSimultaneousRTs; 441 MaxMRTs = (s32)Caps.NumSimultaneousRTs;
442 OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK); 442 OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK);
443 443
444 if (VendorID==0x10DE)//NVidia 444 if (VendorID==0x10DE)//NVidia
445 AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, 445 AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL,
446 D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, 446 D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE,
447 (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK); 447 (D3DFORMAT)MAKEFOURCC('A', 'T', 'O', 'C')) == S_OK);
448 else if (VendorID==0x1002)//ATI 448 else if (VendorID==0x1002)//ATI
449 AlphaToCoverageSupport = true; // TODO: Check unknown 449 AlphaToCoverageSupport = true; // TODO: Check unknown
450#if 0 450#if 0
451 AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL, 451 AlphaToCoverageSupport = (pID3D->CheckDeviceFormat(adapter, D3DDEVTYPE_HAL,
452 D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE, 452 D3DFMT_X8R8G8B8, 0,D3DRTYPE_SURFACE,
453 (D3DFORMAT)MAKEFOURCC('A','2','M','1')) == S_OK); 453 (D3DFORMAT)MAKEFOURCC('A','2','M','1')) == S_OK);
454#endif 454#endif
455 455
456 DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits); 456 DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits);
457 DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures); 457 DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures);
458 DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights); 458 DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights);
459 DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy); 459 DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy);
460 DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes); 460 DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes);
461 DriverAttributes->setAttribute("MaxMultipleRenderTargets", (s32)Caps.NumSimultaneousRTs); 461 DriverAttributes->setAttribute("MaxMultipleRenderTargets", (s32)Caps.NumSimultaneousRTs);
462 DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex); 462 DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex);
463 DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth)); 463 DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth));
464 DriverAttributes->setAttribute("MaxTextureLODBias", 16); 464 DriverAttributes->setAttribute("MaxTextureLODBias", 16);
465 DriverAttributes->setAttribute("Version", 901); 465 DriverAttributes->setAttribute("Version", 901);
466 DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)(((0x00ff00 & Caps.VertexShaderVersion)>>8)*100 + (Caps.VertexShaderVersion&0xff))); 466 DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)(((0x00ff00 & Caps.VertexShaderVersion)>>8)*100 + (Caps.VertexShaderVersion&0xff)));
467 DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias); 467 DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias);
468 468
469 // set the renderstates 469 // set the renderstates
470 setRenderStates3DMode(); 470 setRenderStates3DMode();
471 471
472 // store the screen's depth buffer 472 // store the screen's depth buffer
473 DepthBuffers.push_back(new SDepthSurface()); 473 DepthBuffers.push_back(new SDepthSurface());
474 if (SUCCEEDED(pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface)))) 474 if (SUCCEEDED(pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface))))
475 { 475 {
476 D3DSURFACE_DESC desc; 476 D3DSURFACE_DESC desc;
477 DepthBuffers[0]->Surface->GetDesc(&desc); 477 DepthBuffers[0]->Surface->GetDesc(&desc);
478 DepthBuffers[0]->Size.set(desc.Width, desc.Height); 478 DepthBuffers[0]->Size.set(desc.Width, desc.Height);
479 } 479 }
480 else 480 else
481 { 481 {
482 os::Printer::log("Was not able to get main depth buffer.", ELL_ERROR); 482 os::Printer::log("Was not able to get main depth buffer.", ELL_ERROR);
483 return false; 483 return false;
484 } 484 }
485 485
486 D3DColorFormat = D3DFMT_A8R8G8B8; 486 D3DColorFormat = D3DFMT_A8R8G8B8;
487 IDirect3DSurface9* bb=0; 487 IDirect3DSurface9* bb=0;
488 if (SUCCEEDED(pID3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb))) 488 if (SUCCEEDED(pID3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)))
489 { 489 {
490 D3DSURFACE_DESC desc; 490 D3DSURFACE_DESC desc;
491 bb->GetDesc(&desc); 491 bb->GetDesc(&desc);
492 D3DColorFormat = desc.Format; 492 D3DColorFormat = desc.Format;
493 493
494 if (D3DColorFormat == D3DFMT_X8R8G8B8) 494 if (D3DColorFormat == D3DFMT_X8R8G8B8)
495 D3DColorFormat = D3DFMT_A8R8G8B8; 495 D3DColorFormat = D3DFMT_A8R8G8B8;
496 496
497 bb->Release(); 497 bb->Release();
498 } 498 }
499 ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat); 499 ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat);
500 500
501 #ifdef _IRR_COMPILE_WITH_CG_ 501 #ifdef _IRR_COMPILE_WITH_CG_
502 CgContext = cgCreateContext(); 502 CgContext = cgCreateContext();
503 cgD3D9SetDevice(pID3DDevice); 503 cgD3D9SetDevice(pID3DDevice);
504 #endif 504 #endif
505 505
506 // so far so good. 506 // so far so good.
507 return true; 507 return true;
508} 508}
509 509
510 510
511//! applications must call this method before performing any rendering. returns false if failed. 511//! applications must call this method before performing any rendering. returns false if failed.
512bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, 512bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
513 const SExposedVideoData& videoData, core::rect<s32>* sourceRect) 513 const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
514{ 514{
515 CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); 515 CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect);
516 WindowId = (HWND)videoData.D3D9.HWnd; 516 WindowId = (HWND)videoData.D3D9.HWnd;
517 SceneSourceRect = sourceRect; 517 SceneSourceRect = sourceRect;
518 518
519 if (!pID3DDevice) 519 if (!pID3DDevice)
520 return false; 520 return false;
521 521
522 HRESULT hr; 522 HRESULT hr;
523 if (DeviceLost) 523 if (DeviceLost)
524 { 524 {
525 if (FAILED(hr = pID3DDevice->TestCooperativeLevel())) 525 if (FAILED(hr = pID3DDevice->TestCooperativeLevel()))
526 { 526 {
527 if (hr == D3DERR_DEVICELOST) 527 if (hr == D3DERR_DEVICELOST)
528 { 528 {
529 Sleep(100); 529 Sleep(100);
530 hr = pID3DDevice->TestCooperativeLevel(); 530 hr = pID3DDevice->TestCooperativeLevel();
531 if (hr == D3DERR_DEVICELOST) 531 if (hr == D3DERR_DEVICELOST)
532 return false; 532 return false;
533 } 533 }
534 534
535 if ((hr == D3DERR_DEVICENOTRESET) && !reset()) 535 if ((hr == D3DERR_DEVICENOTRESET) && !reset())
536 return false; 536 return false;
537 } 537 }
538 } 538 }
539 539
540 DWORD flags = 0; 540 DWORD flags = 0;
541 541
542 if (backBuffer) 542 if (backBuffer)
543 flags |= D3DCLEAR_TARGET; 543 flags |= D3DCLEAR_TARGET;
544 544
545 if (zBuffer) 545 if (zBuffer)
546 flags |= D3DCLEAR_ZBUFFER; 546 flags |= D3DCLEAR_ZBUFFER;
547 547
548 if (Params.Stencilbuffer) 548 if (Params.Stencilbuffer)
549 flags |= D3DCLEAR_STENCIL; 549 flags |= D3DCLEAR_STENCIL;
550 550
551 if (flags) 551 if (flags)
552 { 552 {
553 hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); 553 hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0);
554 if (FAILED(hr)) 554 if (FAILED(hr))
555 os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING); 555 os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING);
556 } 556 }
557 557
558 hr = pID3DDevice->BeginScene(); 558 hr = pID3DDevice->BeginScene();
559 if (FAILED(hr)) 559 if (FAILED(hr))
560 { 560 {
561 os::Printer::log("DIRECT3D9 begin scene failed.", ELL_WARNING); 561 os::Printer::log("DIRECT3D9 begin scene failed.", ELL_WARNING);
562 return false; 562 return false;
563 } 563 }
564 564
565 return true; 565 return true;
566} 566}
567 567
568 568
569//! applications must call this method after performing any rendering. returns false if failed. 569//! applications must call this method after performing any rendering. returns false if failed.
570bool CD3D9Driver::endScene() 570bool CD3D9Driver::endScene()
571{ 571{
572 CNullDriver::endScene(); 572 CNullDriver::endScene();
573 DriverWasReset=false; 573 DriverWasReset=false;
574 574
575 HRESULT hr = pID3DDevice->EndScene(); 575 HRESULT hr = pID3DDevice->EndScene();
576 if (FAILED(hr)) 576 if (FAILED(hr))
577 { 577 {
578 os::Printer::log("DIRECT3D9 end scene failed.", ELL_WARNING); 578 os::Printer::log("DIRECT3D9 end scene failed.", ELL_WARNING);
579 return false; 579 return false;
580 } 580 }
581 581
582 RECT* srcRct = 0; 582 RECT* srcRct = 0;
583 RECT sourceRectData; 583 RECT sourceRectData;
584 if ( SceneSourceRect ) 584 if ( SceneSourceRect )
585 { 585 {
586 srcRct = &sourceRectData; 586 srcRct = &sourceRectData;
587 sourceRectData.left = SceneSourceRect->UpperLeftCorner.X; 587 sourceRectData.left = SceneSourceRect->UpperLeftCorner.X;
588 sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y; 588 sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y;
589 sourceRectData.right = SceneSourceRect->LowerRightCorner.X; 589 sourceRectData.right = SceneSourceRect->LowerRightCorner.X;
590 sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; 590 sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y;
591 } 591 }
592 592
593 IDirect3DSwapChain9* swChain; 593 IDirect3DSwapChain9* swChain;
594 hr = pID3DDevice->GetSwapChain(0, &swChain); 594 hr = pID3DDevice->GetSwapChain(0, &swChain);
595 DWORD flags = (Params.HandleSRGB && (Caps.Caps3&D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION))?D3DPRESENT_LINEAR_CONTENT:0; 595 DWORD flags = (Params.HandleSRGB && (Caps.Caps3&D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION))?D3DPRESENT_LINEAR_CONTENT:0;
596 hr = swChain->Present(srcRct, NULL, WindowId, NULL, flags); 596 hr = swChain->Present(srcRct, NULL, WindowId, NULL, flags);
597 swChain->Release(); 597 swChain->Release();
598 598
599 if (SUCCEEDED(hr)) 599 if (SUCCEEDED(hr))
600 return true; 600 return true;
601 601
602 if (hr == D3DERR_DEVICELOST) 602 if (hr == D3DERR_DEVICELOST)
603 { 603 {
604 DeviceLost = true; 604 DeviceLost = true;
605 os::Printer::log("Present failed", "DIRECT3D9 device lost.", ELL_WARNING); 605 os::Printer::log("Present failed", "DIRECT3D9 device lost.", ELL_WARNING);
606 } 606 }
607#ifdef D3DERR_DEVICEREMOVED 607#ifdef D3DERR_DEVICEREMOVED
608 else if (hr == D3DERR_DEVICEREMOVED) 608 else if (hr == D3DERR_DEVICEREMOVED)
609 { 609 {
610 os::Printer::log("Present failed", "Device removed.", ELL_WARNING); 610 os::Printer::log("Present failed", "Device removed.", ELL_WARNING);
611 } 611 }
612#endif 612#endif
613 else if (hr == D3DERR_INVALIDCALL) 613 else if (hr == D3DERR_INVALIDCALL)
614 { 614 {
615 os::Printer::log("Present failed", "Invalid Call", ELL_WARNING); 615 os::Printer::log("Present failed", "Invalid Call", ELL_WARNING);
616 } 616 }
617 else 617 else
618 os::Printer::log("DIRECT3D9 present failed.", ELL_WARNING); 618 os::Printer::log("DIRECT3D9 present failed.", ELL_WARNING);
619 return false; 619 return false;
620} 620}
621 621
622 622
623//! queries the features of the driver, returns true if feature is available 623//! queries the features of the driver, returns true if feature is available
624bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const 624bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
625{ 625{
626 if (!FeatureEnabled[feature]) 626 if (!FeatureEnabled[feature])
627 return false; 627 return false;
628 628
629 switch (feature) 629 switch (feature)
630 { 630 {
631 case EVDF_MULTITEXTURE: 631 case EVDF_MULTITEXTURE:
632 case EVDF_BILINEAR_FILTER: 632 case EVDF_BILINEAR_FILTER:
633 return true; 633 return true;
634 case EVDF_RENDER_TO_TARGET: 634 case EVDF_RENDER_TO_TARGET:
635 return Caps.NumSimultaneousRTs > 0; 635 return Caps.NumSimultaneousRTs > 0;
636 case EVDF_HARDWARE_TL: 636 case EVDF_HARDWARE_TL:
637 return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; 637 return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0;
638 case EVDF_MIP_MAP: 638 case EVDF_MIP_MAP:
639 return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; 639 return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0;
640 case EVDF_MIP_MAP_AUTO_UPDATE: 640 case EVDF_MIP_MAP_AUTO_UPDATE:
641 // always return false because a lot of drivers claim they do 641 // always return false because a lot of drivers claim they do
642 // this but actually don't do this at all. 642 // this but actually don't do this at all.
643 return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0; 643 return false; //(Caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0;
644 case EVDF_STENCIL_BUFFER: 644 case EVDF_STENCIL_BUFFER:
645 return Params.Stencilbuffer && Caps.StencilCaps; 645 return Params.Stencilbuffer && Caps.StencilCaps;
646 case EVDF_VERTEX_SHADER_1_1: 646 case EVDF_VERTEX_SHADER_1_1:
647 return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); 647 return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1);
648 case EVDF_VERTEX_SHADER_2_0: 648 case EVDF_VERTEX_SHADER_2_0:
649 return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); 649 return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0);
650 case EVDF_VERTEX_SHADER_3_0: 650 case EVDF_VERTEX_SHADER_3_0:
651 return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); 651 return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0);
652 case EVDF_PIXEL_SHADER_1_1: 652 case EVDF_PIXEL_SHADER_1_1:
653 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); 653 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1);
654 case EVDF_PIXEL_SHADER_1_2: 654 case EVDF_PIXEL_SHADER_1_2:
655 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); 655 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2);
656 case EVDF_PIXEL_SHADER_1_3: 656 case EVDF_PIXEL_SHADER_1_3:
657 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); 657 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3);
658 case EVDF_PIXEL_SHADER_1_4: 658 case EVDF_PIXEL_SHADER_1_4:
659 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); 659 return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4);
660 case EVDF_PIXEL_SHADER_2_0: 660 case EVDF_PIXEL_SHADER_2_0:
661 return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); 661 return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0);
662 case EVDF_PIXEL_SHADER_3_0: 662 case EVDF_PIXEL_SHADER_3_0:
663 return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); 663 return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0);
664 case EVDF_HLSL: 664 case EVDF_HLSL:
665 return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); 665 return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1);
666 case EVDF_TEXTURE_NSQUARE: 666 case EVDF_TEXTURE_NSQUARE:
667 return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0; 667 return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0;
668 case EVDF_TEXTURE_NPOT: 668 case EVDF_TEXTURE_NPOT:
669 return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; 669 return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0;
670 case EVDF_COLOR_MASK: 670 case EVDF_COLOR_MASK:
671 return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; 671 return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
672 case EVDF_MULTIPLE_RENDER_TARGETS: 672 case EVDF_MULTIPLE_RENDER_TARGETS:
673 return Caps.NumSimultaneousRTs > 1; 673 return Caps.NumSimultaneousRTs > 1;
674 case EVDF_MRT_COLOR_MASK: 674 case EVDF_MRT_COLOR_MASK:
675 return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_INDEPENDENTWRITEMASKS) != 0; 675 return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_INDEPENDENTWRITEMASKS) != 0;
676 case EVDF_MRT_BLEND: 676 case EVDF_MRT_BLEND:
677 return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0; 677 return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0;
678 case EVDF_OCCLUSION_QUERY: 678 case EVDF_OCCLUSION_QUERY:
679 return OcclusionQuerySupport; 679 return OcclusionQuerySupport;
680 case EVDF_POLYGON_OFFSET: 680 case EVDF_POLYGON_OFFSET:
681 return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0; 681 return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0;
682 case EVDF_BLEND_OPERATIONS: 682 case EVDF_BLEND_OPERATIONS:
683 case EVDF_TEXTURE_MATRIX: 683 case EVDF_TEXTURE_MATRIX:
684#ifdef _IRR_COMPILE_WITH_CG_ 684#ifdef _IRR_COMPILE_WITH_CG_
685 // available iff. define is present 685 // available iff. define is present
686 case EVDF_CG: 686 case EVDF_CG:
687#endif 687#endif
688 return true; 688 return true;
689 default: 689 default:
690 return false; 690 return false;
691 }; 691 };
692} 692}
693 693
694 694
695//! sets transformation 695//! sets transformation
696void CD3D9Driver::setTransform(E_TRANSFORMATION_STATE state, 696void CD3D9Driver::setTransform(E_TRANSFORMATION_STATE state,
697 const core::matrix4& mat) 697 const core::matrix4& mat)
698{ 698{
699 Transformation3DChanged = true; 699 Transformation3DChanged = true;
700 700
701 switch(state) 701 switch(state)
702 { 702 {
703 case ETS_VIEW: 703 case ETS_VIEW:
704 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); 704 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer()));
705 break; 705 break;
706 case ETS_WORLD: 706 case ETS_WORLD:
707 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); 707 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer()));
708 break; 708 break;
709 case ETS_PROJECTION: 709 case ETS_PROJECTION:
710 pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); 710 pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer()));
711 break; 711 break;
712 case ETS_COUNT: 712 case ETS_COUNT:
713 return; 713 return;
714 default: 714 default:
715 if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES) 715 if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES)
716 { 716 {
717 if (mat.isIdentity()) 717 if (mat.isIdentity())
718 pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); 718 pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
719 else 719 else
720 { 720 {
721 pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); 721 pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 );
722 pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), 722 pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )),
723 (D3DMATRIX*)((void*)mat.pointer())); 723 (D3DMATRIX*)((void*)mat.pointer()));
724 } 724 }
725 } 725 }
726 break; 726 break;
727 } 727 }
728 728
729 Matrices[state] = mat; 729 Matrices[state] = mat;
730} 730}
731 731
732 732
733//! sets the current Texture 733//! sets the current Texture
734bool CD3D9Driver::setActiveTexture(u32 stage, const video::ITexture* texture) 734bool CD3D9Driver::setActiveTexture(u32 stage, const video::ITexture* texture)
735{ 735{
736 if (CurrentTexture[stage] == texture) 736 if (CurrentTexture[stage] == texture)
737 return true; 737 return true;
738 738
739 if (texture && texture->getDriverType() != EDT_DIRECT3D9) 739 if (texture && texture->getDriverType() != EDT_DIRECT3D9)
740 { 740 {
741 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); 741 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
742 return false; 742 return false;
743 } 743 }
744 744
745 CurrentTexture[stage] = texture; 745 CurrentTexture[stage] = texture;
746 746
747 if (!texture) 747 if (!texture)
748 { 748 {
749 pID3DDevice->SetTexture(stage, 0); 749 pID3DDevice->SetTexture(stage, 0);
750 pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); 750 pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE );
751 } 751 }
752 else 752 else
753 { 753 {
754 pID3DDevice->SetTexture(stage, ((const CD3D9Texture*)texture)->getDX9Texture()); 754 pID3DDevice->SetTexture(stage, ((const CD3D9Texture*)texture)->getDX9Texture());
755 } 755 }
756 return true; 756 return true;
757} 757}
758 758
759 759
760//! sets a material 760//! sets a material
761void CD3D9Driver::setMaterial(const SMaterial& material) 761void CD3D9Driver::setMaterial(const SMaterial& material)
762{ 762{
763 Material = material; 763 Material = material;
764 OverrideMaterial.apply(Material); 764 OverrideMaterial.apply(Material);
765 765
766 for (u32 i=0; i<MaxTextureUnits; ++i) 766 for (u32 i=0; i<MaxTextureUnits; ++i)
767 { 767 {
768 setActiveTexture(i, Material.getTexture(i)); 768 setActiveTexture(i, Material.getTexture(i));
769 setTransform((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), 769 setTransform((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ),
770 material.getTextureMatrix(i)); 770 material.getTextureMatrix(i));
771 } 771 }
772} 772}
773 773
774 774
775//! returns a device dependent texture from a software surface (IImage) 775//! returns a device dependent texture from a software surface (IImage)
776video::ITexture* CD3D9Driver::createDeviceDependentTexture(IImage* surface,const io::path& name, void* mipmapData) 776video::ITexture* CD3D9Driver::createDeviceDependentTexture(IImage* surface,const io::path& name, void* mipmapData)
777{ 777{
778 return new CD3D9Texture(surface, this, TextureCreationFlags, name, mipmapData); 778 return new CD3D9Texture(surface, this, TextureCreationFlags, name, mipmapData);
779} 779}
780 780
781 781
782//! Enables or disables a texture creation flag. 782//! Enables or disables a texture creation flag.
783void CD3D9Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, 783void CD3D9Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag,
784 bool enabled) 784 bool enabled)
785{ 785{
786 if (flag == video::ETCF_CREATE_MIP_MAPS && !queryFeature(EVDF_MIP_MAP)) 786 if (flag == video::ETCF_CREATE_MIP_MAPS && !queryFeature(EVDF_MIP_MAP))
787 enabled = false; 787 enabled = false;
788 788
789 CNullDriver::setTextureCreationFlag(flag, enabled); 789 CNullDriver::setTextureCreationFlag(flag, enabled);
790} 790}
791 791
792 792
793//! sets a render target 793//! sets a render target
794bool CD3D9Driver::setRenderTarget(video::ITexture* texture, 794bool CD3D9Driver::setRenderTarget(video::ITexture* texture,
795 bool clearBackBuffer, bool clearZBuffer, SColor color) 795 bool clearBackBuffer, bool clearZBuffer, SColor color)
796{ 796{
797 // check for right driver type 797 // check for right driver type
798 798
799 if (texture && texture->getDriverType() != EDT_DIRECT3D9) 799 if (texture && texture->getDriverType() != EDT_DIRECT3D9)
800 { 800 {
801 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); 801 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
802 return false; 802 return false;
803 } 803 }
804 804
805 // check for valid render target 805 // check for valid render target
806 806
807 if (texture && !texture->isRenderTarget()) 807 if (texture && !texture->isRenderTarget())
808 { 808 {
809 os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); 809 os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR);
810 return false; 810 return false;
811 } 811 }
812 812
813 CD3D9Texture* tex = static_cast<CD3D9Texture*>(texture); 813 CD3D9Texture* tex = static_cast<CD3D9Texture*>(texture);
814 814
815 // check if we should set the previous RT back 815 // check if we should set the previous RT back
816 816
817 bool ret = true; 817 bool ret = true;
818 818
819 for(u32 i = 1; i < NumSetMRTs; i++) 819 for(u32 i = 1; i < NumSetMRTs; i++)
820 { 820 {
821 // First texture handled elsewhere 821 // First texture handled elsewhere
822 pID3DDevice->SetRenderTarget(i, NULL); 822 pID3DDevice->SetRenderTarget(i, NULL);
823 } 823 }
824 if (tex == 0) 824 if (tex == 0)
825 { 825 {
826 if (PrevRenderTarget) 826 if (PrevRenderTarget)
827 { 827 {
828 if (FAILED(pID3DDevice->SetRenderTarget(0, PrevRenderTarget))) 828 if (FAILED(pID3DDevice->SetRenderTarget(0, PrevRenderTarget)))
829 { 829 {
830 os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); 830 os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR);
831 ret = false; 831 ret = false;
832 } 832 }
833 if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthBuffers[0]->Surface))) 833 if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthBuffers[0]->Surface)))
834 { 834 {
835 os::Printer::log("Error: Could not set main depth buffer.", ELL_ERROR); 835 os::Printer::log("Error: Could not set main depth buffer.", ELL_ERROR);
836 } 836 }
837 837
838 CurrentRendertargetSize = core::dimension2d<u32>(0,0); 838 CurrentRendertargetSize = core::dimension2d<u32>(0,0);
839 PrevRenderTarget->Release(); 839 PrevRenderTarget->Release();
840 PrevRenderTarget = 0; 840 PrevRenderTarget = 0;
841 } 841 }
842 } 842 }
843 else 843 else
844 { 844 {
845 // we want to set a new target. so do this. 845 // we want to set a new target. so do this.
846 846
847 // store previous target 847 // store previous target
848 848
849 if (!PrevRenderTarget) 849 if (!PrevRenderTarget)
850 { 850 {
851 if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget))) 851 if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget)))
852 { 852 {
853 os::Printer::log("Could not get previous render target.", ELL_ERROR); 853 os::Printer::log("Could not get previous render target.", ELL_ERROR);
854 return false; 854 return false;
855 } 855 }
856 } 856 }
857 857
858 // set new render target 858 // set new render target
859 859
860 if (FAILED(pID3DDevice->SetRenderTarget(0, tex->getRenderTargetSurface()))) 860 if (FAILED(pID3DDevice->SetRenderTarget(0, tex->getRenderTargetSurface())))
861 { 861 {
862 os::Printer::log("Error: Could not set render target.", ELL_ERROR); 862 os::Printer::log("Error: Could not set render target.", ELL_ERROR);
863 return false; 863 return false;
864 } 864 }
865 CurrentRendertargetSize = tex->getSize(); 865 CurrentRendertargetSize = tex->getSize();
866 866
867 if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface))) 867 if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface)))
868 { 868 {
869 os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR); 869 os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR);
870 } 870 }
871 } 871 }
872 Transformation3DChanged=true; 872 Transformation3DChanged=true;
873 873
874 if (clearBackBuffer || clearZBuffer) 874 if (clearBackBuffer || clearZBuffer)
875 { 875 {
876 DWORD flags = 0; 876 DWORD flags = 0;
877 877
878 if (clearBackBuffer) 878 if (clearBackBuffer)
879 flags |= D3DCLEAR_TARGET; 879 flags |= D3DCLEAR_TARGET;
880 880
881 if (clearZBuffer) 881 if (clearZBuffer)
882 flags |= D3DCLEAR_ZBUFFER; 882 flags |= D3DCLEAR_ZBUFFER;
883 883
884 pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); 884 pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0);
885 } 885 }
886 886
887 return ret; 887 return ret;
888} 888}
889 889
890 890
891//! Sets multiple render targets 891//! Sets multiple render targets
892bool CD3D9Driver::setRenderTarget(const core::array<video::IRenderTarget>& targets, 892bool CD3D9Driver::setRenderTarget(const core::array<video::IRenderTarget>& targets,
893 bool clearBackBuffer, bool clearZBuffer, SColor color) 893 bool clearBackBuffer, bool clearZBuffer, SColor color)
894{ 894{
895 if (targets.size()==0) 895 if (targets.size()==0)
896 return setRenderTarget(0, clearBackBuffer, clearZBuffer, color); 896 return setRenderTarget(0, clearBackBuffer, clearZBuffer, color);
897 897
898 u32 maxMultipleRTTs = core::min_(MaxMRTs, targets.size()); 898 u32 maxMultipleRTTs = core::min_(MaxMRTs, targets.size());
899 899
900 for (u32 i = 0; i < maxMultipleRTTs; ++i) 900 for (u32 i = 0; i < maxMultipleRTTs; ++i)
901 { 901 {
902 if (targets[i].TargetType != ERT_RENDER_TEXTURE || !targets[i].RenderTexture) 902 if (targets[i].TargetType != ERT_RENDER_TEXTURE || !targets[i].RenderTexture)
903 { 903 {
904 maxMultipleRTTs = i; 904 maxMultipleRTTs = i;
905 os::Printer::log("Missing texture for MRT.", ELL_WARNING); 905 os::Printer::log("Missing texture for MRT.", ELL_WARNING);
906 break; 906 break;
907 } 907 }
908 908
909 // check for right driver type 909 // check for right driver type
910 910
911 if (targets[i].RenderTexture->getDriverType() != EDT_DIRECT3D9) 911 if (targets[i].RenderTexture->getDriverType() != EDT_DIRECT3D9)
912 { 912 {
913 maxMultipleRTTs = i; 913 maxMultipleRTTs = i;
914 os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING); 914 os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING);
915 break; 915 break;
916 } 916 }
917 917
918 // check for valid render target 918 // check for valid render target
919 919
920 if (!targets[i].RenderTexture->isRenderTarget()) 920 if (!targets[i].RenderTexture->isRenderTarget())
921 { 921 {
922 maxMultipleRTTs = i; 922 maxMultipleRTTs = i;
923 os::Printer::log("Tried to set a non render target texture as render target.", ELL_WARNING); 923 os::Printer::log("Tried to set a non render target texture as render target.", ELL_WARNING);
924 break; 924 break;
925 } 925 }
926 926
927 // check for valid size 927 // check for valid size
928 928
929 if (targets[0].RenderTexture->getSize() != targets[i].RenderTexture->getSize()) 929 if (targets[0].RenderTexture->getSize() != targets[i].RenderTexture->getSize())
930 { 930 {
931 maxMultipleRTTs = i; 931 maxMultipleRTTs = i;
932 os::Printer::log("Render target texture has wrong size.", ELL_WARNING); 932 os::Printer::log("Render target texture has wrong size.", ELL_WARNING);
933 break; 933 break;
934 } 934 }
935 } 935 }
936 if (maxMultipleRTTs==0) 936 if (maxMultipleRTTs==0)
937 { 937 {
938 os::Printer::log("Fatal Error: No valid MRT found.", ELL_ERROR); 938 os::Printer::log("Fatal Error: No valid MRT found.", ELL_ERROR);
939 return false; 939 return false;
940 } 940 }
941 941
942 CD3D9Texture* tex = static_cast<CD3D9Texture*>(targets[0].RenderTexture); 942 CD3D9Texture* tex = static_cast<CD3D9Texture*>(targets[0].RenderTexture);
943 943
944 // check if we should set the previous RT back 944 // check if we should set the previous RT back
945 945
946 bool ret = true; 946 bool ret = true;
947 947
948 // we want to set a new target. so do this. 948 // we want to set a new target. so do this.
949 // store previous target 949 // store previous target
950 950
951 if (!PrevRenderTarget) 951 if (!PrevRenderTarget)
952 { 952 {
953 if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget))) 953 if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget)))
954 { 954 {
955 os::Printer::log("Could not get previous render target.", ELL_ERROR); 955 os::Printer::log("Could not get previous render target.", ELL_ERROR);
956 return false; 956 return false;
957 } 957 }
958 } 958 }
959 959
960 // set new render target 960 // set new render target
961 961
962 // In d3d9 we have at most 4 MRTs, so the following is enough 962 // In d3d9 we have at most 4 MRTs, so the following is enough
963 D3DRENDERSTATETYPE colorWrite[4]={D3DRS_COLORWRITEENABLE, D3DRS_COLORWRITEENABLE1, D3DRS_COLORWRITEENABLE2, D3DRS_COLORWRITEENABLE3}; 963 D3DRENDERSTATETYPE colorWrite[4]={D3DRS_COLORWRITEENABLE, D3DRS_COLORWRITEENABLE1, D3DRS_COLORWRITEENABLE2, D3DRS_COLORWRITEENABLE3};
964 for (u32 i = 0; i < maxMultipleRTTs; ++i) 964 for (u32 i = 0; i < maxMultipleRTTs; ++i)
965 { 965 {
966 if (FAILED(pID3DDevice->SetRenderTarget(i, static_cast<CD3D9Texture*>(targets[i].RenderTexture)->getRenderTargetSurface()))) 966 if (FAILED(pID3DDevice->SetRenderTarget(i, static_cast<CD3D9Texture*>(targets[i].RenderTexture)->getRenderTargetSurface())))
967 { 967 {
968 os::Printer::log("Error: Could not set render target.", ELL_ERROR); 968 os::Printer::log("Error: Could not set render target.", ELL_ERROR);
969 return false; 969 return false;
970 } 970 }
971 if (i<4 && (i==0 || queryFeature(EVDF_MRT_COLOR_MASK))) 971 if (i<4 && (i==0 || queryFeature(EVDF_MRT_COLOR_MASK)))
972 { 972 {
973 const DWORD flag = 973 const DWORD flag =
974 ((targets[i].ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | 974 ((targets[i].ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) |
975 ((targets[i].ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | 975 ((targets[i].ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) |
976 ((targets[i].ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | 976 ((targets[i].ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) |
977 ((targets[i].ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); 977 ((targets[i].ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0);
978 pID3DDevice->SetRenderState(colorWrite[i], flag); 978 pID3DDevice->SetRenderState(colorWrite[i], flag);
979 } 979 }
980 } 980 }
981 for(u32 i = maxMultipleRTTs; i < NumSetMRTs; i++) 981 for(u32 i = maxMultipleRTTs; i < NumSetMRTs; i++)
982 { 982 {
983 pID3DDevice->SetRenderTarget(i, NULL); 983 pID3DDevice->SetRenderTarget(i, NULL);
984 } 984 }
985 NumSetMRTs=maxMultipleRTTs; 985 NumSetMRTs=maxMultipleRTTs;
986 986
987 CurrentRendertargetSize = tex->getSize(); 987 CurrentRendertargetSize = tex->getSize();
988 988
989 if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface))) 989 if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface)))
990 { 990 {
991 os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR); 991 os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR);
992 } 992 }
993 993
994 if (clearBackBuffer || clearZBuffer) 994 if (clearBackBuffer || clearZBuffer)
995 { 995 {
996 DWORD flags = 0; 996 DWORD flags = 0;
997 997
998 if (clearBackBuffer) 998 if (clearBackBuffer)
999 flags |= D3DCLEAR_TARGET; 999 flags |= D3DCLEAR_TARGET;
1000 1000
1001 if (clearZBuffer) 1001 if (clearZBuffer)
1002 flags |= D3DCLEAR_ZBUFFER; 1002 flags |= D3DCLEAR_ZBUFFER;
1003 1003
1004 pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); 1004 pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0);
1005 } 1005 }
1006 1006
1007 return ret; 1007 return ret;
1008} 1008}
1009 1009
1010 1010
1011//! sets a viewport 1011//! sets a viewport
1012void CD3D9Driver::setViewPort(const core::rect<s32>& area) 1012void CD3D9Driver::setViewPort(const core::rect<s32>& area)
1013{ 1013{
1014 core::rect<s32> vp = area; 1014 core::rect<s32> vp = area;
1015 core::rect<s32> rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height); 1015 core::rect<s32> rendert(0,0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height);
1016 vp.clipAgainst(rendert); 1016 vp.clipAgainst(rendert);
1017 if (vp.getHeight()>0 && vp.getWidth()>0) 1017 if (vp.getHeight()>0 && vp.getWidth()>0)
1018 { 1018 {
1019 D3DVIEWPORT9 viewPort; 1019 D3DVIEWPORT9 viewPort;
1020 viewPort.X = vp.UpperLeftCorner.X; 1020 viewPort.X = vp.UpperLeftCorner.X;
1021 viewPort.Y = vp.UpperLeftCorner.Y; 1021 viewPort.Y = vp.UpperLeftCorner.Y;
1022 viewPort.Width = vp.getWidth(); 1022 viewPort.Width = vp.getWidth();
1023 viewPort.Height = vp.getHeight(); 1023 viewPort.Height = vp.getHeight();
1024 viewPort.MinZ = 0.0f; 1024 viewPort.MinZ = 0.0f;
1025 viewPort.MaxZ = 1.0f; 1025 viewPort.MaxZ = 1.0f;
1026 1026
1027 HRESULT hr = pID3DDevice->SetViewport(&viewPort); 1027 HRESULT hr = pID3DDevice->SetViewport(&viewPort);
1028 if (FAILED(hr)) 1028 if (FAILED(hr))
1029 os::Printer::log("Failed setting the viewport.", ELL_WARNING); 1029 os::Printer::log("Failed setting the viewport.", ELL_WARNING);
1030 else 1030 else
1031 ViewPort = vp; 1031 ViewPort = vp;
1032 } 1032 }
1033} 1033}
1034 1034
1035 1035
1036//! gets the area of the current viewport 1036//! gets the area of the current viewport
1037const core::rect<s32>& CD3D9Driver::getViewPort() const 1037const core::rect<s32>& CD3D9Driver::getViewPort() const
1038{ 1038{
1039 return ViewPort; 1039 return ViewPort;
1040} 1040}
1041 1041
1042 1042
1043bool CD3D9Driver::updateVertexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) 1043bool CD3D9Driver::updateVertexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer)
1044{ 1044{
1045 if (!hwBuffer) 1045 if (!hwBuffer)
1046 return false; 1046 return false;
1047 1047
1048 const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer; 1048 const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer;
1049 const void* vertices=mb->getVertices(); 1049 const void* vertices=mb->getVertices();
1050 const u32 vertexCount=mb->getVertexCount(); 1050 const u32 vertexCount=mb->getVertexCount();
1051 const E_VERTEX_TYPE vType=mb->getVertexType(); 1051 const E_VERTEX_TYPE vType=mb->getVertexType();
1052 const u32 vertexSize = getVertexPitchFromType(vType); 1052 const u32 vertexSize = getVertexPitchFromType(vType);
1053 const u32 bufSize = vertexSize * vertexCount; 1053 const u32 bufSize = vertexSize * vertexCount;
1054 1054
1055 if (!hwBuffer->vertexBuffer || (bufSize > hwBuffer->vertexBufferSize)) 1055 if (!hwBuffer->vertexBuffer || (bufSize > hwBuffer->vertexBufferSize))
1056 { 1056 {
1057 if (hwBuffer->vertexBuffer) 1057 if (hwBuffer->vertexBuffer)
1058 { 1058 {
1059 hwBuffer->vertexBuffer->Release(); 1059 hwBuffer->vertexBuffer->Release();
1060 hwBuffer->vertexBuffer=0; 1060 hwBuffer->vertexBuffer=0;
1061 } 1061 }
1062 1062
1063 DWORD FVF; 1063 DWORD FVF;
1064 // Get the vertex sizes and cvf 1064 // Get the vertex sizes and cvf
1065 switch (vType) 1065 switch (vType)
1066 { 1066 {
1067 case EVT_STANDARD: 1067 case EVT_STANDARD:
1068 FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1; 1068 FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1;
1069 break; 1069 break;
1070 case EVT_2TCOORDS: 1070 case EVT_2TCOORDS:
1071 FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2; 1071 FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2;
1072 break; 1072 break;
1073 case EVT_TANGENTS: 1073 case EVT_TANGENTS:
1074 FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3; 1074 FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3;
1075 break; 1075 break;
1076 default: 1076 default:
1077 return false; 1077 return false;
1078 } 1078 }
1079 1079
1080 DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY 1080 DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY
1081 if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC) 1081 if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC)
1082 flags |= D3DUSAGE_DYNAMIC; 1082 flags |= D3DUSAGE_DYNAMIC;
1083 1083
1084 if (FAILED(pID3DDevice->CreateVertexBuffer(bufSize, flags, FVF, D3DPOOL_DEFAULT, &hwBuffer->vertexBuffer, NULL))) 1084 if (FAILED(pID3DDevice->CreateVertexBuffer(bufSize, flags, FVF, D3DPOOL_DEFAULT, &hwBuffer->vertexBuffer, NULL)))
1085 return false; 1085 return false;
1086 hwBuffer->vertexBufferSize = bufSize; 1086 hwBuffer->vertexBufferSize = bufSize;
1087 1087
1088 flags = 0; // SIO2: Reset flags before Lock 1088 flags = 0; // SIO2: Reset flags before Lock
1089 if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC) 1089 if (hwBuffer->Mapped_Vertex != scene::EHM_STATIC)
1090 flags = D3DLOCK_DISCARD; 1090 flags = D3DLOCK_DISCARD;
1091 1091
1092 void* lockedBuffer = 0; 1092 void* lockedBuffer = 0;
1093 hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, flags); 1093 hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, flags);
1094 memcpy(lockedBuffer, vertices, bufSize); 1094 memcpy(lockedBuffer, vertices, bufSize);
1095 hwBuffer->vertexBuffer->Unlock(); 1095 hwBuffer->vertexBuffer->Unlock();
1096 } 1096 }
1097 else 1097 else
1098 { 1098 {
1099 void* lockedBuffer = 0; 1099 void* lockedBuffer = 0;
1100 hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, D3DLOCK_DISCARD); 1100 hwBuffer->vertexBuffer->Lock(0, bufSize, (void**)&lockedBuffer, D3DLOCK_DISCARD);
1101 memcpy(lockedBuffer, vertices, bufSize); 1101 memcpy(lockedBuffer, vertices, bufSize);
1102 hwBuffer->vertexBuffer->Unlock(); 1102 hwBuffer->vertexBuffer->Unlock();
1103 } 1103 }
1104 1104
1105 return true; 1105 return true;
1106} 1106}
1107 1107
1108 1108
1109bool CD3D9Driver::updateIndexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) 1109bool CD3D9Driver::updateIndexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer)
1110{ 1110{
1111 if (!hwBuffer) 1111 if (!hwBuffer)
1112 return false; 1112 return false;
1113 1113
1114 const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer; 1114 const scene::IMeshBuffer* mb = hwBuffer->MeshBuffer;
1115 const u16* indices=mb->getIndices(); 1115 const u16* indices=mb->getIndices();
1116 const u32 indexCount=mb->getIndexCount(); 1116 const u32 indexCount=mb->getIndexCount();
1117 u32 indexSize = 2; 1117 u32 indexSize = 2;
1118 D3DFORMAT indexType=D3DFMT_UNKNOWN; 1118 D3DFORMAT indexType=D3DFMT_UNKNOWN;
1119 switch (mb->getIndexType()) 1119 switch (mb->getIndexType())
1120 { 1120 {
1121 case EIT_16BIT: 1121 case EIT_16BIT:
1122 { 1122 {
1123 indexType=D3DFMT_INDEX16; 1123 indexType=D3DFMT_INDEX16;
1124 indexSize = 2; 1124 indexSize = 2;
1125 break; 1125 break;
1126 } 1126 }
1127 case EIT_32BIT: 1127 case EIT_32BIT:
1128 { 1128 {
1129 indexType=D3DFMT_INDEX32; 1129 indexType=D3DFMT_INDEX32;
1130 indexSize = 4; 1130 indexSize = 4;
1131 break; 1131 break;
1132 } 1132 }
1133 } 1133 }
1134 1134
1135 const u32 bufSize = indexSize * indexCount; 1135 const u32 bufSize = indexSize * indexCount;
1136 if (!hwBuffer->indexBuffer || (bufSize > hwBuffer->indexBufferSize)) 1136 if (!hwBuffer->indexBuffer || (bufSize > hwBuffer->indexBufferSize))
1137 { 1137 {
1138 if (hwBuffer->indexBuffer) 1138 if (hwBuffer->indexBuffer)
1139 { 1139 {
1140 hwBuffer->indexBuffer->Release(); 1140 hwBuffer->indexBuffer->Release();
1141 hwBuffer->indexBuffer=0; 1141 hwBuffer->indexBuffer=0;
1142 } 1142 }
1143 1143
1144 DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY 1144 DWORD flags = D3DUSAGE_WRITEONLY; // SIO2: Default to D3DUSAGE_WRITEONLY
1145 if (hwBuffer->Mapped_Index != scene::EHM_STATIC) 1145 if (hwBuffer->Mapped_Index != scene::EHM_STATIC)
1146 flags |= D3DUSAGE_DYNAMIC; // SIO2: Add DYNAMIC flag for dynamic buffer data 1146 flags |= D3DUSAGE_DYNAMIC; // SIO2: Add DYNAMIC flag for dynamic buffer data
1147 1147
1148 if (FAILED(pID3DDevice->CreateIndexBuffer(bufSize, flags, indexType, D3DPOOL_DEFAULT, &hwBuffer->indexBuffer, NULL))) 1148 if (FAILED(pID3DDevice->CreateIndexBuffer(bufSize, flags, indexType, D3DPOOL_DEFAULT, &hwBuffer->indexBuffer, NULL)))
1149 return false; 1149 return false;
1150 1150
1151 flags = 0; // SIO2: Reset flags before Lock 1151 flags = 0; // SIO2: Reset flags before Lock
1152 if (hwBuffer->Mapped_Index != scene::EHM_STATIC) 1152 if (hwBuffer->Mapped_Index != scene::EHM_STATIC)
1153 flags = D3DLOCK_DISCARD; 1153 flags = D3DLOCK_DISCARD;
1154 1154
1155 void* lockedBuffer = 0; 1155 void* lockedBuffer = 0;
1156 if (FAILED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, flags))) 1156 if (FAILED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, flags)))
1157 return false; 1157 return false;
1158 1158
1159 memcpy(lockedBuffer, indices, bufSize); 1159 memcpy(lockedBuffer, indices, bufSize);
1160 hwBuffer->indexBuffer->Unlock(); 1160 hwBuffer->indexBuffer->Unlock();
1161 1161
1162 hwBuffer->indexBufferSize = bufSize; 1162 hwBuffer->indexBufferSize = bufSize;
1163 } 1163 }
1164 else 1164 else
1165 { 1165 {
1166 void* lockedBuffer = 0; 1166 void* lockedBuffer = 0;
1167 if( SUCCEEDED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, D3DLOCK_DISCARD))) 1167 if( SUCCEEDED(hwBuffer->indexBuffer->Lock( 0, 0, (void**)&lockedBuffer, D3DLOCK_DISCARD)))
1168 { 1168 {
1169 memcpy(lockedBuffer, indices, bufSize); 1169 memcpy(lockedBuffer, indices, bufSize);
1170 hwBuffer->indexBuffer->Unlock(); 1170 hwBuffer->indexBuffer->Unlock();
1171 } 1171 }
1172 } 1172 }
1173 1173
1174 return true; 1174 return true;
1175} 1175}
1176 1176
1177 1177
1178//! updates hardware buffer if needed 1178//! updates hardware buffer if needed
1179bool CD3D9Driver::updateHardwareBuffer(SHWBufferLink *hwBuffer) 1179bool CD3D9Driver::updateHardwareBuffer(SHWBufferLink *hwBuffer)
1180{ 1180{
1181 if (!hwBuffer) 1181 if (!hwBuffer)
1182 return false; 1182 return false;
1183 1183
1184 if (hwBuffer->Mapped_Vertex!=scene::EHM_NEVER) 1184 if (hwBuffer->Mapped_Vertex!=scene::EHM_NEVER)
1185 { 1185 {
1186 if (hwBuffer->ChangedID_Vertex != hwBuffer->MeshBuffer->getChangedID_Vertex() 1186 if (hwBuffer->ChangedID_Vertex != hwBuffer->MeshBuffer->getChangedID_Vertex()
1187 || !((SHWBufferLink_d3d9*)hwBuffer)->vertexBuffer) 1187 || !((SHWBufferLink_d3d9*)hwBuffer)->vertexBuffer)
1188 { 1188 {
1189 hwBuffer->ChangedID_Vertex = hwBuffer->MeshBuffer->getChangedID_Vertex(); 1189 hwBuffer->ChangedID_Vertex = hwBuffer->MeshBuffer->getChangedID_Vertex();
1190 1190
1191 if (!updateVertexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer)) 1191 if (!updateVertexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer))
1192 return false; 1192 return false;
1193 } 1193 }
1194 } 1194 }
1195 1195
1196 if (hwBuffer->Mapped_Index!=scene::EHM_NEVER) 1196 if (hwBuffer->Mapped_Index!=scene::EHM_NEVER)
1197 { 1197 {
1198 if (hwBuffer->ChangedID_Index != hwBuffer->MeshBuffer->getChangedID_Index() 1198 if (hwBuffer->ChangedID_Index != hwBuffer->MeshBuffer->getChangedID_Index()
1199 || !((SHWBufferLink_d3d9*)hwBuffer)->indexBuffer) 1199 || !((SHWBufferLink_d3d9*)hwBuffer)->indexBuffer)
1200 { 1200 {
1201 hwBuffer->ChangedID_Index = hwBuffer->MeshBuffer->getChangedID_Index(); 1201 hwBuffer->ChangedID_Index = hwBuffer->MeshBuffer->getChangedID_Index();
1202 1202
1203 if (!updateIndexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer)) 1203 if (!updateIndexHardwareBuffer((SHWBufferLink_d3d9*)hwBuffer))
1204 return false; 1204 return false;
1205 } 1205 }
1206 } 1206 }
1207 1207
1208 return true; 1208 return true;
1209} 1209}
1210 1210
1211 1211
1212//! Create hardware buffer from meshbuffer 1212//! Create hardware buffer from meshbuffer
1213CD3D9Driver::SHWBufferLink *CD3D9Driver::createHardwareBuffer(const scene::IMeshBuffer* mb) 1213CD3D9Driver::SHWBufferLink *CD3D9Driver::createHardwareBuffer(const scene::IMeshBuffer* mb)
1214{ 1214{
1215 // Looks like d3d does not support only partial buffering, so refuse 1215 // Looks like d3d does not support only partial buffering, so refuse
1216 // in any case of NEVER 1216 // in any case of NEVER
1217 if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER || mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER)) 1217 if (!mb || (mb->getHardwareMappingHint_Index()==scene::EHM_NEVER || mb->getHardwareMappingHint_Vertex()==scene::EHM_NEVER))
1218 return 0; 1218 return 0;
1219 1219
1220 SHWBufferLink_d3d9 *hwBuffer=new SHWBufferLink_d3d9(mb); 1220 SHWBufferLink_d3d9 *hwBuffer=new SHWBufferLink_d3d9(mb);
1221 1221
1222 //add to map 1222 //add to map
1223 HWBufferMap.insert(hwBuffer->MeshBuffer, hwBuffer); 1223 HWBufferMap.insert(hwBuffer->MeshBuffer, hwBuffer);
1224 1224
1225 hwBuffer->ChangedID_Vertex=hwBuffer->MeshBuffer->getChangedID_Vertex(); 1225 hwBuffer->ChangedID_Vertex=hwBuffer->MeshBuffer->getChangedID_Vertex();
1226 hwBuffer->ChangedID_Index=hwBuffer->MeshBuffer->getChangedID_Index(); 1226 hwBuffer->ChangedID_Index=hwBuffer->MeshBuffer->getChangedID_Index();
1227 hwBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex(); 1227 hwBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex();
1228 hwBuffer->Mapped_Index=mb->getHardwareMappingHint_Index(); 1228 hwBuffer->Mapped_Index=mb->getHardwareMappingHint_Index();
1229 hwBuffer->LastUsed=0; 1229 hwBuffer->LastUsed=0;
1230 hwBuffer->vertexBuffer=0; 1230 hwBuffer->vertexBuffer=0;
1231 hwBuffer->indexBuffer=0; 1231 hwBuffer->indexBuffer=0;
1232 hwBuffer->vertexBufferSize=0; 1232 hwBuffer->vertexBufferSize=0;
1233 hwBuffer->indexBufferSize=0; 1233 hwBuffer->indexBufferSize=0;
1234 1234
1235 if (!updateHardwareBuffer(hwBuffer)) 1235 if (!updateHardwareBuffer(hwBuffer))
1236 { 1236 {
1237 deleteHardwareBuffer(hwBuffer); 1237 deleteHardwareBuffer(hwBuffer);
1238 return 0; 1238 return 0;
1239 } 1239 }
1240 1240
1241 return hwBuffer; 1241 return hwBuffer;
1242} 1242}
1243 1243
1244 1244
1245void CD3D9Driver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) 1245void CD3D9Driver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer)
1246{ 1246{
1247 if (!_HWBuffer) 1247 if (!_HWBuffer)
1248 return; 1248 return;
1249 1249
1250 SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer; 1250 SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer;
1251 if (HWBuffer->indexBuffer) 1251 if (HWBuffer->indexBuffer)
1252 { 1252 {
1253 HWBuffer->indexBuffer->Release(); 1253 HWBuffer->indexBuffer->Release();
1254 HWBuffer->indexBuffer = 0; 1254 HWBuffer->indexBuffer = 0;
1255 } 1255 }
1256 1256
1257 if (HWBuffer->vertexBuffer) 1257 if (HWBuffer->vertexBuffer)
1258 { 1258 {
1259 HWBuffer->vertexBuffer->Release(); 1259 HWBuffer->vertexBuffer->Release();
1260 HWBuffer->vertexBuffer = 0; 1260 HWBuffer->vertexBuffer = 0;
1261 } 1261 }
1262 1262
1263 CNullDriver::deleteHardwareBuffer(_HWBuffer); 1263 CNullDriver::deleteHardwareBuffer(_HWBuffer);
1264} 1264}
1265 1265
1266 1266
1267//! Draw hardware buffer 1267//! Draw hardware buffer
1268void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) 1268void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer)
1269{ 1269{
1270 if (!_HWBuffer) 1270 if (!_HWBuffer)
1271 return; 1271 return;
1272 1272
1273 SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer; 1273 SHWBufferLink_d3d9 *HWBuffer=(SHWBufferLink_d3d9*)_HWBuffer;
1274 1274
1275 updateHardwareBuffer(HWBuffer); //check if update is needed 1275 updateHardwareBuffer(HWBuffer); //check if update is needed
1276 1276
1277 HWBuffer->LastUsed=0;//reset count 1277 HWBuffer->LastUsed=0;//reset count
1278 1278
1279 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer; 1279 const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;
1280 const E_VERTEX_TYPE vType = mb->getVertexType(); 1280 const E_VERTEX_TYPE vType = mb->getVertexType();
1281 const u32 stride = getVertexPitchFromType(vType); 1281 const u32 stride = getVertexPitchFromType(vType);
1282 const void* vPtr = mb->getVertices(); 1282 const void* vPtr = mb->getVertices();
1283 const void* iPtr = mb->getIndices(); 1283 const void* iPtr = mb->getIndices();
1284 if (HWBuffer->vertexBuffer) 1284 if (HWBuffer->vertexBuffer)
1285 { 1285 {
1286 pID3DDevice->SetStreamSource(0, HWBuffer->vertexBuffer, 0, stride); 1286 pID3DDevice->SetStreamSource(0, HWBuffer->vertexBuffer, 0, stride);
1287 vPtr=0; 1287 vPtr=0;
1288 } 1288 }
1289 if (HWBuffer->indexBuffer) 1289 if (HWBuffer->indexBuffer)
1290 { 1290 {
1291 pID3DDevice->SetIndices(HWBuffer->indexBuffer); 1291 pID3DDevice->SetIndices(HWBuffer->indexBuffer);
1292 iPtr=0; 1292 iPtr=0;
1293 } 1293 }
1294 1294
1295 drawVertexPrimitiveList(vPtr, mb->getVertexCount(), iPtr, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType()); 1295 drawVertexPrimitiveList(vPtr, mb->getVertexCount(), iPtr, mb->getIndexCount()/3, mb->getVertexType(), scene::EPT_TRIANGLES, mb->getIndexType());
1296 1296
1297 if (HWBuffer->vertexBuffer) 1297 if (HWBuffer->vertexBuffer)
1298 pID3DDevice->SetStreamSource(0, 0, 0, 0); 1298 pID3DDevice->SetStreamSource(0, 0, 0, 0);
1299 if (HWBuffer->indexBuffer) 1299 if (HWBuffer->indexBuffer)
1300 pID3DDevice->SetIndices(0); 1300 pID3DDevice->SetIndices(0);
1301} 1301}
1302 1302
1303 1303
1304//! Create occlusion query. 1304//! Create occlusion query.
1305/** Use node for identification and mesh for occlusion test. */ 1305/** Use node for identification and mesh for occlusion test. */
1306void CD3D9Driver::addOcclusionQuery(scene::ISceneNode* node, 1306void CD3D9Driver::addOcclusionQuery(scene::ISceneNode* node,
1307 const scene::IMesh* mesh) 1307 const scene::IMesh* mesh)
1308{ 1308{
1309 if (!queryFeature(EVDF_OCCLUSION_QUERY)) 1309 if (!queryFeature(EVDF_OCCLUSION_QUERY))
1310 return; 1310 return;
1311 CNullDriver::addOcclusionQuery(node, mesh); 1311 CNullDriver::addOcclusionQuery(node, mesh);
1312 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1312 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1313 if ((index != -1) && (OcclusionQueries[index].PID == 0)) 1313 if ((index != -1) && (OcclusionQueries[index].PID == 0))
1314 pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[index].PID)); 1314 pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[index].PID));
1315} 1315}
1316 1316
1317 1317
1318//! Remove occlusion query. 1318//! Remove occlusion query.
1319void CD3D9Driver::removeOcclusionQuery(scene::ISceneNode* node) 1319void CD3D9Driver::removeOcclusionQuery(scene::ISceneNode* node)
1320{ 1320{
1321 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1321 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1322 if (index != -1) 1322 if (index != -1)
1323 { 1323 {
1324 if (OcclusionQueries[index].PID != 0) 1324 if (OcclusionQueries[index].PID != 0)
1325 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Release(); 1325 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Release();
1326 CNullDriver::removeOcclusionQuery(node); 1326 CNullDriver::removeOcclusionQuery(node);
1327 } 1327 }
1328} 1328}
1329 1329
1330 1330
1331//! Run occlusion query. Draws mesh stored in query. 1331//! Run occlusion query. Draws mesh stored in query.
1332/** If the mesh shall not be rendered visible, use 1332/** If the mesh shall not be rendered visible, use
1333overrideMaterial to disable the color and depth buffer. */ 1333overrideMaterial to disable the color and depth buffer. */
1334void CD3D9Driver::runOcclusionQuery(scene::ISceneNode* node, bool visible) 1334void CD3D9Driver::runOcclusionQuery(scene::ISceneNode* node, bool visible)
1335{ 1335{
1336 if (!node) 1336 if (!node)
1337 return; 1337 return;
1338 1338
1339 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1339 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1340 if (index != -1) 1340 if (index != -1)
1341 { 1341 {
1342 if (OcclusionQueries[index].PID) 1342 if (OcclusionQueries[index].PID)
1343 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Issue(D3DISSUE_BEGIN); 1343 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Issue(D3DISSUE_BEGIN);
1344 CNullDriver::runOcclusionQuery(node,visible); 1344 CNullDriver::runOcclusionQuery(node,visible);
1345 if (OcclusionQueries[index].PID) 1345 if (OcclusionQueries[index].PID)
1346 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Issue(D3DISSUE_END); 1346 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->Issue(D3DISSUE_END);
1347 } 1347 }
1348} 1348}
1349 1349
1350 1350
1351//! Update occlusion query. Retrieves results from GPU. 1351//! Update occlusion query. Retrieves results from GPU.
1352/** If the query shall not block, set the flag to false. 1352/** If the query shall not block, set the flag to false.
1353Update might not occur in this case, though */ 1353Update might not occur in this case, though */
1354void CD3D9Driver::updateOcclusionQuery(scene::ISceneNode* node, bool block) 1354void CD3D9Driver::updateOcclusionQuery(scene::ISceneNode* node, bool block)
1355{ 1355{
1356 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1356 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1357 if (index != -1) 1357 if (index != -1)
1358 { 1358 {
1359 // not yet started 1359 // not yet started
1360 if (OcclusionQueries[index].Run==u32(~0)) 1360 if (OcclusionQueries[index].Run==u32(~0))
1361 return; 1361 return;
1362 bool available = block?true:false; 1362 bool available = block?true:false;
1363 int tmp=0; 1363 int tmp=0;
1364 if (!block) 1364 if (!block)
1365 available=(reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), 0)==S_OK); 1365 available=(reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), 0)==S_OK);
1366 else 1366 else
1367 { 1367 {
1368 do 1368 do
1369 { 1369 {
1370 HRESULT hr = reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), D3DGETDATA_FLUSH); 1370 HRESULT hr = reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[index].PID)->GetData(&tmp, sizeof(DWORD), D3DGETDATA_FLUSH);
1371 available = (hr == S_OK); 1371 available = (hr == S_OK);
1372 if (hr!=S_FALSE) 1372 if (hr!=S_FALSE)
1373 break; 1373 break;
1374 } while (!available); 1374 } while (!available);
1375 } 1375 }
1376 if (available) 1376 if (available)
1377 OcclusionQueries[index].Result = tmp; 1377 OcclusionQueries[index].Result = tmp;
1378 } 1378 }
1379} 1379}
1380 1380
1381 1381
1382//! Return query result. 1382//! Return query result.
1383/** Return value is the number of visible pixels/fragments. 1383/** Return value is the number of visible pixels/fragments.
1384The value is a safe approximation, i.e. can be larger than the 1384The value is a safe approximation, i.e. can be larger than the
1385actual value of pixels. */ 1385actual value of pixels. */
1386u32 CD3D9Driver::getOcclusionQueryResult(scene::ISceneNode* node) const 1386u32 CD3D9Driver::getOcclusionQueryResult(scene::ISceneNode* node) const
1387{ 1387{
1388 const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); 1388 const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
1389 if (index != -1) 1389 if (index != -1)
1390 return OcclusionQueries[index].Result; 1390 return OcclusionQueries[index].Result;
1391 else 1391 else
1392 return ~0; 1392 return ~0;
1393} 1393}
1394 1394
1395 1395
1396//! draws a vertex primitive list 1396//! draws a vertex primitive list
1397void CD3D9Driver::drawVertexPrimitiveList(const void* vertices, 1397void CD3D9Driver::drawVertexPrimitiveList(const void* vertices,
1398 u32 vertexCount, const void* indexList, u32 primitiveCount, 1398 u32 vertexCount, const void* indexList, u32 primitiveCount,
1399 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, 1399 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
1400 E_INDEX_TYPE iType) 1400 E_INDEX_TYPE iType)
1401{ 1401{
1402 if (!checkPrimitiveCount(primitiveCount)) 1402 if (!checkPrimitiveCount(primitiveCount))
1403 return; 1403 return;
1404 1404
1405 CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); 1405 CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType);
1406 1406
1407 if (!vertexCount || !primitiveCount) 1407 if (!vertexCount || !primitiveCount)
1408 return; 1408 return;
1409 1409
1410 draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, 1410 draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount,
1411 vType, pType, iType, true); 1411 vType, pType, iType, true);
1412} 1412}
1413 1413
1414 1414
1415//! draws a vertex primitive list 1415//! draws a vertex primitive list
1416void CD3D9Driver::draw2DVertexPrimitiveList(const void* vertices, 1416void CD3D9Driver::draw2DVertexPrimitiveList(const void* vertices,
1417 u32 vertexCount, const void* indexList, u32 primitiveCount, 1417 u32 vertexCount, const void* indexList, u32 primitiveCount,
1418 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, 1418 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
1419 E_INDEX_TYPE iType) 1419 E_INDEX_TYPE iType)
1420{ 1420{
1421 if (!checkPrimitiveCount(primitiveCount)) 1421 if (!checkPrimitiveCount(primitiveCount))
1422 return; 1422 return;
1423 1423
1424 CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); 1424 CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType);
1425 1425
1426 if (!vertexCount || !primitiveCount) 1426 if (!vertexCount || !primitiveCount)
1427 return; 1427 return;
1428 1428
1429 draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, 1429 draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount,
1430 vType, pType, iType, false); 1430 vType, pType, iType, false);
1431} 1431}
1432 1432
1433 1433
1434void CD3D9Driver::draw2D3DVertexPrimitiveList(const void* vertices, 1434void CD3D9Driver::draw2D3DVertexPrimitiveList(const void* vertices,
1435 u32 vertexCount, const void* indexList, u32 primitiveCount, 1435 u32 vertexCount, const void* indexList, u32 primitiveCount,
1436 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, 1436 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType,
1437 E_INDEX_TYPE iType, bool is3D) 1437 E_INDEX_TYPE iType, bool is3D)
1438{ 1438{
1439 setVertexShader(vType); 1439 setVertexShader(vType);
1440 1440
1441 const u32 stride = getVertexPitchFromType(vType); 1441 const u32 stride = getVertexPitchFromType(vType);
1442 1442
1443 D3DFORMAT indexType=D3DFMT_UNKNOWN; 1443 D3DFORMAT indexType=D3DFMT_UNKNOWN;
1444 switch (iType) 1444 switch (iType)
1445 { 1445 {
1446 case (EIT_16BIT): 1446 case (EIT_16BIT):
1447 { 1447 {
1448 indexType=D3DFMT_INDEX16; 1448 indexType=D3DFMT_INDEX16;
1449 break; 1449 break;
1450 } 1450 }
1451 case (EIT_32BIT): 1451 case (EIT_32BIT):
1452 { 1452 {
1453 indexType=D3DFMT_INDEX32; 1453 indexType=D3DFMT_INDEX32;
1454 break; 1454 break;
1455 } 1455 }
1456 } 1456 }
1457 1457
1458 if (is3D) 1458 if (is3D)
1459 { 1459 {
1460 if (!setRenderStates3DMode()) 1460 if (!setRenderStates3DMode())
1461 return; 1461 return;
1462 } 1462 }
1463 else 1463 else
1464 { 1464 {
1465 if (Material.MaterialType==EMT_ONETEXTURE_BLEND) 1465 if (Material.MaterialType==EMT_ONETEXTURE_BLEND)
1466 { 1466 {
1467 E_BLEND_FACTOR srcFact; 1467 E_BLEND_FACTOR srcFact;
1468 E_BLEND_FACTOR dstFact; 1468 E_BLEND_FACTOR dstFact;
1469 E_MODULATE_FUNC modulo; 1469 E_MODULATE_FUNC modulo;
1470 u32 alphaSource; 1470 u32 alphaSource;
1471 unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); 1471 unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam);
1472 setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); 1472 setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0);
1473 } 1473 }
1474 else 1474 else
1475 setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); 1475 setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL);
1476 } 1476 }
1477 1477
1478 switch (pType) 1478 switch (pType)
1479 { 1479 {
1480 case scene::EPT_POINT_SPRITES: 1480 case scene::EPT_POINT_SPRITES:
1481 case scene::EPT_POINTS: 1481 case scene::EPT_POINTS:
1482 { 1482 {
1483 f32 tmp=Material.Thickness/getScreenSize().Height; 1483 f32 tmp=Material.Thickness/getScreenSize().Height;
1484 if (pType==scene::EPT_POINT_SPRITES) 1484 if (pType==scene::EPT_POINT_SPRITES)
1485 pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); 1485 pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
1486 pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); 1486 pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
1487 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(tmp)); 1487 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(tmp));
1488 tmp=1.0f; 1488 tmp=1.0f;
1489 pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, F2DW(tmp)); 1489 pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, F2DW(tmp));
1490 pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, F2DW(tmp)); 1490 pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, F2DW(tmp));
1491 pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, F2DW(tmp)); 1491 pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, F2DW(tmp));
1492 tmp=0.0f; 1492 tmp=0.0f;
1493 pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, F2DW(tmp)); 1493 pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, F2DW(tmp));
1494 1494
1495 if (!vertices) 1495 if (!vertices)
1496 { 1496 {
1497 pID3DDevice->DrawIndexedPrimitive(D3DPT_POINTLIST, 0, 0, vertexCount, 0, primitiveCount); 1497 pID3DDevice->DrawIndexedPrimitive(D3DPT_POINTLIST, 0, 0, vertexCount, 0, primitiveCount);
1498 } 1498 }
1499 else 1499 else
1500 { 1500 {
1501 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, 1501 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount,
1502 primitiveCount, indexList, indexType, vertices, stride); 1502 primitiveCount, indexList, indexType, vertices, stride);
1503 } 1503 }
1504 1504
1505 pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); 1505 pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
1506 if (pType==scene::EPT_POINT_SPRITES) 1506 if (pType==scene::EPT_POINT_SPRITES)
1507 pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); 1507 pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
1508 } 1508 }
1509 break; 1509 break;
1510 case scene::EPT_LINE_STRIP: 1510 case scene::EPT_LINE_STRIP:
1511 if(!vertices) 1511 if(!vertices)
1512 pID3DDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 0, vertexCount, 0, primitiveCount); 1512 pID3DDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, 0, 0, vertexCount, 0, primitiveCount);
1513 else 1513 else
1514 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, 1514 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount,
1515 primitiveCount, indexList, indexType, vertices, stride); 1515 primitiveCount, indexList, indexType, vertices, stride);
1516 break; 1516 break;
1517 case scene::EPT_LINE_LOOP: 1517 case scene::EPT_LINE_LOOP:
1518 if(!vertices) 1518 if(!vertices)
1519 { 1519 {
1520 // TODO: Implement proper hardware support for this primitive type. 1520 // TODO: Implement proper hardware support for this primitive type.
1521 // (No looping occurs currently because this would require a way to 1521 // (No looping occurs currently because this would require a way to
1522 // draw the hardware buffer with a custom set of indices. We may even 1522 // draw the hardware buffer with a custom set of indices. We may even
1523 // need to create a new mini index buffer specifically for this 1523 // need to create a new mini index buffer specifically for this
1524 // primitive type.) 1524 // primitive type.)
1525 pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount); 1525 pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount);
1526 } 1526 }
1527 else 1527 else
1528 { 1528 {
1529 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, 1529 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount,
1530 primitiveCount - 1, indexList, indexType, vertices, stride); 1530 primitiveCount - 1, indexList, indexType, vertices, stride);
1531 1531
1532 u16 tmpIndices[] = {primitiveCount - 1, 0}; 1532 u16 tmpIndices[] = {primitiveCount - 1, 0};
1533 1533
1534 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, 1534 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount,
1535 1, tmpIndices, indexType, vertices, stride); 1535 1, tmpIndices, indexType, vertices, stride);
1536 } 1536 }
1537 break; 1537 break;
1538 case scene::EPT_LINES: 1538 case scene::EPT_LINES:
1539 if(!vertices) 1539 if(!vertices)
1540 pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount); 1540 pID3DDevice->DrawIndexedPrimitive(D3DPT_LINELIST, 0, 0, vertexCount, 0, primitiveCount);
1541 else 1541 else
1542 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, 1542 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount,
1543 primitiveCount, indexList, indexType, vertices, stride); 1543 primitiveCount, indexList, indexType, vertices, stride);
1544 break; 1544 break;
1545 case scene::EPT_TRIANGLE_STRIP: 1545 case scene::EPT_TRIANGLE_STRIP:
1546 if(!vertices) 1546 if(!vertices)
1547 pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, vertexCount, 0, primitiveCount); 1547 pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP, 0, 0, vertexCount, 0, primitiveCount);
1548 else 1548 else
1549 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, primitiveCount, 1549 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, primitiveCount,
1550 indexList, indexType, vertices, stride); 1550 indexList, indexType, vertices, stride);
1551 break; 1551 break;
1552 case scene::EPT_TRIANGLE_FAN: 1552 case scene::EPT_TRIANGLE_FAN:
1553 if(!vertices) 1553 if(!vertices)
1554 pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, 0, vertexCount, 0, primitiveCount); 1554 pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN, 0, 0, vertexCount, 0, primitiveCount);
1555 else 1555 else
1556 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, primitiveCount, 1556 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, primitiveCount,
1557 indexList, indexType, vertices, stride); 1557 indexList, indexType, vertices, stride);
1558 break; 1558 break;
1559 case scene::EPT_TRIANGLES: 1559 case scene::EPT_TRIANGLES:
1560 if(!vertices) 1560 if(!vertices)
1561 { 1561 {
1562 pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertexCount, 0, primitiveCount); 1562 pID3DDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, vertexCount, 0, primitiveCount);
1563 } 1563 }
1564 else 1564 else
1565 { 1565 {
1566 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, 1566 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount,
1567 primitiveCount, indexList, indexType, vertices, stride); 1567 primitiveCount, indexList, indexType, vertices, stride);
1568 } 1568 }
1569 break; 1569 break;
1570 } 1570 }
1571} 1571}
1572 1572
1573 1573
1574void CD3D9Driver::draw2DImage(const video::ITexture* texture, 1574void CD3D9Driver::draw2DImage(const video::ITexture* texture,
1575 const core::rect<s32>& destRect, 1575 const core::rect<s32>& destRect,
1576 const core::rect<s32>& sourceRect, 1576 const core::rect<s32>& sourceRect,
1577 const core::rect<s32>* clipRect, 1577 const core::rect<s32>* clipRect,
1578 const video::SColor* const colors, 1578 const video::SColor* const colors,
1579 bool useAlphaChannelOfTexture) 1579 bool useAlphaChannelOfTexture)
1580{ 1580{
1581 if(!texture) 1581 if(!texture)
1582 return; 1582 return;
1583 1583
1584 const core::dimension2d<u32>& ss = texture->getOriginalSize(); 1584 const core::dimension2d<u32>& ss = texture->getOriginalSize();
1585 core::rect<f32> tcoords; 1585 core::rect<f32> tcoords;
1586 tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; 1586 tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width;
1587 tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; 1587 tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height;
1588 tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; 1588 tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width;
1589 tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; 1589 tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height;
1590 1590
1591 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 1591 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
1592 1592
1593 const video::SColor temp[4] = 1593 const video::SColor temp[4] =
1594 { 1594 {
1595 0xFFFFFFFF, 1595 0xFFFFFFFF,
1596 0xFFFFFFFF, 1596 0xFFFFFFFF,
1597 0xFFFFFFFF, 1597 0xFFFFFFFF,
1598 0xFFFFFFFF 1598 0xFFFFFFFF
1599 }; 1599 };
1600 1600
1601 const video::SColor* const useColor = colors ? colors : temp; 1601 const video::SColor* const useColor = colors ? colors : temp;
1602 1602
1603 S3DVertex vtx[4]; // clock wise 1603 S3DVertex vtx[4]; // clock wise
1604 vtx[0] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f, 1604 vtx[0] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f,
1605 0.0f, 0.0f, 0.0f, useColor[0], 1605 0.0f, 0.0f, 0.0f, useColor[0],
1606 tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); 1606 tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
1607 vtx[1] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f, 1607 vtx[1] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f,
1608 0.0f, 0.0f, 0.0f, useColor[3], 1608 0.0f, 0.0f, 0.0f, useColor[3],
1609 tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); 1609 tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
1610 vtx[2] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f, 1610 vtx[2] = S3DVertex((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f,
1611 0.0f, 0.0f, 0.0f, useColor[2], 1611 0.0f, 0.0f, 0.0f, useColor[2],
1612 tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); 1612 tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
1613 vtx[3] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f, 1613 vtx[3] = S3DVertex((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f,
1614 0.0f, 0.0f, 0.0f, useColor[1], 1614 0.0f, 0.0f, 0.0f, useColor[1],
1615 tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); 1615 tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
1616 1616
1617 s16 indices[6] = {0,1,2,0,2,3}; 1617 s16 indices[6] = {0,1,2,0,2,3};
1618 1618
1619 setActiveTexture(0, const_cast<video::ITexture*>(texture)); 1619 setActiveTexture(0, const_cast<video::ITexture*>(texture));
1620 1620
1621 setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || 1621 setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 ||
1622 useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, 1622 useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255,
1623 true, useAlphaChannelOfTexture); 1623 true, useAlphaChannelOfTexture);
1624 1624
1625 setVertexShader(EVT_STANDARD); 1625 setVertexShader(EVT_STANDARD);
1626 1626
1627 if (clipRect) 1627 if (clipRect)
1628 { 1628 {
1629 pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); 1629 pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
1630 RECT scissor; 1630 RECT scissor;
1631 scissor.left = clipRect->UpperLeftCorner.X; 1631 scissor.left = clipRect->UpperLeftCorner.X;
1632 scissor.top = clipRect->UpperLeftCorner.Y; 1632 scissor.top = clipRect->UpperLeftCorner.Y;
1633 scissor.right = clipRect->LowerRightCorner.X; 1633 scissor.right = clipRect->LowerRightCorner.X;
1634 scissor.bottom = clipRect->LowerRightCorner.Y; 1634 scissor.bottom = clipRect->LowerRightCorner.Y;
1635 pID3DDevice->SetScissorRect(&scissor); 1635 pID3DDevice->SetScissorRect(&scissor);
1636 } 1636 }
1637 1637
1638 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], 1638 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
1639 D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); 1639 D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex));
1640 1640
1641 if (clipRect) 1641 if (clipRect)
1642 pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); 1642 pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
1643} 1643}
1644 1644
1645 1645
1646void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture, 1646void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture,
1647 const core::array<core::position2d<s32> >& positions, 1647 const core::array<core::position2d<s32> >& positions,
1648 const core::array<core::rect<s32> >& sourceRects, 1648 const core::array<core::rect<s32> >& sourceRects,
1649 const core::rect<s32>* clipRect, 1649 const core::rect<s32>* clipRect,
1650 SColor color, 1650 SColor color,
1651 bool useAlphaChannelOfTexture) 1651 bool useAlphaChannelOfTexture)
1652{ 1652{
1653 if (!texture) 1653 if (!texture)
1654 return; 1654 return;
1655 1655
1656 if (!setActiveTexture(0, const_cast<video::ITexture*>(texture))) 1656 if (!setActiveTexture(0, const_cast<video::ITexture*>(texture)))
1657 return; 1657 return;
1658 1658
1659 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); 1659 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
1660 1660
1661 const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size()); 1661 const irr::u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
1662 1662
1663 core::array<S3DVertex> vtx(drawCount * 4); 1663 core::array<S3DVertex> vtx(drawCount * 4);
1664 core::array<u16> indices(drawCount * 6); 1664 core::array<u16> indices(drawCount * 6);
1665 1665
1666 for(u32 i = 0;i < drawCount;i++) 1666 for(u32 i = 0;i < drawCount;i++)
1667 { 1667 {
1668 core::position2d<s32> targetPos = positions[i]; 1668 core::position2d<s32> targetPos = positions[i];
1669 core::position2d<s32> sourcePos = sourceRects[i].UpperLeftCorner; 1669 core::position2d<s32> sourcePos = sourceRects[i].UpperLeftCorner;
1670 // This needs to be signed as it may go negative. 1670 // This needs to be signed as it may go negative.
1671 core::dimension2d<s32> sourceSize(sourceRects[i].getSize()); 1671 core::dimension2d<s32> sourceSize(sourceRects[i].getSize());
1672 1672
1673 if (clipRect) 1673 if (clipRect)
1674 { 1674 {
1675 if (targetPos.X < clipRect->UpperLeftCorner.X) 1675 if (targetPos.X < clipRect->UpperLeftCorner.X)
1676 { 1676 {
1677 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; 1677 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
1678 if (sourceSize.Width <= 0) 1678 if (sourceSize.Width <= 0)
1679 continue; 1679 continue;
1680 1680
1681 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; 1681 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
1682 targetPos.X = clipRect->UpperLeftCorner.X; 1682 targetPos.X = clipRect->UpperLeftCorner.X;
1683 } 1683 }
1684 1684
1685 if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) 1685 if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X)
1686 { 1686 {
1687 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; 1687 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
1688 if (sourceSize.Width <= 0) 1688 if (sourceSize.Width <= 0)
1689 continue; 1689 continue;
1690 } 1690 }
1691 1691
1692 if (targetPos.Y < clipRect->UpperLeftCorner.Y) 1692 if (targetPos.Y < clipRect->UpperLeftCorner.Y)
1693 { 1693 {
1694 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; 1694 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
1695 if (sourceSize.Height <= 0) 1695 if (sourceSize.Height <= 0)
1696 continue; 1696 continue;
1697 1697
1698 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; 1698 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
1699 targetPos.Y = clipRect->UpperLeftCorner.Y; 1699 targetPos.Y = clipRect->UpperLeftCorner.Y;
1700 } 1700 }
1701 1701
1702 if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) 1702 if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y)
1703 { 1703 {
1704 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; 1704 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
1705 if (sourceSize.Height <= 0) 1705 if (sourceSize.Height <= 0)
1706 continue; 1706 continue;
1707 } 1707 }
1708 } 1708 }
1709 1709
1710 // clip these coordinates 1710 // clip these coordinates
1711 1711
1712 if (targetPos.X<0) 1712 if (targetPos.X<0)
1713 { 1713 {
1714 sourceSize.Width += targetPos.X; 1714 sourceSize.Width += targetPos.X;
1715 if (sourceSize.Width <= 0) 1715 if (sourceSize.Width <= 0)
1716 continue; 1716 continue;
1717 1717
1718 sourcePos.X -= targetPos.X; 1718 sourcePos.X -= targetPos.X;
1719 targetPos.X = 0; 1719 targetPos.X = 0;
1720 } 1720 }
1721 1721
1722 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 1722 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
1723 1723
1724 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) 1724 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
1725 { 1725 {
1726 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; 1726 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
1727 if (sourceSize.Width <= 0) 1727 if (sourceSize.Width <= 0)
1728 continue; 1728 continue;
1729 } 1729 }
1730 1730
1731 if (targetPos.Y<0) 1731 if (targetPos.Y<0)
1732 { 1732 {
1733 sourceSize.Height += targetPos.Y; 1733 sourceSize.Height += targetPos.Y;
1734 if (sourceSize.Height <= 0) 1734 if (sourceSize.Height <= 0)
1735 continue; 1735 continue;
1736 1736
1737 sourcePos.Y -= targetPos.Y; 1737 sourcePos.Y -= targetPos.Y;
1738 targetPos.Y = 0; 1738 targetPos.Y = 0;
1739 } 1739 }
1740 1740
1741 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) 1741 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
1742 { 1742 {
1743 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; 1743 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
1744 if (sourceSize.Height <= 0) 1744 if (sourceSize.Height <= 0)
1745 continue; 1745 continue;
1746 } 1746 }
1747 1747
1748 // ok, we've clipped everything. 1748 // ok, we've clipped everything.
1749 // now draw it. 1749 // now draw it.
1750 1750
1751 core::rect<f32> tcoords; 1751 core::rect<f32> tcoords;
1752 tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; 1752 tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ;
1753 tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; 1753 tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height;
1754 tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); 1754 tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width);
1755 tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); 1755 tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height);
1756 1756
1757 const core::rect<s32> poss(targetPos, sourceSize); 1757 const core::rect<s32> poss(targetPos, sourceSize);
1758 1758
1759 vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, 1759 vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f,
1760 0.0f, 0.0f, 0.0f, color, 1760 0.0f, 0.0f, 0.0f, color,
1761 tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y)); 1761 tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y));
1762 vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, 1762 vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f,
1763 0.0f, 0.0f, 0.0f, color, 1763 0.0f, 0.0f, 0.0f, color,
1764 tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y)); 1764 tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y));
1765 vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, 1765 vtx.push_back(S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f,
1766 0.0f, 0.0f, 0.0f, color, 1766 0.0f, 0.0f, 0.0f, color,
1767 tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y)); 1767 tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y));
1768 vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, 1768 vtx.push_back(S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f,
1769 0.0f, 0.0f, 0.0f, color, 1769 0.0f, 0.0f, 0.0f, color,
1770 tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y)); 1770 tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y));
1771 1771
1772 const u32 curPos = vtx.size()-4; 1772 const u32 curPos = vtx.size()-4;
1773 indices.push_back(0+curPos); 1773 indices.push_back(0+curPos);
1774 indices.push_back(1+curPos); 1774 indices.push_back(1+curPos);
1775 indices.push_back(2+curPos); 1775 indices.push_back(2+curPos);
1776 1776
1777 indices.push_back(0+curPos); 1777 indices.push_back(0+curPos);
1778 indices.push_back(2+curPos); 1778 indices.push_back(2+curPos);
1779 indices.push_back(3+curPos); 1779 indices.push_back(3+curPos);
1780 } 1780 }
1781 1781
1782 if (vtx.size()) 1782 if (vtx.size())
1783 { 1783 {
1784 setVertexShader(EVT_STANDARD); 1784 setVertexShader(EVT_STANDARD);
1785 1785
1786 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vtx.size(), indices.size() / 3, indices.pointer(), 1786 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vtx.size(), indices.size() / 3, indices.pointer(),
1787 D3DFMT_INDEX16,vtx.pointer(), sizeof(S3DVertex)); 1787 D3DFMT_INDEX16,vtx.pointer(), sizeof(S3DVertex));
1788 } 1788 }
1789} 1789}
1790 1790
1791 1791
1792//! draws a 2d image, using a color and the alpha channel of the texture if 1792//! draws a 2d image, using a color and the alpha channel of the texture if
1793//! desired. The image is drawn at pos and clipped against clipRect (if != 0). 1793//! desired. The image is drawn at pos and clipped against clipRect (if != 0).
1794void CD3D9Driver::draw2DImage(const video::ITexture* texture, 1794void CD3D9Driver::draw2DImage(const video::ITexture* texture,
1795 const core::position2d<s32>& pos, 1795 const core::position2d<s32>& pos,
1796 const core::rect<s32>& sourceRect, 1796 const core::rect<s32>& sourceRect,
1797 const core::rect<s32>* clipRect, SColor color, 1797 const core::rect<s32>* clipRect, SColor color,
1798 bool useAlphaChannelOfTexture) 1798 bool useAlphaChannelOfTexture)
1799{ 1799{
1800 if (!texture) 1800 if (!texture)
1801 return; 1801 return;
1802 1802
1803 if (!sourceRect.isValid()) 1803 if (!sourceRect.isValid())
1804 return; 1804 return;
1805 1805
1806 if (!setActiveTexture(0, const_cast<video::ITexture*>(texture))) 1806 if (!setActiveTexture(0, const_cast<video::ITexture*>(texture)))
1807 return; 1807 return;
1808 1808
1809 core::position2d<s32> targetPos = pos; 1809 core::position2d<s32> targetPos = pos;
1810 core::position2d<s32> sourcePos = sourceRect.UpperLeftCorner; 1810 core::position2d<s32> sourcePos = sourceRect.UpperLeftCorner;
1811 // This needs to be signed as it may go negative. 1811 // This needs to be signed as it may go negative.
1812 core::dimension2d<s32> sourceSize(sourceRect.getSize()); 1812 core::dimension2d<s32> sourceSize(sourceRect.getSize());
1813 1813
1814 if (clipRect) 1814 if (clipRect)
1815 { 1815 {
1816 if (targetPos.X < clipRect->UpperLeftCorner.X) 1816 if (targetPos.X < clipRect->UpperLeftCorner.X)
1817 { 1817 {
1818 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; 1818 sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
1819 if (sourceSize.Width <= 0) 1819 if (sourceSize.Width <= 0)
1820 return; 1820 return;
1821 1821
1822 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; 1822 sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
1823 targetPos.X = clipRect->UpperLeftCorner.X; 1823 targetPos.X = clipRect->UpperLeftCorner.X;
1824 } 1824 }
1825 1825
1826 if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) 1826 if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X)
1827 { 1827 {
1828 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; 1828 sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
1829 if (sourceSize.Width <= 0) 1829 if (sourceSize.Width <= 0)
1830 return; 1830 return;
1831 } 1831 }
1832 1832
1833 if (targetPos.Y < clipRect->UpperLeftCorner.Y) 1833 if (targetPos.Y < clipRect->UpperLeftCorner.Y)
1834 { 1834 {
1835 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; 1835 sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
1836 if (sourceSize.Height <= 0) 1836 if (sourceSize.Height <= 0)
1837 return; 1837 return;
1838 1838
1839 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; 1839 sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
1840 targetPos.Y = clipRect->UpperLeftCorner.Y; 1840 targetPos.Y = clipRect->UpperLeftCorner.Y;
1841 } 1841 }
1842 1842
1843 if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) 1843 if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y)
1844 { 1844 {
1845 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; 1845 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
1846 if (sourceSize.Height <= 0) 1846 if (sourceSize.Height <= 0)
1847 return; 1847 return;
1848 } 1848 }
1849 } 1849 }
1850 1850
1851 // clip these coordinates 1851 // clip these coordinates
1852 1852
1853 if (targetPos.X<0) 1853 if (targetPos.X<0)
1854 { 1854 {
1855 sourceSize.Width += targetPos.X; 1855 sourceSize.Width += targetPos.X;
1856 if (sourceSize.Width <= 0) 1856 if (sourceSize.Width <= 0)
1857 return; 1857 return;
1858 1858
1859 sourcePos.X -= targetPos.X; 1859 sourcePos.X -= targetPos.X;
1860 targetPos.X = 0; 1860 targetPos.X = 0;
1861 } 1861 }
1862 1862
1863 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 1863 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
1864 1864
1865 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) 1865 if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width)
1866 { 1866 {
1867 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; 1867 sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width;
1868 if (sourceSize.Width <= 0) 1868 if (sourceSize.Width <= 0)
1869 return; 1869 return;
1870 } 1870 }
1871 1871
1872 if (targetPos.Y<0) 1872 if (targetPos.Y<0)
1873 { 1873 {
1874 sourceSize.Height += targetPos.Y; 1874 sourceSize.Height += targetPos.Y;
1875 if (sourceSize.Height <= 0) 1875 if (sourceSize.Height <= 0)
1876 return; 1876 return;
1877 1877
1878 sourcePos.Y -= targetPos.Y; 1878 sourcePos.Y -= targetPos.Y;
1879 targetPos.Y = 0; 1879 targetPos.Y = 0;
1880 } 1880 }
1881 1881
1882 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) 1882 if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height)
1883 { 1883 {
1884 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; 1884 sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height;
1885 if (sourceSize.Height <= 0) 1885 if (sourceSize.Height <= 0)
1886 return; 1886 return;
1887 } 1887 }
1888 1888
1889 // ok, we've clipped everything. 1889 // ok, we've clipped everything.
1890 // now draw it. 1890 // now draw it.
1891 1891
1892 core::rect<f32> tcoords; 1892 core::rect<f32> tcoords;
1893 tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; 1893 tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ;
1894 tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; 1894 tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height;
1895 tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); 1895 tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width);
1896 tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); 1896 tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height);
1897 1897
1898 const core::rect<s32> poss(targetPos, sourceSize); 1898 const core::rect<s32> poss(targetPos, sourceSize);
1899 1899
1900 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); 1900 setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
1901 1901
1902 S3DVertex vtx[4]; 1902 S3DVertex vtx[4];
1903 vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, 1903 vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f,
1904 0.0f, 0.0f, 0.0f, color, 1904 0.0f, 0.0f, 0.0f, color,
1905 tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); 1905 tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
1906 vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f, 1906 vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.UpperLeftCorner.Y, 0.0f,
1907 0.0f, 0.0f, 0.0f, color, 1907 0.0f, 0.0f, 0.0f, color,
1908 tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); 1908 tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
1909 vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, 1909 vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f,
1910 0.0f, 0.0f, 0.0f, color, 1910 0.0f, 0.0f, 0.0f, color,
1911 tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); 1911 tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
1912 vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f, 1912 vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, (f32)poss.LowerRightCorner.Y, 0.0f,
1913 0.0f, 0.0f, 0.0f, color, 1913 0.0f, 0.0f, 0.0f, color,
1914 tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); 1914 tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
1915 1915
1916 s16 indices[6] = {0,1,2,0,2,3}; 1916 s16 indices[6] = {0,1,2,0,2,3};
1917 1917
1918 setVertexShader(EVT_STANDARD); 1918 setVertexShader(EVT_STANDARD);
1919 1919
1920 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], 1920 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
1921 D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); 1921 D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex));
1922} 1922}
1923 1923
1924 1924
1925//!Draws a 2d rectangle with a gradient. 1925//!Draws a 2d rectangle with a gradient.
1926void CD3D9Driver::draw2DRectangle(const core::rect<s32>& position, 1926void CD3D9Driver::draw2DRectangle(const core::rect<s32>& position,
1927 SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, 1927 SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
1928 const core::rect<s32>* clip) 1928 const core::rect<s32>* clip)
1929{ 1929{
1930 core::rect<s32> pos(position); 1930 core::rect<s32> pos(position);
1931 1931
1932 if (clip) 1932 if (clip)
1933 pos.clipAgainst(*clip); 1933 pos.clipAgainst(*clip);
1934 1934
1935 if (!pos.isValid()) 1935 if (!pos.isValid())
1936 return; 1936 return;
1937 1937
1938 S3DVertex vtx[4]; 1938 S3DVertex vtx[4];
1939 vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, 1939 vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f,
1940 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); 1940 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f);
1941 vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, 1941 vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f,
1942 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); 1942 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f);
1943 vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, 1943 vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f,
1944 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); 1944 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f);
1945 vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, 1945 vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f,
1946 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); 1946 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f);
1947 1947
1948 s16 indices[6] = {0,1,2,0,2,3}; 1948 s16 indices[6] = {0,1,2,0,2,3};
1949 1949
1950 setRenderStates2DMode( 1950 setRenderStates2DMode(
1951 colorLeftUp.getAlpha() < 255 || 1951 colorLeftUp.getAlpha() < 255 ||
1952 colorRightUp.getAlpha() < 255 || 1952 colorRightUp.getAlpha() < 255 ||
1953 colorLeftDown.getAlpha() < 255 || 1953 colorLeftDown.getAlpha() < 255 ||
1954 colorRightDown.getAlpha() < 255, false, false); 1954 colorRightDown.getAlpha() < 255, false, false);
1955 1955
1956 setActiveTexture(0,0); 1956 setActiveTexture(0,0);
1957 1957
1958 setVertexShader(EVT_STANDARD); 1958 setVertexShader(EVT_STANDARD);
1959 1959
1960 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], 1960 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
1961 D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); 1961 D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex));
1962} 1962}
1963 1963
1964 1964
1965//! Draws a 2d line. 1965//! Draws a 2d line.
1966void CD3D9Driver::draw2DLine(const core::position2d<s32>& start, 1966void CD3D9Driver::draw2DLine(const core::position2d<s32>& start,
1967 const core::position2d<s32>& end, 1967 const core::position2d<s32>& end,
1968 SColor color) 1968 SColor color)
1969{ 1969{
1970 if (start==end) 1970 if (start==end)
1971 drawPixel(start.X, start.Y, color); 1971 drawPixel(start.X, start.Y, color);
1972 else 1972 else
1973 { 1973 {
1974 // thanks to Vash TheStampede who sent in his implementation 1974 // thanks to Vash TheStampede who sent in his implementation
1975 S3DVertex vtx[2]; 1975 S3DVertex vtx[2];
1976 vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f, 1976 vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f,
1977 0.0f, 0.0f, 0.0f, // normal 1977 0.0f, 0.0f, 0.0f, // normal
1978 color, 0.0f, 0.0f); // texture 1978 color, 0.0f, 0.0f); // texture
1979 1979
1980 vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f, 1980 vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f,
1981 0.0f, 0.0f, 0.0f, 1981 0.0f, 0.0f, 0.0f,
1982 color, 0.0f, 0.0f); 1982 color, 0.0f, 0.0f);
1983 1983
1984 setRenderStates2DMode(color.getAlpha() < 255, false, false); 1984 setRenderStates2DMode(color.getAlpha() < 255, false, false);
1985 setActiveTexture(0,0); 1985 setActiveTexture(0,0);
1986 1986
1987 setVertexShader(EVT_STANDARD); 1987 setVertexShader(EVT_STANDARD);
1988 1988
1989 pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, 1989 pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1,
1990 &vtx[0], sizeof(S3DVertex) ); 1990 &vtx[0], sizeof(S3DVertex) );
1991 } 1991 }
1992} 1992}
1993 1993
1994 1994
1995//! Draws a pixel 1995//! Draws a pixel
1996void CD3D9Driver::drawPixel(u32 x, u32 y, const SColor & color) 1996void CD3D9Driver::drawPixel(u32 x, u32 y, const SColor & color)
1997{ 1997{
1998 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 1998 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
1999 if(x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) 1999 if(x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height)
2000 return; 2000 return;
2001 2001
2002 setRenderStates2DMode(color.getAlpha() < 255, false, false); 2002 setRenderStates2DMode(color.getAlpha() < 255, false, false);
2003 setActiveTexture(0,0); 2003 setActiveTexture(0,0);
2004 2004
2005 setVertexShader(EVT_STANDARD); 2005 setVertexShader(EVT_STANDARD);
2006 2006
2007 S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); 2007 S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f);
2008 2008
2009 pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); 2009 pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex));
2010} 2010}
2011 2011
2012 2012
2013//! sets right vertex shader 2013//! sets right vertex shader
2014void CD3D9Driver::setVertexShader(E_VERTEX_TYPE newType) 2014void CD3D9Driver::setVertexShader(E_VERTEX_TYPE newType)
2015{ 2015{
2016 if (newType != LastVertexType) 2016 if (newType != LastVertexType)
2017 { 2017 {
2018 LastVertexType = newType; 2018 LastVertexType = newType;
2019 HRESULT hr = 0; 2019 HRESULT hr = 0;
2020 2020
2021 switch(newType) 2021 switch(newType)
2022 { 2022 {
2023 case EVT_STANDARD: 2023 case EVT_STANDARD:
2024 hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); 2024 hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1);
2025 break; 2025 break;
2026 case EVT_2TCOORDS: 2026 case EVT_2TCOORDS:
2027 hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); 2027 hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2);
2028 break; 2028 break;
2029 case EVT_TANGENTS: 2029 case EVT_TANGENTS:
2030 hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | 2030 hr = pID3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 |
2031 D3DFVF_TEXCOORDSIZE2(0) | // real texture coord 2031 D3DFVF_TEXCOORDSIZE2(0) | // real texture coord
2032 D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent 2032 D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent
2033 D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal 2033 D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal
2034 ); 2034 );
2035 break; 2035 break;
2036 } 2036 }
2037 2037
2038 if (FAILED(hr)) 2038 if (FAILED(hr))
2039 { 2039 {
2040 os::Printer::log("Could not set vertex Shader.", ELL_ERROR); 2040 os::Printer::log("Could not set vertex Shader.", ELL_ERROR);
2041 return; 2041 return;
2042 } 2042 }
2043 } 2043 }
2044} 2044}
2045 2045
2046 2046
2047//! sets the needed renderstates 2047//! sets the needed renderstates
2048bool CD3D9Driver::setRenderStates3DMode() 2048bool CD3D9Driver::setRenderStates3DMode()
2049{ 2049{
2050 if (!pID3DDevice) 2050 if (!pID3DDevice)
2051 return false; 2051 return false;
2052 2052
2053 if (CurrentRenderMode != ERM_3D) 2053 if (CurrentRenderMode != ERM_3D)
2054 { 2054 {
2055 // switch back the matrices 2055 // switch back the matrices
2056 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); 2056 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW]));
2057 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); 2057 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD]));
2058 pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); 2058 pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION]));
2059 2059
2060 pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); 2060 pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
2061 pID3DDevice->SetRenderState(D3DRS_CLIPPING, TRUE); 2061 pID3DDevice->SetRenderState(D3DRS_CLIPPING, TRUE);
2062 2062
2063 ResetRenderStates = true; 2063 ResetRenderStates = true;
2064 } 2064 }
2065 2065
2066 if (ResetRenderStates || LastMaterial != Material) 2066 if (ResetRenderStates || LastMaterial != Material)
2067 { 2067 {
2068 // unset old material 2068 // unset old material
2069 2069
2070 if (CurrentRenderMode == ERM_3D && 2070 if (CurrentRenderMode == ERM_3D &&
2071 LastMaterial.MaterialType != Material.MaterialType && 2071 LastMaterial.MaterialType != Material.MaterialType &&
2072 LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) 2072 LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size())
2073 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); 2073 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
2074 2074
2075 // set new material. 2075 // set new material.
2076 2076
2077 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 2077 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
2078 MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( 2078 MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial(
2079 Material, LastMaterial, ResetRenderStates, this); 2079 Material, LastMaterial, ResetRenderStates, this);
2080 } 2080 }
2081 2081
2082 bool shaderOK = true; 2082 bool shaderOK = true;
2083 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 2083 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
2084 shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); 2084 shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType);
2085 2085
2086 LastMaterial = Material; 2086 LastMaterial = Material;
2087 2087
2088 ResetRenderStates = false; 2088 ResetRenderStates = false;
2089 2089
2090 CurrentRenderMode = ERM_3D; 2090 CurrentRenderMode = ERM_3D;
2091 2091
2092 return shaderOK; 2092 return shaderOK;
2093} 2093}
2094 2094
2095 2095
2096//! Map Irrlicht texture wrap mode to native values 2096//! Map Irrlicht texture wrap mode to native values
2097D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp) 2097D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp)
2098{ 2098{
2099 switch (clamp) 2099 switch (clamp)
2100 { 2100 {
2101 case ETC_REPEAT: 2101 case ETC_REPEAT:
2102 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP) 2102 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP)
2103 return D3DTADDRESS_WRAP; 2103 return D3DTADDRESS_WRAP;
2104 case ETC_CLAMP: 2104 case ETC_CLAMP:
2105 case ETC_CLAMP_TO_EDGE: 2105 case ETC_CLAMP_TO_EDGE:
2106 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) 2106 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP)
2107 return D3DTADDRESS_CLAMP; 2107 return D3DTADDRESS_CLAMP;
2108 case ETC_MIRROR: 2108 case ETC_MIRROR:
2109 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) 2109 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR)
2110 return D3DTADDRESS_MIRROR; 2110 return D3DTADDRESS_MIRROR;
2111 case ETC_CLAMP_TO_BORDER: 2111 case ETC_CLAMP_TO_BORDER:
2112 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) 2112 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER)
2113 return D3DTADDRESS_BORDER; 2113 return D3DTADDRESS_BORDER;
2114 else 2114 else
2115 return D3DTADDRESS_CLAMP; 2115 return D3DTADDRESS_CLAMP;
2116 case ETC_MIRROR_CLAMP: 2116 case ETC_MIRROR_CLAMP:
2117 case ETC_MIRROR_CLAMP_TO_EDGE: 2117 case ETC_MIRROR_CLAMP_TO_EDGE:
2118 case ETC_MIRROR_CLAMP_TO_BORDER: 2118 case ETC_MIRROR_CLAMP_TO_BORDER:
2119 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE) 2119 if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE)
2120 return D3DTADDRESS_MIRRORONCE; 2120 return D3DTADDRESS_MIRRORONCE;
2121 else 2121 else
2122 return D3DTADDRESS_CLAMP; 2122 return D3DTADDRESS_CLAMP;
2123 default: 2123 default:
2124 return D3DTADDRESS_WRAP; 2124 return D3DTADDRESS_WRAP;
2125 } 2125 }
2126} 2126}
2127 2127
2128 2128
2129//! Can be called by an IMaterialRenderer to make its work easier. 2129//! Can be called by an IMaterialRenderer to make its work easier.
2130void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, 2130void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial,
2131 bool resetAllRenderstates) 2131 bool resetAllRenderstates)
2132{ 2132{
2133 // This needs only to be updated onresets 2133 // This needs only to be updated onresets
2134 if (Params.HandleSRGB && resetAllRenderstates) 2134 if (Params.HandleSRGB && resetAllRenderstates)
2135 pID3DDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE); 2135 pID3DDevice->SetRenderState(D3DRS_SRGBWRITEENABLE, TRUE);
2136 2136
2137 if (resetAllRenderstates || 2137 if (resetAllRenderstates ||
2138 lastmaterial.AmbientColor != material.AmbientColor || 2138 lastmaterial.AmbientColor != material.AmbientColor ||
2139 lastmaterial.DiffuseColor != material.DiffuseColor || 2139 lastmaterial.DiffuseColor != material.DiffuseColor ||
2140 lastmaterial.SpecularColor != material.SpecularColor || 2140 lastmaterial.SpecularColor != material.SpecularColor ||
2141 lastmaterial.EmissiveColor != material.EmissiveColor || 2141 lastmaterial.EmissiveColor != material.EmissiveColor ||
2142 lastmaterial.Shininess != material.Shininess) 2142 lastmaterial.Shininess != material.Shininess)
2143 { 2143 {
2144 D3DMATERIAL9 mat; 2144 D3DMATERIAL9 mat;
2145 mat.Diffuse = colorToD3D(material.DiffuseColor); 2145 mat.Diffuse = colorToD3D(material.DiffuseColor);
2146 mat.Ambient = colorToD3D(material.AmbientColor); 2146 mat.Ambient = colorToD3D(material.AmbientColor);
2147 mat.Specular = colorToD3D(material.SpecularColor); 2147 mat.Specular = colorToD3D(material.SpecularColor);
2148 mat.Emissive = colorToD3D(material.EmissiveColor); 2148 mat.Emissive = colorToD3D(material.EmissiveColor);
2149 mat.Power = material.Shininess; 2149 mat.Power = material.Shininess;
2150 pID3DDevice->SetMaterial(&mat); 2150 pID3DDevice->SetMaterial(&mat);
2151 } 2151 }
2152 2152
2153 if (lastmaterial.ColorMaterial != material.ColorMaterial) 2153 if (lastmaterial.ColorMaterial != material.ColorMaterial)
2154 { 2154 {
2155 pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE)); 2155 pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE));
2156 pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, 2156 pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE,
2157 ((material.ColorMaterial == ECM_DIFFUSE)|| 2157 ((material.ColorMaterial == ECM_DIFFUSE)||
2158 (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); 2158 (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL);
2159 pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, 2159 pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,
2160 ((material.ColorMaterial == ECM_AMBIENT)|| 2160 ((material.ColorMaterial == ECM_AMBIENT)||
2161 (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); 2161 (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL);
2162 pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, 2162 pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE,
2163 (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); 2163 (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL);
2164 pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, 2164 pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE,
2165 (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); 2165 (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL);
2166 } 2166 }
2167 2167
2168 // fillmode 2168 // fillmode
2169 if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) 2169 if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud)
2170 { 2170 {
2171 if (material.Wireframe) 2171 if (material.Wireframe)
2172 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); 2172 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
2173 else 2173 else
2174 if (material.PointCloud) 2174 if (material.PointCloud)
2175 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); 2175 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT);
2176 else 2176 else
2177 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); 2177 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
2178 } 2178 }
2179 2179
2180 // shademode 2180 // shademode
2181 2181
2182 if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) 2182 if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading)
2183 { 2183 {
2184 if (material.GouraudShading) 2184 if (material.GouraudShading)
2185 pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); 2185 pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
2186 else 2186 else
2187 pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); 2187 pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
2188 } 2188 }
2189 2189
2190 // lighting 2190 // lighting
2191 2191
2192 if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) 2192 if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting)
2193 { 2193 {
2194 if (material.Lighting) 2194 if (material.Lighting)
2195 pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); 2195 pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
2196 else 2196 else
2197 pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 2197 pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
2198 } 2198 }
2199 2199
2200 // zbuffer 2200 // zbuffer
2201 2201
2202 if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) 2202 if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer)
2203 { 2203 {
2204 switch (material.ZBuffer) 2204 switch (material.ZBuffer)
2205 { 2205 {
2206 case ECFN_NEVER: 2206 case ECFN_NEVER:
2207 pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); 2207 pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
2208 break; 2208 break;
2209 case ECFN_LESSEQUAL: 2209 case ECFN_LESSEQUAL:
2210 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2210 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2211 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); 2211 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
2212 break; 2212 break;
2213 case ECFN_EQUAL: 2213 case ECFN_EQUAL:
2214 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2214 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2215 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); 2215 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL);
2216 break; 2216 break;
2217 case ECFN_LESS: 2217 case ECFN_LESS:
2218 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2218 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2219 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); 2219 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
2220 break; 2220 break;
2221 case ECFN_NOTEQUAL: 2221 case ECFN_NOTEQUAL:
2222 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2222 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2223 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); 2223 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL);
2224 break; 2224 break;
2225 case ECFN_GREATEREQUAL: 2225 case ECFN_GREATEREQUAL:
2226 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2226 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2227 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); 2227 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL);
2228 break; 2228 break;
2229 case ECFN_GREATER: 2229 case ECFN_GREATER:
2230 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2230 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2231 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); 2231 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER);
2232 break; 2232 break;
2233 case ECFN_ALWAYS: 2233 case ECFN_ALWAYS:
2234 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2234 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2235 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); 2235 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
2236 break; 2236 break;
2237 } 2237 }
2238 } 2238 }
2239 2239
2240 // zwrite 2240 // zwrite
2241// if (resetAllRenderstates || (lastmaterial.ZWriteEnable != material.ZWriteEnable)) 2241// if (resetAllRenderstates || (lastmaterial.ZWriteEnable != material.ZWriteEnable))
2242 { 2242 {
2243 if ( material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) 2243 if ( material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent()))
2244 pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); 2244 pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE);
2245 else 2245 else
2246 pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); 2246 pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE);
2247 } 2247 }
2248 2248
2249 // back face culling 2249 // back face culling
2250 2250
2251 if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) 2251 if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling))
2252 { 2252 {
2253// if (material.FrontfaceCulling && material.BackfaceCulling) 2253// if (material.FrontfaceCulling && material.BackfaceCulling)
2254// pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW); 2254// pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW);
2255// else 2255// else
2256 if (material.FrontfaceCulling) 2256 if (material.FrontfaceCulling)
2257 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); 2257 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
2258 else 2258 else
2259 if (material.BackfaceCulling) 2259 if (material.BackfaceCulling)
2260 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); 2260 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
2261 else 2261 else
2262 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); 2262 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
2263 } 2263 }
2264 2264
2265 // fog 2265 // fog
2266 if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) 2266 if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable)
2267 { 2267 {
2268 pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); 2268 pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable);
2269 } 2269 }
2270 2270
2271 // specular highlights 2271 // specular highlights
2272 if (resetAllRenderstates || !core::equals(lastmaterial.Shininess,material.Shininess)) 2272 if (resetAllRenderstates || !core::equals(lastmaterial.Shininess,material.Shininess))
2273 { 2273 {
2274 const bool enable = (material.Shininess!=0.0f); 2274 const bool enable = (material.Shininess!=0.0f);
2275 pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); 2275 pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable);
2276 pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); 2276 pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);
2277 } 2277 }
2278 2278
2279 // normalization 2279 // normalization
2280 if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) 2280 if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals)
2281 { 2281 {
2282 pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); 2282 pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals);
2283 } 2283 }
2284 2284
2285 // Color Mask 2285 // Color Mask
2286 if (queryFeature(EVDF_COLOR_MASK) && 2286 if (queryFeature(EVDF_COLOR_MASK) &&
2287 (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask)) 2287 (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask))
2288 { 2288 {
2289 const DWORD flag = 2289 const DWORD flag =
2290 ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | 2290 ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) |
2291 ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | 2291 ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) |
2292 ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | 2292 ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) |
2293 ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); 2293 ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0);
2294 pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); 2294 pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag);
2295 } 2295 }
2296 2296
2297 if (queryFeature(EVDF_BLEND_OPERATIONS) && 2297 if (queryFeature(EVDF_BLEND_OPERATIONS) &&
2298 (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation)) 2298 (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation))
2299 { 2299 {
2300 if (material.BlendOperation==EBO_NONE) 2300 if (material.BlendOperation==EBO_NONE)
2301 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 2301 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
2302 else 2302 else
2303 { 2303 {
2304 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 2304 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
2305 switch (material.BlendOperation) 2305 switch (material.BlendOperation)
2306 { 2306 {
2307 case EBO_SUBTRACT: 2307 case EBO_SUBTRACT:
2308 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); 2308 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
2309 break; 2309 break;
2310 case EBO_REVSUBTRACT: 2310 case EBO_REVSUBTRACT:
2311 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); 2311 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
2312 break; 2312 break;
2313 case EBO_MIN: 2313 case EBO_MIN:
2314 case EBO_MIN_FACTOR: 2314 case EBO_MIN_FACTOR:
2315 case EBO_MIN_ALPHA: 2315 case EBO_MIN_ALPHA:
2316 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); 2316 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN);
2317 break; 2317 break;
2318 case EBO_MAX: 2318 case EBO_MAX:
2319 case EBO_MAX_FACTOR: 2319 case EBO_MAX_FACTOR:
2320 case EBO_MAX_ALPHA: 2320 case EBO_MAX_ALPHA:
2321 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); 2321 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX);
2322 break; 2322 break;
2323 default: 2323 default:
2324 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); 2324 pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
2325 break; 2325 break;
2326 } 2326 }
2327 } 2327 }
2328 } 2328 }
2329 2329
2330 // Polygon offset 2330 // Polygon offset
2331 if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || 2331 if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates ||
2332 lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || 2332 lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
2333 lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) 2333 lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor))
2334 { 2334 {
2335 if (material.PolygonOffsetFactor) 2335 if (material.PolygonOffsetFactor)
2336 { 2336 {
2337 if (material.PolygonOffsetDirection==EPO_BACK) 2337 if (material.PolygonOffsetDirection==EPO_BACK)
2338 { 2338 {
2339 pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1.f)); 2339 pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1.f));
2340 pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)material.PolygonOffsetFactor)); 2340 pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)material.PolygonOffsetFactor));
2341 } 2341 }
2342 else 2342 else
2343 { 2343 {
2344 pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(-1.f)); 2344 pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(-1.f));
2345 pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)-material.PolygonOffsetFactor)); 2345 pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)-material.PolygonOffsetFactor));
2346 } 2346 }
2347 } 2347 }
2348 else 2348 else
2349 { 2349 {
2350 pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); 2350 pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
2351 pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); 2351 pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
2352 } 2352 }
2353 } 2353 }
2354 2354
2355 // Anti Aliasing 2355 // Anti Aliasing
2356 if (resetAllRenderstates || lastmaterial.AntiAliasing != material.AntiAliasing) 2356 if (resetAllRenderstates || lastmaterial.AntiAliasing != material.AntiAliasing)
2357 { 2357 {
2358 if (AlphaToCoverageSupport && (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)) 2358 if (AlphaToCoverageSupport && (material.AntiAliasing & EAAM_ALPHA_TO_COVERAGE))
2359 { 2359 {
2360 if (VendorID==0x10DE)//NVidia 2360 if (VendorID==0x10DE)//NVidia
2361 pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, MAKEFOURCC('A','T','O','C')); 2361 pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, MAKEFOURCC('A','T','O','C'));
2362 // SSAA could give better results on NVidia cards 2362 // SSAA could give better results on NVidia cards
2363 else if (VendorID==0x1002)//ATI 2363 else if (VendorID==0x1002)//ATI
2364 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1')); 2364 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','1'));
2365 } 2365 }
2366 else if (AlphaToCoverageSupport && (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE)) 2366 else if (AlphaToCoverageSupport && (lastmaterial.AntiAliasing & EAAM_ALPHA_TO_COVERAGE))
2367 { 2367 {
2368 if (VendorID==0x10DE) 2368 if (VendorID==0x10DE)
2369 pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN); 2369 pID3DDevice->SetRenderState(D3DRS_ADAPTIVETESS_Y, D3DFMT_UNKNOWN);
2370 else if (VendorID==0x1002) 2370 else if (VendorID==0x1002)
2371 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0')); 2371 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, MAKEFOURCC('A','2','M','0'));
2372 } 2372 }
2373 2373
2374 // enable antialiasing 2374 // enable antialiasing
2375 if (Params.AntiAlias) 2375 if (Params.AntiAlias)
2376 { 2376 {
2377 if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)) 2377 if (material.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY))
2378 pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); 2378 pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
2379 else if (lastmaterial.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY)) 2379 else if (lastmaterial.AntiAliasing & (EAAM_SIMPLE|EAAM_QUALITY))
2380 pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE); 2380 pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, FALSE);
2381 if (material.AntiAliasing & (EAAM_LINE_SMOOTH)) 2381 if (material.AntiAliasing & (EAAM_LINE_SMOOTH))
2382 pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, TRUE); 2382 pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, TRUE);
2383 else if (lastmaterial.AntiAliasing & (EAAM_LINE_SMOOTH)) 2383 else if (lastmaterial.AntiAliasing & (EAAM_LINE_SMOOTH))
2384 pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE); 2384 pID3DDevice->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE);
2385 } 2385 }
2386 } 2386 }
2387 2387
2388 // thickness 2388 // thickness
2389 if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) 2389 if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness)
2390 { 2390 {
2391 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(material.Thickness)); 2391 pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(material.Thickness));
2392 } 2392 }
2393 2393
2394 // texture address mode 2394 // texture address mode
2395 for (u32 st=0; st<MaxTextureUnits; ++st) 2395 for (u32 st=0; st<MaxTextureUnits; ++st)
2396 { 2396 {
2397 if (resetAllRenderstates && Params.HandleSRGB) 2397 if (resetAllRenderstates && Params.HandleSRGB)
2398 pID3DDevice->SetSamplerState(st, D3DSAMP_SRGBTEXTURE, TRUE); 2398 pID3DDevice->SetSamplerState(st, D3DSAMP_SRGBTEXTURE, TRUE);
2399 2399
2400 if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias) 2400 if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias)
2401 { 2401 {
2402 const float tmp = material.TextureLayer[st].LODBias * 0.125f; 2402 const float tmp = material.TextureLayer[st].LODBias * 0.125f;
2403 pID3DDevice->SetSamplerState(st, D3DSAMP_MIPMAPLODBIAS, F2DW(tmp)); 2403 pID3DDevice->SetSamplerState(st, D3DSAMP_MIPMAPLODBIAS, F2DW(tmp));
2404 } 2404 }
2405 2405
2406 if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) 2406 if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU)
2407 pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); 2407 pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
2408 // If separate UV not supported reuse U for V 2408 // If separate UV not supported reuse U for V
2409 if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV)) 2409 if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV))
2410 pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); 2410 pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU));
2411 else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV) 2411 else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV)
2412 pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV)); 2412 pID3DDevice->SetSamplerState(st, D3DSAMP_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV));
2413 2413
2414 // Bilinear, trilinear, and anisotropic filter 2414 // Bilinear, trilinear, and anisotropic filter
2415 if (resetAllRenderstates || 2415 if (resetAllRenderstates ||
2416 lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || 2416 lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter ||
2417 lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || 2417 lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter ||
2418 lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter || 2418 lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter ||
2419 lastmaterial.UseMipMaps != material.UseMipMaps) 2419 lastmaterial.UseMipMaps != material.UseMipMaps)
2420 { 2420 {
2421 if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter) 2421 if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter)
2422 { 2422 {
2423 D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && 2423 D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) &&
2424 material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; 2424 material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
2425 D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && 2425 D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) &&
2426 material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; 2426 material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR;
2427 D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE; 2427 D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE;
2428 2428
2429 if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC) 2429 if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC)
2430 pID3DDevice->SetSamplerState(st, D3DSAMP_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy)); 2430 pID3DDevice->SetSamplerState(st, D3DSAMP_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy));
2431 pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, tftMag); 2431 pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, tftMag);
2432 pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, tftMin); 2432 pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, tftMin);
2433 pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, tftMip); 2433 pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, tftMip);
2434 } 2434 }
2435 else 2435 else
2436 { 2436 {
2437 pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, D3DTEXF_POINT); 2437 pID3DDevice->SetSamplerState(st, D3DSAMP_MINFILTER, D3DTEXF_POINT);
2438 pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, D3DTEXF_NONE); 2438 pID3DDevice->SetSamplerState(st, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
2439 pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, D3DTEXF_POINT); 2439 pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
2440 } 2440 }
2441 } 2441 }
2442 } 2442 }
2443} 2443}
2444 2444
2445 2445
2446//! sets the needed renderstates 2446//! sets the needed renderstates
2447void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) 2447void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible)
2448{ 2448{
2449 if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && 2449 if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL &&
2450 CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || 2450 CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) ||
2451 Transformation3DChanged) 2451 Transformation3DChanged)
2452 { 2452 {
2453 // unset last 3d material 2453 // unset last 3d material
2454 if (CurrentRenderMode == ERM_3D && 2454 if (CurrentRenderMode == ERM_3D &&
2455 static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) 2455 static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
2456 { 2456 {
2457 MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); 2457 MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial();
2458 ResetRenderStates = true; 2458 ResetRenderStates = true;
2459 } 2459 }
2460 // switch back the matrices 2460 // switch back the matrices
2461 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); 2461 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW]));
2462 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); 2462 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD]));
2463 pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); 2463 pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION]));
2464 2464
2465 Transformation3DChanged = false; 2465 Transformation3DChanged = false;
2466 2466
2467 setActiveTexture(0,0); 2467 setActiveTexture(0,0);
2468 setActiveTexture(1,0); 2468 setActiveTexture(1,0);
2469 setActiveTexture(2,0); 2469 setActiveTexture(2,0);
2470 setActiveTexture(3,0); 2470 setActiveTexture(3,0);
2471 2471
2472 pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); 2472 pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
2473 2473
2474 pID3DDevice->SetFVF(D3DFVF_XYZ); 2474 pID3DDevice->SetFVF(D3DFVF_XYZ);
2475 LastVertexType = (video::E_VERTEX_TYPE)(-1); 2475 LastVertexType = (video::E_VERTEX_TYPE)(-1);
2476 2476
2477 pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); 2477 pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
2478 pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); 2478 pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
2479 pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); 2479 pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
2480 //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); 2480 //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
2481 //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); 2481 //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
2482 2482
2483 pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); 2483 pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
2484 pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0); 2484 pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0);
2485 pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); 2485 pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
2486 pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); 2486 pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
2487 2487
2488 pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE ); 2488 pID3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
2489 pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO ); 2489 pID3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ZERO );
2490 pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); 2490 pID3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
2491 2491
2492 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); 2492 pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
2493 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); 2493 pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
2494 2494
2495 //if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) 2495 //if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY)))
2496 // pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); 2496 // pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0);
2497 if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)) 2497 if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY))
2498 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); 2498 pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
2499 } 2499 }
2500 2500
2501 if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) 2501 if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail)
2502 { 2502 {
2503 // USE THE ZPASS METHOD 2503 // USE THE ZPASS METHOD
2504 pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); 2504 pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
2505 pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); 2505 pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
2506 //pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); // does not matter, will be set later 2506 //pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); // does not matter, will be set later
2507 } 2507 }
2508 else 2508 else
2509 if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) 2509 if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail)
2510 { 2510 {
2511 // USE THE ZFAIL METHOD 2511 // USE THE ZFAIL METHOD
2512 pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); 2512 pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
2513 //pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); // does not matter, will be set later 2513 //pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); // does not matter, will be set later
2514 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); 2514 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
2515 } 2515 }
2516 2516
2517 CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; 2517 CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS;
2518} 2518}
2519 2519
2520 2520
2521//! sets the needed renderstates 2521//! sets the needed renderstates
2522void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha) 2522void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha)
2523{ 2523{
2524 if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) 2524 if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged)
2525 { 2525 {
2526 core::matrix4 mat; 2526 core::matrix4 mat;
2527 pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D9); 2527 pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D9);
2528 pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D9); 2528 pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D9);
2529 pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D9); 2529 pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D9);
2530 2530
2531 pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); 2531 pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE);
2532 pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); 2532 pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
2533 pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); 2533 pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
2534 2534
2535 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); 2535 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
2536 2536
2537 pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1); 2537 pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1);
2538 pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); 2538 pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL);
2539 //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); 2539 //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL);
2540 pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); 2540 pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
2541 pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); 2541 pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
2542 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); 2542 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
2543 pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); 2543 pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
2544 pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); 2544 pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
2545 2545
2546 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); 2546 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
2547 2547
2548 Transformation3DChanged = false; 2548 Transformation3DChanged = false;
2549 2549
2550 pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 2550 pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
2551 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 2551 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2552 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 2552 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
2553 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); 2553 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
2554 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); 2554 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
2555 if (alpha) 2555 if (alpha)
2556 { 2556 {
2557 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 2557 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
2558 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 2558 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2559 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 2559 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2560 } 2560 }
2561 else 2561 else
2562 { 2562 {
2563 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 2563 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
2564 } 2564 }
2565 } 2565 }
2566 2566
2567 CurrentRenderMode = ERM_STENCIL_FILL; 2567 CurrentRenderMode = ERM_STENCIL_FILL;
2568} 2568}
2569 2569
2570 2570
2571//! Enable the 2d override material 2571//! Enable the 2d override material
2572void CD3D9Driver::enableMaterial2D(bool enable) 2572void CD3D9Driver::enableMaterial2D(bool enable)
2573{ 2573{
2574 if (!enable) 2574 if (!enable)
2575 CurrentRenderMode = ERM_NONE; 2575 CurrentRenderMode = ERM_NONE;
2576 CNullDriver::enableMaterial2D(enable); 2576 CNullDriver::enableMaterial2D(enable);
2577} 2577}
2578 2578
2579 2579
2580//! sets the needed renderstates 2580//! sets the needed renderstates
2581void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) 2581void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel)
2582{ 2582{
2583 if (!pID3DDevice) 2583 if (!pID3DDevice)
2584 return; 2584 return;
2585 2585
2586 if (CurrentRenderMode != ERM_2D || Transformation3DChanged) 2586 if (CurrentRenderMode != ERM_2D || Transformation3DChanged)
2587 { 2587 {
2588 // unset last 3d material 2588 // unset last 3d material
2589 if (CurrentRenderMode == ERM_3D) 2589 if (CurrentRenderMode == ERM_3D)
2590 { 2590 {
2591 if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) 2591 if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size())
2592 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); 2592 MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial();
2593 } 2593 }
2594 if (!OverrideMaterial2DEnabled) 2594 if (!OverrideMaterial2DEnabled)
2595 { 2595 {
2596 setBasicRenderStates(InitMaterial2D, LastMaterial, true); 2596 setBasicRenderStates(InitMaterial2D, LastMaterial, true);
2597 LastMaterial=InitMaterial2D; 2597 LastMaterial=InitMaterial2D;
2598 2598
2599 // fix everything that is wrongly set by InitMaterial2D default 2599 // fix everything that is wrongly set by InitMaterial2D default
2600 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); 2600 pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
2601 2601
2602 pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); 2602 pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
2603 } 2603 }
2604 core::matrix4 m; 2604 core::matrix4 m;
2605// this fixes some problems with pixel exact rendering, but also breaks nice texturing 2605// this fixes some problems with pixel exact rendering, but also breaks nice texturing
2606// moreover, it would have to be tested in each call, as the texture flag can change each time 2606// moreover, it would have to be tested in each call, as the texture flag can change each time
2607// if (!texture) 2607// if (!texture)
2608// m.setTranslation(core::vector3df(0.5f,0.5f,0)); 2608// m.setTranslation(core::vector3df(0.5f,0.5f,0));
2609 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)m.pointer())); 2609 pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)m.pointer()));
2610 2610
2611 // adjust the view such that pixel center aligns with texels 2611 // adjust the view such that pixel center aligns with texels
2612 // Otherwise, subpixel artifacts will occur 2612 // Otherwise, subpixel artifacts will occur
2613 m.setTranslation(core::vector3df(-0.5f,-0.5f,0)); 2613 m.setTranslation(core::vector3df(-0.5f,-0.5f,0));
2614 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer())); 2614 pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer()));
2615 2615
2616 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); 2616 const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
2617 m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0); 2617 m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0);
2618 m.setTranslation(core::vector3df(-1,1,0)); 2618 m.setTranslation(core::vector3df(-1,1,0));
2619 pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer())); 2619 pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer()));
2620 2620
2621 // 2d elements are clipped in software 2621 // 2d elements are clipped in software
2622 pID3DDevice->SetRenderState(D3DRS_CLIPPING, FALSE); 2622 pID3DDevice->SetRenderState(D3DRS_CLIPPING, FALSE);
2623 2623
2624 Transformation3DChanged = false; 2624 Transformation3DChanged = false;
2625 } 2625 }
2626 if (OverrideMaterial2DEnabled) 2626 if (OverrideMaterial2DEnabled)
2627 { 2627 {
2628 OverrideMaterial2D.Lighting=false; 2628 OverrideMaterial2D.Lighting=false;
2629 setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); 2629 setBasicRenderStates(OverrideMaterial2D, LastMaterial, false);
2630 LastMaterial = OverrideMaterial2D; 2630 LastMaterial = OverrideMaterial2D;
2631 } 2631 }
2632 2632
2633 // no alphaChannel without texture 2633 // no alphaChannel without texture
2634 alphaChannel &= texture; 2634 alphaChannel &= texture;
2635 2635
2636 if (alpha || alphaChannel) 2636 if (alpha || alphaChannel)
2637 { 2637 {
2638 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); 2638 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
2639 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 2639 pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
2640 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 2640 pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
2641 } 2641 }
2642 else 2642 else
2643 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); 2643 pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
2644 pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); 2644 pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
2645 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 2645 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
2646 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); 2646 pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
2647 if (texture) 2647 if (texture)
2648 { 2648 {
2649 setTransform(ETS_TEXTURE_0, core::IdentityMatrix); 2649 setTransform(ETS_TEXTURE_0, core::IdentityMatrix);
2650 // Due to the transformation change, the previous line would call a reset each frame 2650 // Due to the transformation change, the previous line would call a reset each frame
2651 // but we can safely reset the variable as it was false before 2651 // but we can safely reset the variable as it was false before
2652 Transformation3DChanged=false; 2652 Transformation3DChanged=false;
2653 } 2653 }
2654 if (alphaChannel) 2654 if (alphaChannel)
2655 { 2655 {
2656 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 2656 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
2657 2657
2658 if (alpha) 2658 if (alpha)
2659 { 2659 {
2660 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 2660 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
2661 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); 2661 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
2662 } 2662 }
2663 else 2663 else
2664 { 2664 {
2665 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); 2665 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
2666 } 2666 }
2667 } 2667 }
2668 else 2668 else
2669 { 2669 {
2670 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); 2670 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
2671 if (alpha) 2671 if (alpha)
2672 { 2672 {
2673 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); 2673 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
2674 } 2674 }
2675 else 2675 else
2676 { 2676 {
2677 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); 2677 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
2678 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); 2678 pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
2679 } 2679 }
2680 } 2680 }
2681 2681
2682 CurrentRenderMode = ERM_2D; 2682 CurrentRenderMode = ERM_2D;
2683} 2683}
2684 2684
2685 2685
2686//! deletes all dynamic lights there are 2686//! deletes all dynamic lights there are
2687void CD3D9Driver::deleteAllDynamicLights() 2687void CD3D9Driver::deleteAllDynamicLights()
2688{ 2688{
2689 for (s32 i=0; i<LastSetLight+1; ++i) 2689 for (s32 i=0; i<LastSetLight+1; ++i)
2690 pID3DDevice->LightEnable(i, false); 2690 pID3DDevice->LightEnable(i, false);
2691 2691
2692 LastSetLight = -1; 2692 LastSetLight = -1;
2693 2693
2694 CNullDriver::deleteAllDynamicLights(); 2694 CNullDriver::deleteAllDynamicLights();
2695} 2695}
2696 2696
2697 2697
2698//! adds a dynamic light 2698//! adds a dynamic light
2699s32 CD3D9Driver::addDynamicLight(const SLight& dl) 2699s32 CD3D9Driver::addDynamicLight(const SLight& dl)
2700{ 2700{
2701 CNullDriver::addDynamicLight(dl); 2701 CNullDriver::addDynamicLight(dl);
2702 2702
2703 D3DLIGHT9 light; 2703 D3DLIGHT9 light;
2704 2704
2705 switch (dl.Type) 2705 switch (dl.Type)
2706 { 2706 {
2707 case ELT_POINT: 2707 case ELT_POINT:
2708 light.Type = D3DLIGHT_POINT; 2708 light.Type = D3DLIGHT_POINT;
2709 break; 2709 break;
2710 case ELT_SPOT: 2710 case ELT_SPOT:
2711 light.Type = D3DLIGHT_SPOT; 2711 light.Type = D3DLIGHT_SPOT;
2712 break; 2712 break;
2713 case ELT_DIRECTIONAL: 2713 case ELT_DIRECTIONAL:
2714 light.Type = D3DLIGHT_DIRECTIONAL; 2714 light.Type = D3DLIGHT_DIRECTIONAL;
2715 break; 2715 break;
2716 } 2716 }
2717 2717
2718 light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); 2718 light.Position = *(D3DVECTOR*)((void*)(&dl.Position));
2719 light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); 2719 light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction));
2720 2720
2721 light.Range = core::min_(dl.Radius, MaxLightDistance); 2721 light.Range = core::min_(dl.Radius, MaxLightDistance);
2722 light.Falloff = dl.Falloff; 2722 light.Falloff = dl.Falloff;
2723 2723
2724 light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); 2724 light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor));
2725 light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); 2725 light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor));
2726 light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); 2726 light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor));
2727 2727
2728 light.Attenuation0 = dl.Attenuation.X; 2728 light.Attenuation0 = dl.Attenuation.X;
2729 light.Attenuation1 = dl.Attenuation.Y; 2729 light.Attenuation1 = dl.Attenuation.Y;
2730 light.Attenuation2 = dl.Attenuation.Z; 2730 light.Attenuation2 = dl.Attenuation.Z;
2731 2731
2732 light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; 2732 light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD;
2733 light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; 2733 light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD;
2734 2734
2735 ++LastSetLight; 2735 ++LastSetLight;
2736 2736
2737 if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light)) 2737 if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light))
2738 { 2738 {
2739 // I don't care if this succeeds 2739 // I don't care if this succeeds
2740 (void)pID3DDevice->LightEnable(LastSetLight, true); 2740 (void)pID3DDevice->LightEnable(LastSetLight, true);
2741 return LastSetLight; 2741 return LastSetLight;
2742 } 2742 }
2743 2743
2744 return -1; 2744 return -1;
2745} 2745}
2746 2746
2747//! Turns a dynamic light on or off 2747//! Turns a dynamic light on or off
2748//! \param lightIndex: the index returned by addDynamicLight 2748//! \param lightIndex: the index returned by addDynamicLight
2749//! \param turnOn: true to turn the light on, false to turn it off 2749//! \param turnOn: true to turn the light on, false to turn it off
2750void CD3D9Driver::turnLightOn(s32 lightIndex, bool turnOn) 2750void CD3D9Driver::turnLightOn(s32 lightIndex, bool turnOn)
2751{ 2751{
2752 if(lightIndex < 0 || lightIndex > LastSetLight) 2752 if(lightIndex < 0 || lightIndex > LastSetLight)
2753 return; 2753 return;
2754 2754
2755 (void)pID3DDevice->LightEnable(lightIndex, turnOn); 2755 (void)pID3DDevice->LightEnable(lightIndex, turnOn);
2756} 2756}
2757 2757
2758 2758
2759//! returns the maximal amount of dynamic lights the device can handle 2759//! returns the maximal amount of dynamic lights the device can handle
2760u32 CD3D9Driver::getMaximalDynamicLightAmount() const 2760u32 CD3D9Driver::getMaximalDynamicLightAmount() const
2761{ 2761{
2762 return Caps.MaxActiveLights; 2762 return Caps.MaxActiveLights;
2763} 2763}
2764 2764
2765 2765
2766//! Sets the dynamic ambient light color. The default color is 2766//! Sets the dynamic ambient light color. The default color is
2767//! (0,0,0,0) which means it is dark. 2767//! (0,0,0,0) which means it is dark.
2768//! \param color: New color of the ambient light. 2768//! \param color: New color of the ambient light.
2769void CD3D9Driver::setAmbientLight(const SColorf& color) 2769void CD3D9Driver::setAmbientLight(const SColorf& color)
2770{ 2770{
2771 if (!pID3DDevice) 2771 if (!pID3DDevice)
2772 return; 2772 return;
2773 2773
2774 AmbientLight = color; 2774 AmbientLight = color;
2775 D3DCOLOR col = color.toSColor().color; 2775 D3DCOLOR col = color.toSColor().color;
2776 pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); 2776 pID3DDevice->SetRenderState(D3DRS_AMBIENT, col);
2777} 2777}
2778 2778
2779 2779
2780//! \return Returns the name of the video driver. Example: In case of the DIRECT3D9 2780//! \return Returns the name of the video driver. Example: In case of the DIRECT3D9
2781//! driver, it would return "Direct3D9.0". 2781//! driver, it would return "Direct3D9.0".
2782const wchar_t* CD3D9Driver::getName() const 2782const wchar_t* CD3D9Driver::getName() const
2783{ 2783{
2784 return L"Direct3D 9.0"; 2784 return L"Direct3D 9.0";
2785} 2785}
2786 2786
2787 2787
2788//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do 2788//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do
2789//! this: First, draw all geometry. Then use this method, to draw the shadow 2789//! this: First, draw all geometry. Then use this method, to draw the shadow
2790//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. 2790//! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow.
2791void CD3D9Driver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) 2791void CD3D9Driver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)
2792{ 2792{
2793 if (!Params.Stencilbuffer) 2793 if (!Params.Stencilbuffer)
2794 return; 2794 return;
2795 2795
2796 setRenderStatesStencilShadowMode(zfail, debugDataVisible); 2796 setRenderStatesStencilShadowMode(zfail, debugDataVisible);
2797 2797
2798 const u32 count = triangles.size(); 2798 const u32 count = triangles.size();
2799 if (!count) 2799 if (!count)
2800 return; 2800 return;
2801 2801
2802 if (!zfail) 2802 if (!zfail)
2803 { 2803 {
2804 // ZPASS Method 2804 // ZPASS Method
2805 2805
2806 // Draw front-side of shadow volume in stencil only 2806 // Draw front-side of shadow volume in stencil only
2807 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); 2807 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
2808 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); 2808 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);
2809 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); 2809 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df));
2810 2810
2811 // Now reverse cull order so front sides of shadow volume are written. 2811 // Now reverse cull order so front sides of shadow volume are written.
2812 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); 2812 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
2813 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR); 2813 pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR);
2814 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); 2814 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df));
2815 } 2815 }
2816 else 2816 else
2817 { 2817 {
2818 // ZFAIL Method 2818 // ZFAIL Method
2819 2819
2820 // Draw front-side of shadow volume in stencil only 2820 // Draw front-side of shadow volume in stencil only
2821 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); 2821 pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
2822 pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); 2822 pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR);
2823 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); 2823 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df));
2824 2824
2825 // Now reverse cull order so front sides of shadow volume are written. 2825 // Now reverse cull order so front sides of shadow volume are written.
2826 pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); 2826 pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW);
2827 pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR); 2827 pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
2828 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); 2828 pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df));
2829 } 2829 }
2830} 2830}
2831 2831
2832 2832
2833//! Fills the stencil shadow with color. After the shadow volume has been drawn 2833//! Fills the stencil shadow with color. After the shadow volume has been drawn
2834//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this 2834//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
2835//! to draw the color of the shadow. 2835//! to draw the color of the shadow.
2836void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, 2836void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
2837 video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) 2837 video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
2838{ 2838{
2839 if (!Params.Stencilbuffer) 2839 if (!Params.Stencilbuffer)
2840 return; 2840 return;
2841 2841
2842 S3DVertex vtx[4]; 2842 S3DVertex vtx[4];
2843 vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); 2843 vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f);
2844 vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); 2844 vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f);
2845 vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); 2845 vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f);
2846 vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); 2846 vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f);
2847 2847
2848 s16 indices[6] = {0,1,2,1,3,2}; 2848 s16 indices[6] = {0,1,2,1,3,2};
2849 2849
2850 setRenderStatesStencilFillMode( 2850 setRenderStatesStencilFillMode(
2851 leftUpEdge.getAlpha() < 255 || 2851 leftUpEdge.getAlpha() < 255 ||
2852 rightUpEdge.getAlpha() < 255 || 2852 rightUpEdge.getAlpha() < 255 ||
2853 leftDownEdge.getAlpha() < 255 || 2853 leftDownEdge.getAlpha() < 255 ||
2854 rightDownEdge.getAlpha() < 255); 2854 rightDownEdge.getAlpha() < 255);
2855 2855
2856 setActiveTexture(0,0); 2856 setActiveTexture(0,0);
2857 2857
2858 setVertexShader(EVT_STANDARD); 2858 setVertexShader(EVT_STANDARD);
2859 2859
2860 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], 2860 pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
2861 D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); 2861 D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex));
2862 2862
2863 if (clearStencilBuffer) 2863 if (clearStencilBuffer)
2864 pID3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); 2864 pID3DDevice->Clear( 0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0);
2865} 2865}
2866 2866
2867 2867
2868//! Returns the maximum amount of primitives (mostly vertices) which 2868//! Returns the maximum amount of primitives (mostly vertices) which
2869//! the device is able to render with one drawIndexedTriangleList 2869//! the device is able to render with one drawIndexedTriangleList
2870//! call. 2870//! call.
2871u32 CD3D9Driver::getMaximalPrimitiveCount() const 2871u32 CD3D9Driver::getMaximalPrimitiveCount() const
2872{ 2872{
2873 return Caps.MaxPrimitiveCount; 2873 return Caps.MaxPrimitiveCount;
2874} 2874}
2875 2875
2876 2876
2877//! Sets the fog mode. 2877//! Sets the fog mode.
2878void CD3D9Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, 2878void CD3D9Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start,
2879 f32 end, f32 density, bool pixelFog, bool rangeFog) 2879 f32 end, f32 density, bool pixelFog, bool rangeFog)
2880{ 2880{
2881 CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); 2881 CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog);
2882 2882
2883 if (!pID3DDevice) 2883 if (!pID3DDevice)
2884 return; 2884 return;
2885 2885
2886 pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); 2886 pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color);
2887 2887
2888 pID3DDevice->SetRenderState( 2888 pID3DDevice->SetRenderState(
2889 pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, 2889 pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE,
2890 (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2); 2890 (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2);
2891 2891
2892 if (fogType==EFT_FOG_LINEAR) 2892 if (fogType==EFT_FOG_LINEAR)
2893 { 2893 {
2894 pID3DDevice->SetRenderState(D3DRS_FOGSTART, F2DW(start)); 2894 pID3DDevice->SetRenderState(D3DRS_FOGSTART, F2DW(start));
2895 pID3DDevice->SetRenderState(D3DRS_FOGEND, F2DW(end)); 2895 pID3DDevice->SetRenderState(D3DRS_FOGEND, F2DW(end));
2896 } 2896 }
2897 else 2897 else
2898 pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, F2DW(density)); 2898 pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, F2DW(density));
2899 2899
2900 if(!pixelFog) 2900 if(!pixelFog)
2901 pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); 2901 pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog);
2902} 2902}
2903 2903
2904 2904
2905//! Draws a 3d line. 2905//! Draws a 3d line.
2906void CD3D9Driver::draw3DLine(const core::vector3df& start, 2906void CD3D9Driver::draw3DLine(const core::vector3df& start,
2907 const core::vector3df& end, SColor color) 2907 const core::vector3df& end, SColor color)
2908{ 2908{
2909 setVertexShader(EVT_STANDARD); 2909 setVertexShader(EVT_STANDARD);
2910 setRenderStates3DMode(); 2910 setRenderStates3DMode();
2911 video::S3DVertex v[2]; 2911 video::S3DVertex v[2];
2912 v[0].Color = color; 2912 v[0].Color = color;
2913 v[1].Color = color; 2913 v[1].Color = color;
2914 v[0].Pos = start; 2914 v[0].Pos = start;
2915 v[1].Pos = end; 2915 v[1].Pos = end;
2916 2916
2917 pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); 2917 pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex));
2918} 2918}
2919 2919
2920 2920
2921//! resets the device 2921//! resets the device
2922bool CD3D9Driver::reset() 2922bool CD3D9Driver::reset()
2923{ 2923{
2924 u32 i; 2924 u32 i;
2925 os::Printer::log("Resetting D3D9 device.", ELL_INFORMATION); 2925 os::Printer::log("Resetting D3D9 device.", ELL_INFORMATION);
2926 2926
2927 for (i=0; i<Textures.size(); ++i) 2927 for (i=0; i<Textures.size(); ++i)
2928 { 2928 {
2929 if (Textures[i].Surface->isRenderTarget()) 2929 if (Textures[i].Surface->isRenderTarget())
2930 { 2930 {
2931 IDirect3DBaseTexture9* tex = ((CD3D9Texture*)(Textures[i].Surface))->getDX9Texture(); 2931 IDirect3DBaseTexture9* tex = ((CD3D9Texture*)(Textures[i].Surface))->getDX9Texture();
2932 if (tex) 2932 if (tex)
2933 tex->Release(); 2933 tex->Release();
2934 } 2934 }
2935 } 2935 }
2936 for (i=0; i<DepthBuffers.size(); ++i) 2936 for (i=0; i<DepthBuffers.size(); ++i)
2937 { 2937 {
2938 if (DepthBuffers[i]->Surface) 2938 if (DepthBuffers[i]->Surface)
2939 DepthBuffers[i]->Surface->Release(); 2939 DepthBuffers[i]->Surface->Release();
2940 } 2940 }
2941 for (i=0; i<OcclusionQueries.size(); ++i) 2941 for (i=0; i<OcclusionQueries.size(); ++i)
2942 { 2942 {
2943 if (OcclusionQueries[i].PID) 2943 if (OcclusionQueries[i].PID)
2944 { 2944 {
2945 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[i].PID)->Release(); 2945 reinterpret_cast<IDirect3DQuery9*>(OcclusionQueries[i].PID)->Release();
2946 OcclusionQueries[i].PID=0; 2946 OcclusionQueries[i].PID=0;
2947 } 2947 }
2948 } 2948 }
2949 // this does not require a restore in the reset method, it's updated 2949 // this does not require a restore in the reset method, it's updated
2950 // automatically in the next render cycle. 2950 // automatically in the next render cycle.
2951 removeAllHardwareBuffers(); 2951 removeAllHardwareBuffers();
2952 2952
2953 DriverWasReset=true; 2953 DriverWasReset=true;
2954 2954
2955 HRESULT hr = pID3DDevice->Reset(&present); 2955 HRESULT hr = pID3DDevice->Reset(&present);
2956 2956
2957 // restore RTTs 2957 // restore RTTs
2958 for (i=0; i<Textures.size(); ++i) 2958 for (i=0; i<Textures.size(); ++i)
2959 { 2959 {
2960 if (Textures[i].Surface->isRenderTarget()) 2960 if (Textures[i].Surface->isRenderTarget())
2961 ((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget(); 2961 ((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget();
2962 } 2962 }
2963 2963
2964 // restore screen depthbuffer 2964 // restore screen depthbuffer
2965 pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface)); 2965 pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
2966 D3DSURFACE_DESC desc; 2966 D3DSURFACE_DESC desc;
2967 // restore other depth buffers 2967 // restore other depth buffers
2968 // depth format is taken from main depth buffer 2968 // depth format is taken from main depth buffer
2969 DepthBuffers[0]->Surface->GetDesc(&desc); 2969 DepthBuffers[0]->Surface->GetDesc(&desc);
2970 // multisampling is taken from rendertarget 2970 // multisampling is taken from rendertarget
2971 D3DSURFACE_DESC desc2; 2971 D3DSURFACE_DESC desc2;
2972 for (i=1; i<DepthBuffers.size(); ++i) 2972 for (i=1; i<DepthBuffers.size(); ++i)
2973 { 2973 {
2974 for (u32 j=0; j<Textures.size(); ++j) 2974 for (u32 j=0; j<Textures.size(); ++j)
2975 { 2975 {
2976 // all textures sharing this depth buffer must have the same setting 2976 // all textures sharing this depth buffer must have the same setting
2977 // so take first one 2977 // so take first one
2978 if (((CD3D9Texture*)(Textures[j].Surface))->DepthSurface==DepthBuffers[i]) 2978 if (((CD3D9Texture*)(Textures[j].Surface))->DepthSurface==DepthBuffers[i])
2979 { 2979 {
2980 ((CD3D9Texture*)(Textures[j].Surface))->Texture->GetLevelDesc(0,&desc2); 2980 ((CD3D9Texture*)(Textures[j].Surface))->Texture->GetLevelDesc(0,&desc2);
2981 break; 2981 break;
2982 } 2982 }
2983 } 2983 }
2984 2984
2985 pID3DDevice->CreateDepthStencilSurface(DepthBuffers[i]->Size.Width, 2985 pID3DDevice->CreateDepthStencilSurface(DepthBuffers[i]->Size.Width,
2986 DepthBuffers[i]->Size.Height, 2986 DepthBuffers[i]->Size.Height,
2987 desc.Format, 2987 desc.Format,
2988 desc2.MultiSampleType, 2988 desc2.MultiSampleType,
2989 desc2.MultiSampleQuality, 2989 desc2.MultiSampleQuality,
2990 TRUE, 2990 TRUE,
2991 &(DepthBuffers[i]->Surface), 2991 &(DepthBuffers[i]->Surface),
2992 NULL); 2992 NULL);
2993 } 2993 }
2994 for (i=0; i<OcclusionQueries.size(); ++i) 2994 for (i=0; i<OcclusionQueries.size(); ++i)
2995 { 2995 {
2996 pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[i].PID)); 2996 pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[i].PID));
2997 } 2997 }
2998 2998
2999 if (FAILED(hr)) 2999 if (FAILED(hr))
3000 { 3000 {
3001 if (hr == D3DERR_DEVICELOST) 3001 if (hr == D3DERR_DEVICELOST)
3002 { 3002 {
3003 DeviceLost = true; 3003 DeviceLost = true;
3004 os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); 3004 os::Printer::log("Resetting failed due to device lost.", ELL_WARNING);
3005 } 3005 }
3006#ifdef D3DERR_DEVICEREMOVED 3006#ifdef D3DERR_DEVICEREMOVED
3007 else if (hr == D3DERR_DEVICEREMOVED) 3007 else if (hr == D3DERR_DEVICEREMOVED)
3008 { 3008 {
3009 os::Printer::log("Resetting failed due to device removed.", ELL_WARNING); 3009 os::Printer::log("Resetting failed due to device removed.", ELL_WARNING);
3010 } 3010 }
3011#endif 3011#endif
3012 else if (hr == D3DERR_DRIVERINTERNALERROR) 3012 else if (hr == D3DERR_DRIVERINTERNALERROR)
3013 { 3013 {
3014 os::Printer::log("Resetting failed due to internal error.", ELL_WARNING); 3014 os::Printer::log("Resetting failed due to internal error.", ELL_WARNING);
3015 } 3015 }
3016 else if (hr == D3DERR_OUTOFVIDEOMEMORY) 3016 else if (hr == D3DERR_OUTOFVIDEOMEMORY)
3017 { 3017 {
3018 os::Printer::log("Resetting failed due to out of memory.", ELL_WARNING); 3018 os::Printer::log("Resetting failed due to out of memory.", ELL_WARNING);
3019 } 3019 }
3020 else if (hr == D3DERR_DEVICENOTRESET) 3020 else if (hr == D3DERR_DEVICENOTRESET)
3021 { 3021 {
3022 os::Printer::log("Resetting failed due to not reset.", ELL_WARNING); 3022 os::Printer::log("Resetting failed due to not reset.", ELL_WARNING);
3023 } 3023 }
3024 else if (hr == D3DERR_INVALIDCALL) 3024 else if (hr == D3DERR_INVALIDCALL)
3025 { 3025 {
3026 os::Printer::log("Resetting failed due to invalid call", "You need to release some more surfaces.", ELL_WARNING); 3026 os::Printer::log("Resetting failed due to invalid call", "You need to release some more surfaces.", ELL_WARNING);
3027 } 3027 }
3028 else 3028 else
3029 { 3029 {
3030 os::Printer::log("Resetting failed due to unknown reason.", core::stringc((int)hr).c_str(), ELL_WARNING); 3030 os::Printer::log("Resetting failed due to unknown reason.", core::stringc((int)hr).c_str(), ELL_WARNING);
3031 } 3031 }
3032 return false; 3032 return false;
3033 } 3033 }
3034 3034
3035 DeviceLost = false; 3035 DeviceLost = false;
3036 ResetRenderStates = true; 3036 ResetRenderStates = true;
3037 LastVertexType = (E_VERTEX_TYPE)-1; 3037 LastVertexType = (E_VERTEX_TYPE)-1;
3038 3038
3039 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) 3039 for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i)
3040 CurrentTexture[i] = 0; 3040 CurrentTexture[i] = 0;
3041 3041
3042 setVertexShader(EVT_STANDARD); 3042 setVertexShader(EVT_STANDARD);
3043 setRenderStates3DMode(); 3043 setRenderStates3DMode();
3044 setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); 3044 setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog);
3045 setAmbientLight(AmbientLight); 3045 setAmbientLight(AmbientLight);
3046 3046
3047 return true; 3047 return true;
3048} 3048}
3049 3049
3050 3050
3051void CD3D9Driver::OnResize(const core::dimension2d<u32>& size) 3051void CD3D9Driver::OnResize(const core::dimension2d<u32>& size)
3052{ 3052{
3053 if (!pID3DDevice) 3053 if (!pID3DDevice)
3054 return; 3054 return;
3055 3055
3056 CNullDriver::OnResize(size); 3056 CNullDriver::OnResize(size);
3057 present.BackBufferWidth = size.Width; 3057 present.BackBufferWidth = size.Width;
3058 present.BackBufferHeight = size.Height; 3058 present.BackBufferHeight = size.Height;
3059 3059
3060 reset(); 3060 reset();
3061} 3061}
3062 3062
3063 3063
3064//! Returns type of video driver 3064//! Returns type of video driver
3065E_DRIVER_TYPE CD3D9Driver::getDriverType() const 3065E_DRIVER_TYPE CD3D9Driver::getDriverType() const
3066{ 3066{
3067 return EDT_DIRECT3D9; 3067 return EDT_DIRECT3D9;
3068} 3068}
3069 3069
3070 3070
3071//! Returns the transformation set by setTransform 3071//! Returns the transformation set by setTransform
3072const core::matrix4& CD3D9Driver::getTransform(E_TRANSFORMATION_STATE state) const 3072const core::matrix4& CD3D9Driver::getTransform(E_TRANSFORMATION_STATE state) const
3073{ 3073{
3074 return Matrices[state]; 3074 return Matrices[state];
3075} 3075}
3076 3076
3077 3077
3078//! Sets a vertex shader constant. 3078//! Sets a vertex shader constant.
3079void CD3D9Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) 3079void CD3D9Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
3080{ 3080{
3081 if (data) 3081 if (data)
3082 pID3DDevice->SetVertexShaderConstantF(startRegister, data, constantAmount); 3082 pID3DDevice->SetVertexShaderConstantF(startRegister, data, constantAmount);
3083} 3083}
3084 3084
3085 3085
3086//! Sets a pixel shader constant. 3086//! Sets a pixel shader constant.
3087void CD3D9Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) 3087void CD3D9Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
3088{ 3088{
3089 if (data) 3089 if (data)
3090 pID3DDevice->SetPixelShaderConstantF(startRegister, data, constantAmount); 3090 pID3DDevice->SetPixelShaderConstantF(startRegister, data, constantAmount);
3091} 3091}
3092 3092
3093 3093
3094//! Sets a constant for the vertex shader based on a name. 3094//! Sets a constant for the vertex shader based on a name.
3095bool CD3D9Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) 3095bool CD3D9Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count)
3096{ 3096{
3097 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 3097 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
3098 { 3098 {
3099 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; 3099 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer;
3100 return r->setVariable(true, name, floats, count); 3100 return r->setVariable(true, name, floats, count);
3101 } 3101 }
3102 3102
3103 return false; 3103 return false;
3104} 3104}
3105 3105
3106 3106
3107//! Bool interface for the above. 3107//! Bool interface for the above.
3108bool CD3D9Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) 3108bool CD3D9Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count)
3109{ 3109{
3110 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 3110 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
3111 { 3111 {
3112 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; 3112 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer;
3113 return r->setVariable(true, name, bools, count); 3113 return r->setVariable(true, name, bools, count);
3114 } 3114 }
3115 3115
3116 return false; 3116 return false;
3117} 3117}
3118 3118
3119 3119
3120//! Int interface for the above. 3120//! Int interface for the above.
3121bool CD3D9Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) 3121bool CD3D9Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count)
3122{ 3122{
3123 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 3123 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
3124 { 3124 {
3125 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; 3125 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer;
3126 return r->setVariable(true, name, ints, count); 3126 return r->setVariable(true, name, ints, count);
3127 } 3127 }
3128 3128
3129 return false; 3129 return false;
3130} 3130}
3131 3131
3132 3132
3133//! Sets a constant for the pixel shader based on a name. 3133//! Sets a constant for the pixel shader based on a name.
3134bool CD3D9Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) 3134bool CD3D9Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count)
3135{ 3135{
3136 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 3136 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
3137 { 3137 {
3138 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; 3138 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer;
3139 return r->setVariable(false, name, floats, count); 3139 return r->setVariable(false, name, floats, count);
3140 } 3140 }
3141 3141
3142 return false; 3142 return false;
3143} 3143}
3144 3144
3145 3145
3146//! Bool interface for the above. 3146//! Bool interface for the above.
3147bool CD3D9Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) 3147bool CD3D9Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count)
3148{ 3148{
3149 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 3149 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
3150 { 3150 {
3151 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; 3151 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer;
3152 return r->setVariable(false, name, bools, count); 3152 return r->setVariable(false, name, bools, count);
3153 } 3153 }
3154 3154
3155 return false; 3155 return false;
3156} 3156}
3157 3157
3158 3158
3159//! Int interface for the above. 3159//! Int interface for the above.
3160bool CD3D9Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) 3160bool CD3D9Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count)
3161{ 3161{
3162 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) 3162 if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size())
3163 { 3163 {
3164 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer; 3164 CD3D9MaterialRenderer* r = (CD3D9MaterialRenderer*)MaterialRenderers[Material.MaterialType].Renderer;
3165 return r->setVariable(false, name, ints, count); 3165 return r->setVariable(false, name, ints, count);
3166 } 3166 }
3167 3167
3168 return false; 3168 return false;
3169} 3169}
3170 3170
3171 3171
3172//! Adds a new material renderer to the VideoDriver, using pixel and/or 3172//! Adds a new material renderer to the VideoDriver, using pixel and/or
3173//! vertex shaders to render geometry. 3173//! vertex shaders to render geometry.
3174s32 CD3D9Driver::addShaderMaterial(const c8* vertexShaderProgram, 3174s32 CD3D9Driver::addShaderMaterial(const c8* vertexShaderProgram,
3175 const c8* pixelShaderProgram, 3175 const c8* pixelShaderProgram,
3176 IShaderConstantSetCallBack* callback, 3176 IShaderConstantSetCallBack* callback,
3177 E_MATERIAL_TYPE baseMaterial, s32 userData) 3177 E_MATERIAL_TYPE baseMaterial, s32 userData)
3178{ 3178{
3179 s32 nr = -1; 3179 s32 nr = -1;
3180 CD3D9ShaderMaterialRenderer* r = new CD3D9ShaderMaterialRenderer( 3180 CD3D9ShaderMaterialRenderer* r = new CD3D9ShaderMaterialRenderer(
3181 pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, 3181 pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram,
3182 callback, getMaterialRenderer(baseMaterial), userData); 3182 callback, getMaterialRenderer(baseMaterial), userData);
3183 3183
3184 r->drop(); 3184 r->drop();
3185 return nr; 3185 return nr;
3186} 3186}
3187 3187
3188 3188
3189//! Adds a new material renderer to the VideoDriver, based on a high level shading 3189//! Adds a new material renderer to the VideoDriver, based on a high level shading
3190//! language. 3190//! language.
3191s32 CD3D9Driver::addHighLevelShaderMaterial( 3191s32 CD3D9Driver::addHighLevelShaderMaterial(
3192 const c8* vertexShaderProgram, 3192 const c8* vertexShaderProgram,
3193 const c8* vertexShaderEntryPointName, 3193 const c8* vertexShaderEntryPointName,
3194 E_VERTEX_SHADER_TYPE vsCompileTarget, 3194 E_VERTEX_SHADER_TYPE vsCompileTarget,
3195 const c8* pixelShaderProgram, 3195 const c8* pixelShaderProgram,
3196 const c8* pixelShaderEntryPointName, 3196 const c8* pixelShaderEntryPointName,
3197 E_PIXEL_SHADER_TYPE psCompileTarget, 3197 E_PIXEL_SHADER_TYPE psCompileTarget,
3198 const c8* geometryShaderProgram, 3198 const c8* geometryShaderProgram,
3199 const c8* geometryShaderEntryPointName, 3199 const c8* geometryShaderEntryPointName,
3200 E_GEOMETRY_SHADER_TYPE gsCompileTarget, 3200 E_GEOMETRY_SHADER_TYPE gsCompileTarget,
3201 scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType, 3201 scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE outType,
3202 u32 verticesOut, 3202 u32 verticesOut,
3203 IShaderConstantSetCallBack* callback, 3203 IShaderConstantSetCallBack* callback,
3204 E_MATERIAL_TYPE baseMaterial, s32 userData, E_GPU_SHADING_LANGUAGE shadingLang) 3204 E_MATERIAL_TYPE baseMaterial, s32 userData, E_GPU_SHADING_LANGUAGE shadingLang)
3205{ 3205{
3206 s32 nr = -1; 3206 s32 nr = -1;
3207 3207
3208 #ifdef _IRR_COMPILE_WITH_CG_ 3208 #ifdef _IRR_COMPILE_WITH_CG_
3209 if(shadingLang == EGSL_CG) 3209 if(shadingLang == EGSL_CG)
3210 { 3210 {
3211 CD3D9CgMaterialRenderer* r = new CD3D9CgMaterialRenderer( 3211 CD3D9CgMaterialRenderer* r = new CD3D9CgMaterialRenderer(
3212 this, nr, 3212 this, nr,
3213 vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget, 3213 vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,
3214 pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget, 3214 pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,
3215 geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget, 3215 geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,
3216 inType, outType, verticesOut, 3216 inType, outType, verticesOut,
3217 callback,getMaterialRenderer(baseMaterial), userData); 3217 callback,getMaterialRenderer(baseMaterial), userData);
3218 3218
3219 r->drop(); 3219 r->drop();
3220 } 3220 }
3221 else 3221 else
3222 #endif 3222 #endif
3223 { 3223 {
3224 CD3D9HLSLMaterialRenderer* r = new CD3D9HLSLMaterialRenderer( 3224 CD3D9HLSLMaterialRenderer* r = new CD3D9HLSLMaterialRenderer(
3225 pID3DDevice, this, nr, 3225 pID3DDevice, this, nr,
3226 vertexShaderProgram, 3226 vertexShaderProgram,
3227 vertexShaderEntryPointName, 3227 vertexShaderEntryPointName,
3228 vsCompileTarget, 3228 vsCompileTarget,
3229 pixelShaderProgram, 3229 pixelShaderProgram,
3230 pixelShaderEntryPointName, 3230 pixelShaderEntryPointName,
3231 psCompileTarget, 3231 psCompileTarget,
3232 callback, 3232 callback,
3233 getMaterialRenderer(baseMaterial), 3233 getMaterialRenderer(baseMaterial),
3234 userData); 3234 userData);
3235 3235
3236 r->drop(); 3236 r->drop();
3237 } 3237 }
3238 3238
3239 return nr; 3239 return nr;
3240} 3240}
3241 3241
3242 3242
3243//! Returns a pointer to the IVideoDriver interface. (Implementation for 3243//! Returns a pointer to the IVideoDriver interface. (Implementation for
3244//! IMaterialRendererServices) 3244//! IMaterialRendererServices)
3245IVideoDriver* CD3D9Driver::getVideoDriver() 3245IVideoDriver* CD3D9Driver::getVideoDriver()
3246{ 3246{
3247 return this; 3247 return this;
3248} 3248}
3249 3249
3250 3250
3251//! Creates a render target texture. 3251//! Creates a render target texture.
3252ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d<u32>& size, 3252ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d<u32>& size,
3253 const io::path& name, 3253 const io::path& name,
3254 const ECOLOR_FORMAT format) 3254 const ECOLOR_FORMAT format)
3255{ 3255{
3256 CD3D9Texture* tex = new CD3D9Texture(this, size, name, format); 3256 CD3D9Texture* tex = new CD3D9Texture(this, size, name, format);
3257 if (tex) 3257 if (tex)
3258 { 3258 {
3259 if (!tex->Texture) 3259 if (!tex->Texture)
3260 { 3260 {
3261 tex->drop(); 3261 tex->drop();
3262 return 0; 3262 return 0;
3263 } 3263 }
3264 checkDepthBuffer(tex); 3264 checkDepthBuffer(tex);
3265 addTexture(tex); 3265 addTexture(tex);
3266 tex->drop(); 3266 tex->drop();
3267 } 3267 }
3268 return tex; 3268 return tex;
3269} 3269}
3270 3270
3271 3271
3272//! Clears the ZBuffer. 3272//! Clears the ZBuffer.
3273void CD3D9Driver::clearZBuffer() 3273void CD3D9Driver::clearZBuffer()
3274{ 3274{
3275 HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); 3275 HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0);
3276 3276
3277 if (FAILED(hr)) 3277 if (FAILED(hr))
3278 os::Printer::log("CD3D9Driver clearZBuffer() failed.", ELL_WARNING); 3278 os::Printer::log("CD3D9Driver clearZBuffer() failed.", ELL_WARNING);
3279} 3279}
3280 3280
3281 3281
3282//! Returns an image created from the last rendered frame. 3282//! Returns an image created from the last rendered frame.
3283IImage* CD3D9Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) 3283IImage* CD3D9Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
3284{ 3284{
3285 if (target != video::ERT_FRAME_BUFFER) 3285 if (target != video::ERT_FRAME_BUFFER)
3286 return 0; 3286 return 0;
3287 3287
3288 // query the screen dimensions of the current adapter 3288 // query the screen dimensions of the current adapter
3289 D3DDISPLAYMODE displayMode; 3289 D3DDISPLAYMODE displayMode;
3290 pID3DDevice->GetDisplayMode(0, &displayMode); 3290 pID3DDevice->GetDisplayMode(0, &displayMode);
3291 3291
3292 if (format==video::ECF_UNKNOWN) 3292 if (format==video::ECF_UNKNOWN)
3293 format=video::ECF_A8R8G8B8; 3293 format=video::ECF_A8R8G8B8;
3294 3294
3295 // create the image surface to store the front buffer image [always A8R8G8B8] 3295 // create the image surface to store the front buffer image [always A8R8G8B8]
3296 HRESULT hr; 3296 HRESULT hr;
3297 LPDIRECT3DSURFACE9 lpSurface; 3297 LPDIRECT3DSURFACE9 lpSurface;
3298 if (FAILED(hr = pID3DDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &lpSurface, 0))) 3298 if (FAILED(hr = pID3DDevice->CreateOffscreenPlainSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &lpSurface, 0)))
3299 return 0; 3299 return 0;
3300 3300
3301 // read the front buffer into the image surface 3301 // read the front buffer into the image surface
3302 if (FAILED(hr = pID3DDevice->GetFrontBufferData(0, lpSurface))) 3302 if (FAILED(hr = pID3DDevice->GetFrontBufferData(0, lpSurface)))
3303 { 3303 {
3304 lpSurface->Release(); 3304 lpSurface->Release();
3305 return 0; 3305 return 0;
3306 } 3306 }
3307 3307
3308 RECT clientRect; 3308 RECT clientRect;
3309 { 3309 {
3310 POINT clientPoint; 3310 POINT clientPoint;
3311 clientPoint.x = 0; 3311 clientPoint.x = 0;
3312 clientPoint.y = 0; 3312 clientPoint.y = 0;
3313 3313
3314 ClientToScreen((HWND)getExposedVideoData().D3D9.HWnd, &clientPoint); 3314 ClientToScreen((HWND)getExposedVideoData().D3D9.HWnd, &clientPoint);
3315 3315
3316 clientRect.left = clientPoint.x; 3316 clientRect.left = clientPoint.x;
3317 clientRect.top = clientPoint.y; 3317 clientRect.top = clientPoint.y;
3318 clientRect.right = clientRect.left + ScreenSize.Width; 3318 clientRect.right = clientRect.left + ScreenSize.Width;
3319 clientRect.bottom = clientRect.top + ScreenSize.Height; 3319 clientRect.bottom = clientRect.top + ScreenSize.Height;
3320 3320
3321 // window can be off-screen partly, we can't take screenshots from that 3321 // window can be off-screen partly, we can't take screenshots from that
3322 clientRect.left = core::max_(clientRect.left, 0l); 3322 clientRect.left = core::max_(clientRect.left, 0l);
3323 clientRect.top = core::max_(clientRect.top, 0l); 3323 clientRect.top = core::max_(clientRect.top, 0l);
3324 clientRect.right = core::min_(clientRect.right, (long)displayMode.Width); 3324 clientRect.right = core::min_(clientRect.right, (long)displayMode.Width);
3325 clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height ); 3325 clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height );
3326 } 3326 }
3327 3327
3328 // lock our area of the surface 3328 // lock our area of the surface
3329 D3DLOCKED_RECT lockedRect; 3329 D3DLOCKED_RECT lockedRect;
3330 if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) 3330 if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY)))
3331 { 3331 {
3332 lpSurface->Release(); 3332 lpSurface->Release();
3333 return 0; 3333 return 0;
3334 } 3334 }
3335 3335
3336 irr::core::dimension2d<u32> shotSize; 3336 irr::core::dimension2d<u32> shotSize;
3337 shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) ); 3337 shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) );
3338 shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) ); 3338 shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) );
3339 3339
3340 // this could throw, but we aren't going to worry about that case very much 3340 // this could throw, but we aren't going to worry about that case very much
3341 IImage* newImage = createImage(format, shotSize); 3341 IImage* newImage = createImage(format, shotSize);
3342 3342
3343 if (newImage) 3343 if (newImage)
3344 { 3344 {
3345 // d3d pads the image, so we need to copy the correct number of bytes 3345 // d3d pads the image, so we need to copy the correct number of bytes
3346 u32* dP = (u32*)newImage->lock(); 3346 u32* dP = (u32*)newImage->lock();
3347 u8 * sP = (u8 *)lockedRect.pBits; 3347 u8 * sP = (u8 *)lockedRect.pBits;
3348 3348
3349 // If the display mode format doesn't promise anything about the Alpha value 3349 // If the display mode format doesn't promise anything about the Alpha value
3350 // and it appears that it's not presenting 255, then we should manually 3350 // and it appears that it's not presenting 255, then we should manually
3351 // set each pixel alpha value to 255. 3351 // set each pixel alpha value to 255.
3352 if (D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000))) 3352 if (D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000)))
3353 { 3353 {
3354 for (u32 y = 0; y < shotSize.Height; ++y) 3354 for (u32 y = 0; y < shotSize.Height; ++y)
3355 { 3355 {
3356 for (u32 x = 0; x < shotSize.Width; ++x) 3356 for (u32 x = 0; x < shotSize.Width; ++x)
3357 { 3357 {
3358 newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000); 3358 newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000);
3359 sP += 4; 3359 sP += 4;
3360 } 3360 }
3361 3361
3362 sP += lockedRect.Pitch - (4 * shotSize.Width); 3362 sP += lockedRect.Pitch - (4 * shotSize.Width);
3363 } 3363 }
3364 } 3364 }
3365 else 3365 else
3366 { 3366 {
3367 for (u32 y = 0; y < shotSize.Height; ++y) 3367 for (u32 y = 0; y < shotSize.Height; ++y)
3368 { 3368 {
3369 convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format); 3369 convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format);
3370 sP += lockedRect.Pitch; 3370 sP += lockedRect.Pitch;
3371 dP += shotSize.Width; 3371 dP += shotSize.Width;
3372 } 3372 }
3373 } 3373 }
3374 3374
3375 newImage->unlock(); 3375 newImage->unlock();
3376 } 3376 }
3377 3377
3378 // we can unlock and release the surface 3378 // we can unlock and release the surface
3379 lpSurface->UnlockRect(); 3379 lpSurface->UnlockRect();
3380 3380
3381 // release the image surface 3381 // release the image surface
3382 lpSurface->Release(); 3382 lpSurface->Release();
3383 3383
3384 // return status of save operation to caller 3384 // return status of save operation to caller
3385 return newImage; 3385 return newImage;
3386} 3386}
3387 3387
3388 3388
3389//! returns color format 3389//! returns color format
3390ECOLOR_FORMAT CD3D9Driver::getColorFormat() const 3390ECOLOR_FORMAT CD3D9Driver::getColorFormat() const
3391{ 3391{
3392 return ColorFormat; 3392 return ColorFormat;
3393} 3393}
3394 3394
3395 3395
3396//! returns color format 3396//! returns color format
3397D3DFORMAT CD3D9Driver::getD3DColorFormat() const 3397D3DFORMAT CD3D9Driver::getD3DColorFormat() const
3398{ 3398{
3399 return D3DColorFormat; 3399 return D3DColorFormat;
3400} 3400}
3401 3401
3402 3402
3403// returns the current size of the screen or rendertarget 3403// returns the current size of the screen or rendertarget
3404const core::dimension2d<u32>& CD3D9Driver::getCurrentRenderTargetSize() const 3404const core::dimension2d<u32>& CD3D9Driver::getCurrentRenderTargetSize() const
3405{ 3405{
3406 if ( CurrentRendertargetSize.Width == 0 ) 3406 if ( CurrentRendertargetSize.Width == 0 )
3407 return ScreenSize; 3407 return ScreenSize;
3408 else 3408 else
3409 return CurrentRendertargetSize; 3409 return CurrentRendertargetSize;
3410} 3410}
3411 3411
3412 3412
3413// Set/unset a clipping plane. 3413// Set/unset a clipping plane.
3414bool CD3D9Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) 3414bool CD3D9Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable)
3415{ 3415{
3416 if (index >= MaxUserClipPlanes) 3416 if (index >= MaxUserClipPlanes)
3417 return false; 3417 return false;
3418 3418
3419 HRESULT ok = pID3DDevice->SetClipPlane(index, (const float*)&(plane.Normal.X)); 3419 HRESULT ok = pID3DDevice->SetClipPlane(index, (const float*)&(plane.Normal.X));
3420 if (D3D_OK == ok) 3420 if (D3D_OK == ok)
3421 enableClipPlane(index, enable); 3421 enableClipPlane(index, enable);
3422 return true; 3422 return true;
3423} 3423}
3424 3424
3425 3425
3426// Enable/disable a clipping plane. 3426// Enable/disable a clipping plane.
3427void CD3D9Driver::enableClipPlane(u32 index, bool enable) 3427void CD3D9Driver::enableClipPlane(u32 index, bool enable)
3428{ 3428{
3429 if (index >= MaxUserClipPlanes) 3429 if (index >= MaxUserClipPlanes)
3430 return; 3430 return;
3431 DWORD renderstate; 3431 DWORD renderstate;
3432 HRESULT ok = pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); 3432 HRESULT ok = pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate);
3433 if (S_OK == ok) 3433 if (S_OK == ok)
3434 { 3434 {
3435 if (enable) 3435 if (enable)
3436 renderstate |= (1 << index); 3436 renderstate |= (1 << index);
3437 else 3437 else
3438 renderstate &= ~(1 << index); 3438 renderstate &= ~(1 << index);
3439 ok = pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); 3439 ok = pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate);
3440 } 3440 }
3441} 3441}
3442 3442
3443 3443
3444D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const 3444D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const
3445{ 3445{
3446 switch(format) 3446 switch(format)
3447 { 3447 {
3448 case ECF_A1R5G5B5: 3448 case ECF_A1R5G5B5:
3449 return D3DFMT_A1R5G5B5; 3449 return D3DFMT_A1R5G5B5;
3450 case ECF_R5G6B5: 3450 case ECF_R5G6B5:
3451 return D3DFMT_R5G6B5; 3451 return D3DFMT_R5G6B5;
3452 case ECF_R8G8B8: 3452 case ECF_R8G8B8:
3453 return D3DFMT_R8G8B8; 3453 return D3DFMT_R8G8B8;
3454 case ECF_A8R8G8B8: 3454 case ECF_A8R8G8B8:
3455 return D3DFMT_A8R8G8B8; 3455 return D3DFMT_A8R8G8B8;
3456 3456
3457 // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski. 3457 // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski.
3458 case ECF_R16F: 3458 case ECF_R16F:
3459 return D3DFMT_R16F; 3459 return D3DFMT_R16F;
3460 case ECF_G16R16F: 3460 case ECF_G16R16F:
3461 return D3DFMT_G16R16F; 3461 return D3DFMT_G16R16F;
3462 case ECF_A16B16G16R16F: 3462 case ECF_A16B16G16R16F:
3463 return D3DFMT_A16B16G16R16F; 3463 return D3DFMT_A16B16G16R16F;
3464 case ECF_R32F: 3464 case ECF_R32F:
3465 return D3DFMT_R32F; 3465 return D3DFMT_R32F;
3466 case ECF_G32R32F: 3466 case ECF_G32R32F:
3467 return D3DFMT_G32R32F; 3467 return D3DFMT_G32R32F;
3468 case ECF_A32B32G32R32F: 3468 case ECF_A32B32G32R32F:
3469 return D3DFMT_A32B32G32R32F; 3469 return D3DFMT_A32B32G32R32F;
3470 } 3470 }
3471 return D3DFMT_UNKNOWN; 3471 return D3DFMT_UNKNOWN;
3472} 3472}
3473 3473
3474 3474
3475ECOLOR_FORMAT CD3D9Driver::getColorFormatFromD3DFormat(D3DFORMAT format) const 3475ECOLOR_FORMAT CD3D9Driver::getColorFormatFromD3DFormat(D3DFORMAT format) const
3476{ 3476{
3477 switch(format) 3477 switch(format)
3478 { 3478 {
3479 case D3DFMT_X1R5G5B5: 3479 case D3DFMT_X1R5G5B5:
3480 case D3DFMT_A1R5G5B5: 3480 case D3DFMT_A1R5G5B5:
3481 return ECF_A1R5G5B5; 3481 return ECF_A1R5G5B5;
3482 case D3DFMT_A8B8G8R8: 3482 case D3DFMT_A8B8G8R8:
3483 case D3DFMT_A8R8G8B8: 3483 case D3DFMT_A8R8G8B8:
3484 case D3DFMT_X8R8G8B8: 3484 case D3DFMT_X8R8G8B8:
3485 return ECF_A8R8G8B8; 3485 return ECF_A8R8G8B8;
3486 case D3DFMT_R5G6B5: 3486 case D3DFMT_R5G6B5:
3487 return ECF_R5G6B5; 3487 return ECF_R5G6B5;
3488 case D3DFMT_R8G8B8: 3488 case D3DFMT_R8G8B8:
3489 return ECF_R8G8B8; 3489 return ECF_R8G8B8;
3490 3490
3491 // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski. 3491 // Floating Point formats. Thanks to Patryk "Nadro" Nadrowski.
3492 case D3DFMT_R16F: 3492 case D3DFMT_R16F:
3493 return ECF_R16F; 3493 return ECF_R16F;
3494 case D3DFMT_G16R16F: 3494 case D3DFMT_G16R16F:
3495 return ECF_G16R16F; 3495 return ECF_G16R16F;
3496 case D3DFMT_A16B16G16R16F: 3496 case D3DFMT_A16B16G16R16F:
3497 return ECF_A16B16G16R16F; 3497 return ECF_A16B16G16R16F;
3498 case D3DFMT_R32F: 3498 case D3DFMT_R32F:
3499 return ECF_R32F; 3499 return ECF_R32F;
3500 case D3DFMT_G32R32F: 3500 case D3DFMT_G32R32F:
3501 return ECF_G32R32F; 3501 return ECF_G32R32F;
3502 case D3DFMT_A32B32G32R32F: 3502 case D3DFMT_A32B32G32R32F:
3503 return ECF_A32B32G32R32F; 3503 return ECF_A32B32G32R32F;
3504 default: 3504 default:
3505 return (ECOLOR_FORMAT)0; 3505 return (ECOLOR_FORMAT)0;
3506 }; 3506 };
3507} 3507}
3508 3508
3509 3509
3510void CD3D9Driver::checkDepthBuffer(ITexture* tex) 3510void CD3D9Driver::checkDepthBuffer(ITexture* tex)
3511{ 3511{
3512 if (!tex) 3512 if (!tex)
3513 return; 3513 return;
3514 const core::dimension2du optSize = tex->getSize().getOptimalSize( 3514 const core::dimension2du optSize = tex->getSize().getOptimalSize(
3515 !queryFeature(EVDF_TEXTURE_NPOT), 3515 !queryFeature(EVDF_TEXTURE_NPOT),
3516 !queryFeature(EVDF_TEXTURE_NSQUARE), true); 3516 !queryFeature(EVDF_TEXTURE_NSQUARE), true);
3517 SDepthSurface* depth=0; 3517 SDepthSurface* depth=0;
3518 core::dimension2du destSize(0x7fffffff, 0x7fffffff); 3518 core::dimension2du destSize(0x7fffffff, 0x7fffffff);
3519 for (u32 i=0; i<DepthBuffers.size(); ++i) 3519 for (u32 i=0; i<DepthBuffers.size(); ++i)
3520 { 3520 {
3521 if ((DepthBuffers[i]->Size.Width>=optSize.Width) && 3521 if ((DepthBuffers[i]->Size.Width>=optSize.Width) &&
3522 (DepthBuffers[i]->Size.Height>=optSize.Height)) 3522 (DepthBuffers[i]->Size.Height>=optSize.Height))
3523 { 3523 {
3524 if ((DepthBuffers[i]->Size.Width<destSize.Width) && 3524 if ((DepthBuffers[i]->Size.Width<destSize.Width) &&
3525 (DepthBuffers[i]->Size.Height<destSize.Height)) 3525 (DepthBuffers[i]->Size.Height<destSize.Height))
3526 { 3526 {
3527 depth = DepthBuffers[i]; 3527 depth = DepthBuffers[i];
3528 destSize=DepthBuffers[i]->Size; 3528 destSize=DepthBuffers[i]->Size;
3529 } 3529 }
3530 } 3530 }
3531 } 3531 }
3532 if (!depth) 3532 if (!depth)
3533 { 3533 {
3534 D3DSURFACE_DESC desc; 3534 D3DSURFACE_DESC desc;
3535 DepthBuffers[0]->Surface->GetDesc(&desc); 3535 DepthBuffers[0]->Surface->GetDesc(&desc);
3536 // the multisampling needs to match the RTT 3536 // the multisampling needs to match the RTT
3537 D3DSURFACE_DESC desc2; 3537 D3DSURFACE_DESC desc2;
3538 ((CD3D9Texture*)tex)->Texture->GetLevelDesc(0,&desc2); 3538 ((CD3D9Texture*)tex)->Texture->GetLevelDesc(0,&desc2);
3539 DepthBuffers.push_back(new SDepthSurface()); 3539 DepthBuffers.push_back(new SDepthSurface());
3540 HRESULT hr=pID3DDevice->CreateDepthStencilSurface(optSize.Width, 3540 HRESULT hr=pID3DDevice->CreateDepthStencilSurface(optSize.Width,
3541 optSize.Height, 3541 optSize.Height,
3542 desc.Format, 3542 desc.Format,
3543 desc2.MultiSampleType, 3543 desc2.MultiSampleType,
3544 desc2.MultiSampleQuality, 3544 desc2.MultiSampleQuality,
3545 TRUE, 3545 TRUE,
3546 &(DepthBuffers.getLast()->Surface), 3546 &(DepthBuffers.getLast()->Surface),
3547 NULL); 3547 NULL);
3548 if (SUCCEEDED(hr)) 3548 if (SUCCEEDED(hr))
3549 { 3549 {
3550 depth=DepthBuffers.getLast(); 3550 depth=DepthBuffers.getLast();
3551 depth->Surface->GetDesc(&desc); 3551 depth->Surface->GetDesc(&desc);
3552 depth->Size.set(desc.Width, desc.Height); 3552 depth->Size.set(desc.Width, desc.Height);
3553 } 3553 }
3554 else 3554 else
3555 { 3555 {
3556 if (hr == D3DERR_OUTOFVIDEOMEMORY) 3556 if (hr == D3DERR_OUTOFVIDEOMEMORY)
3557 os::Printer::log("Could not create DepthBuffer","out of video memory",ELL_ERROR); 3557 os::Printer::log("Could not create DepthBuffer","out of video memory",ELL_ERROR);
3558 else if( hr == E_OUTOFMEMORY ) 3558 else if( hr == E_OUTOFMEMORY )
3559 os::Printer::log("Could not create DepthBuffer","out of memory",ELL_ERROR); 3559 os::Printer::log("Could not create DepthBuffer","out of memory",ELL_ERROR);
3560 else 3560 else
3561 { 3561 {
3562 char buffer[128]; 3562 char buffer[128];
3563 sprintf(buffer,"Could not create DepthBuffer of %ix%i",optSize.Width,optSize.Height); 3563 sprintf(buffer,"Could not create DepthBuffer of %ix%i",optSize.Width,optSize.Height);
3564 os::Printer::log(buffer,ELL_ERROR); 3564 os::Printer::log(buffer,ELL_ERROR);
3565 } 3565 }
3566 DepthBuffers.erase(DepthBuffers.size()-1); 3566 DepthBuffers.erase(DepthBuffers.size()-1);
3567 } 3567 }
3568 } 3568 }
3569 else 3569 else
3570 depth->grab(); 3570 depth->grab();
3571 3571
3572 static_cast<CD3D9Texture*>(tex)->DepthSurface=depth; 3572 static_cast<CD3D9Texture*>(tex)->DepthSurface=depth;
3573} 3573}
3574 3574
3575 3575
3576void CD3D9Driver::removeDepthSurface(SDepthSurface* depth) 3576void CD3D9Driver::removeDepthSurface(SDepthSurface* depth)
3577{ 3577{
3578 for (u32 i=0; i<DepthBuffers.size(); ++i) 3578 for (u32 i=0; i<DepthBuffers.size(); ++i)
3579 { 3579 {
3580 if (DepthBuffers[i]==depth) 3580 if (DepthBuffers[i]==depth)
3581 { 3581 {
3582 DepthBuffers.erase(i); 3582 DepthBuffers.erase(i);
3583 return; 3583 return;
3584 } 3584 }
3585 } 3585 }
3586} 3586}
3587 3587
3588 3588
3589core::dimension2du CD3D9Driver::getMaxTextureSize() const 3589core::dimension2du CD3D9Driver::getMaxTextureSize() const
3590{ 3590{
3591 return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight); 3591 return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight);
3592} 3592}
3593 3593
3594#ifdef _IRR_COMPILE_WITH_CG_ 3594#ifdef _IRR_COMPILE_WITH_CG_
3595const CGcontext& CD3D9Driver::getCgContext() 3595const CGcontext& CD3D9Driver::getCgContext()
3596{ 3596{
3597 return CgContext; 3597 return CgContext;
3598} 3598}
3599#endif 3599#endif
3600 3600
3601 3601
3602} // end namespace video 3602} // end namespace video
3603} // end namespace irr 3603} // end namespace irr
3604 3604
3605#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ 3605#endif // _IRR_COMPILE_WITH_DIRECT3D_9_
3606 3606
3607 3607
3608 3608
3609namespace irr 3609namespace irr
3610{ 3610{
3611namespace video 3611namespace video
3612{ 3612{
3613 3613
3614#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ 3614#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
3615//! creates a video driver 3615//! creates a video driver
3616IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params, 3616IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params,
3617 io::IFileSystem* io, HWND window) 3617 io::IFileSystem* io, HWND window)
3618{ 3618{
3619 const bool pureSoftware = false; 3619 const bool pureSoftware = false;
3620 CD3D9Driver* dx9 = new CD3D9Driver(params, io); 3620 CD3D9Driver* dx9 = new CD3D9Driver(params, io);
3621 if (!dx9->initDriver(window, pureSoftware)) 3621 if (!dx9->initDriver(window, pureSoftware))
3622 { 3622 {
3623 dx9->drop(); 3623 dx9->drop();
3624 dx9 = 0; 3624 dx9 = 0;
3625 } 3625 }
3626 3626
3627 return dx9; 3627 return dx9;
3628} 3628}
3629#endif // _IRR_COMPILE_WITH_DIRECT3D_9_ 3629#endif // _IRR_COMPILE_WITH_DIRECT3D_9_
3630 3630
3631} // end namespace video 3631} // end namespace video
3632} // end namespace irr 3632} // end namespace irr
3633 3633