diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CD3D9Driver.cpp | 7266 |
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 | ||
21 | namespace irr | 21 | namespace irr |
22 | { | 22 | { |
23 | namespace video | 23 | namespace video |
24 | { | 24 | { |
25 | 25 | ||
26 | namespace | 26 | namespace |
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 |
32 | CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) | 32 | CD3D9Driver::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 |
79 | CD3D9Driver::~CD3D9Driver() | 79 | CD3D9Driver::~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 | ||
110 | void CD3D9Driver::createMaterialRenderers() | 110 | void 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 |
177 | bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware) | 177 | bool 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. |
512 | bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, | 512 | bool 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. |
570 | bool CD3D9Driver::endScene() | 570 | bool 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 |
624 | bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const | 624 | bool 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 |
696 | void CD3D9Driver::setTransform(E_TRANSFORMATION_STATE state, | 696 | void 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 |
734 | bool CD3D9Driver::setActiveTexture(u32 stage, const video::ITexture* texture) | 734 | bool 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 |
761 | void CD3D9Driver::setMaterial(const SMaterial& material) | 761 | void 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) |
776 | video::ITexture* CD3D9Driver::createDeviceDependentTexture(IImage* surface,const io::path& name, void* mipmapData) | 776 | video::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. |
783 | void CD3D9Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, | 783 | void 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 |
794 | bool CD3D9Driver::setRenderTarget(video::ITexture* texture, | 794 | bool 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 |
892 | bool CD3D9Driver::setRenderTarget(const core::array<video::IRenderTarget>& targets, | 892 | bool 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 |
1012 | void CD3D9Driver::setViewPort(const core::rect<s32>& area) | 1012 | void 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 |
1037 | const core::rect<s32>& CD3D9Driver::getViewPort() const | 1037 | const core::rect<s32>& CD3D9Driver::getViewPort() const |
1038 | { | 1038 | { |
1039 | return ViewPort; | 1039 | return ViewPort; |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | 1042 | ||
1043 | bool CD3D9Driver::updateVertexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) | 1043 | bool 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 | ||
1109 | bool CD3D9Driver::updateIndexHardwareBuffer(SHWBufferLink_d3d9 *hwBuffer) | 1109 | bool 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 |
1179 | bool CD3D9Driver::updateHardwareBuffer(SHWBufferLink *hwBuffer) | 1179 | bool 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 |
1213 | CD3D9Driver::SHWBufferLink *CD3D9Driver::createHardwareBuffer(const scene::IMeshBuffer* mb) | 1213 | CD3D9Driver::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 | ||
1245 | void CD3D9Driver::deleteHardwareBuffer(SHWBufferLink *_HWBuffer) | 1245 | void 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 |
1268 | void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer) | 1268 | void 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. */ |
1306 | void CD3D9Driver::addOcclusionQuery(scene::ISceneNode* node, | 1306 | void 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. |
1319 | void CD3D9Driver::removeOcclusionQuery(scene::ISceneNode* node) | 1319 | void 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 |
1333 | overrideMaterial to disable the color and depth buffer. */ | 1333 | overrideMaterial to disable the color and depth buffer. */ |
1334 | void CD3D9Driver::runOcclusionQuery(scene::ISceneNode* node, bool visible) | 1334 | void 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. |
1353 | Update might not occur in this case, though */ | 1353 | Update might not occur in this case, though */ |
1354 | void CD3D9Driver::updateOcclusionQuery(scene::ISceneNode* node, bool block) | 1354 | void 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. |
1384 | The value is a safe approximation, i.e. can be larger than the | 1384 | The value is a safe approximation, i.e. can be larger than the |
1385 | actual value of pixels. */ | 1385 | actual value of pixels. */ |
1386 | u32 CD3D9Driver::getOcclusionQueryResult(scene::ISceneNode* node) const | 1386 | u32 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 |
1397 | void CD3D9Driver::drawVertexPrimitiveList(const void* vertices, | 1397 | void 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 |
1416 | void CD3D9Driver::draw2DVertexPrimitiveList(const void* vertices, | 1416 | void 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 | ||
1434 | void CD3D9Driver::draw2D3DVertexPrimitiveList(const void* vertices, | 1434 | void 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 | ||
1574 | void CD3D9Driver::draw2DImage(const video::ITexture* texture, | 1574 | void 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 | ||
1646 | void CD3D9Driver::draw2DImageBatch(const video::ITexture* texture, | 1646 | void 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). |
1794 | void CD3D9Driver::draw2DImage(const video::ITexture* texture, | 1794 | void 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. |
1926 | void CD3D9Driver::draw2DRectangle(const core::rect<s32>& position, | 1926 | void 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. |
1966 | void CD3D9Driver::draw2DLine(const core::position2d<s32>& start, | 1966 | void 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 |
1996 | void CD3D9Driver::drawPixel(u32 x, u32 y, const SColor & color) | 1996 | void 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 |
2014 | void CD3D9Driver::setVertexShader(E_VERTEX_TYPE newType) | 2014 | void 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 |
2048 | bool CD3D9Driver::setRenderStates3DMode() | 2048 | bool 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 |
2097 | D3DTEXTUREADDRESS CD3D9Driver::getTextureWrapMode(const u8 clamp) | 2097 | D3DTEXTUREADDRESS 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. |
2130 | void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, | 2130 | void 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 |
2447 | void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) | 2447 | void 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 |
2522 | void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha) | 2522 | void 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 |
2572 | void CD3D9Driver::enableMaterial2D(bool enable) | 2572 | void 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 |
2581 | void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) | 2581 | void 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 |
2687 | void CD3D9Driver::deleteAllDynamicLights() | 2687 | void 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 |
2699 | s32 CD3D9Driver::addDynamicLight(const SLight& dl) | 2699 | s32 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 |
2750 | void CD3D9Driver::turnLightOn(s32 lightIndex, bool turnOn) | 2750 | void 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 |
2760 | u32 CD3D9Driver::getMaximalDynamicLightAmount() const | 2760 | u32 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. |
2769 | void CD3D9Driver::setAmbientLight(const SColorf& color) | 2769 | void 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". |
2782 | const wchar_t* CD3D9Driver::getName() const | 2782 | const 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. |
2791 | void CD3D9Driver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) | 2791 | void 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. |
2836 | void CD3D9Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, | 2836 | void 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. |
2871 | u32 CD3D9Driver::getMaximalPrimitiveCount() const | 2871 | u32 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. |
2878 | void CD3D9Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, | 2878 | void 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. |
2906 | void CD3D9Driver::draw3DLine(const core::vector3df& start, | 2906 | void 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 |
2922 | bool CD3D9Driver::reset() | 2922 | bool 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 | ||
3051 | void CD3D9Driver::OnResize(const core::dimension2d<u32>& size) | 3051 | void 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 |
3065 | E_DRIVER_TYPE CD3D9Driver::getDriverType() const | 3065 | E_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 |
3072 | const core::matrix4& CD3D9Driver::getTransform(E_TRANSFORMATION_STATE state) const | 3072 | const 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. |
3079 | void CD3D9Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) | 3079 | void 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. |
3087 | void CD3D9Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) | 3087 | void 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. |
3095 | bool CD3D9Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) | 3095 | bool 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. |
3108 | bool CD3D9Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) | 3108 | bool 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. |
3121 | bool CD3D9Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) | 3121 | bool 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. |
3134 | bool CD3D9Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) | 3134 | bool 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. |
3147 | bool CD3D9Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) | 3147 | bool 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. |
3160 | bool CD3D9Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) | 3160 | bool 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. |
3174 | s32 CD3D9Driver::addShaderMaterial(const c8* vertexShaderProgram, | 3174 | s32 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. |
3191 | s32 CD3D9Driver::addHighLevelShaderMaterial( | 3191 | s32 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) |
3245 | IVideoDriver* CD3D9Driver::getVideoDriver() | 3245 | IVideoDriver* 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. |
3252 | ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d<u32>& size, | 3252 | ITexture* 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. |
3273 | void CD3D9Driver::clearZBuffer() | 3273 | void 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. |
3283 | IImage* CD3D9Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) | 3283 | IImage* 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 |
3390 | ECOLOR_FORMAT CD3D9Driver::getColorFormat() const | 3390 | ECOLOR_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 |
3397 | D3DFORMAT CD3D9Driver::getD3DColorFormat() const | 3397 | D3DFORMAT 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 |
3404 | const core::dimension2d<u32>& CD3D9Driver::getCurrentRenderTargetSize() const | 3404 | const 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. |
3414 | bool CD3D9Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) | 3414 | bool 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. |
3427 | void CD3D9Driver::enableClipPlane(u32 index, bool enable) | 3427 | void 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 | ||
3444 | D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const | 3444 | D3DFORMAT 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 | ||
3475 | ECOLOR_FORMAT CD3D9Driver::getColorFormatFromD3DFormat(D3DFORMAT format) const | 3475 | ECOLOR_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 | ||
3510 | void CD3D9Driver::checkDepthBuffer(ITexture* tex) | 3510 | void 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 | ||
3576 | void CD3D9Driver::removeDepthSurface(SDepthSurface* depth) | 3576 | void 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 | ||
3589 | core::dimension2du CD3D9Driver::getMaxTextureSize() const | 3589 | core::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_ |
3595 | const CGcontext& CD3D9Driver::getCgContext() | 3595 | const 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 | ||
3609 | namespace irr | 3609 | namespace irr |
3610 | { | 3610 | { |
3611 | namespace video | 3611 | namespace 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 |
3616 | IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params, | 3616 | IVideoDriver* 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 | ||