diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/CD3D8Driver.cpp | 4910 |
1 files changed, 2455 insertions, 2455 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CD3D8Driver.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CD3D8Driver.cpp index 9886b37..34cbca3 100644 --- a/libraries/irrlicht-1.8/source/Irrlicht/CD3D8Driver.cpp +++ b/libraries/irrlicht-1.8/source/Irrlicht/CD3D8Driver.cpp | |||
@@ -1,2455 +1,2455 @@ | |||
1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt | 1 | // Copyright (C) 2002-2012 Nikolaus Gebhardt |
2 | // This file is part of the "Irrlicht Engine". | 2 | // This file is part of the "Irrlicht Engine". |
3 | // For conditions of distribution and use, see copyright notice in irrlicht.h | 3 | // For conditions of distribution and use, see copyright notice in irrlicht.h |
4 | 4 | ||
5 | #include "IrrCompileConfig.h" | 5 | #include "IrrCompileConfig.h" |
6 | 6 | ||
7 | #define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE | 7 | #define _IRR_DONT_DO_MEMORY_DEBUGGING_HERE |
8 | #include "CD3D8Driver.h" | 8 | #include "CD3D8Driver.h" |
9 | 9 | ||
10 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ | 10 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ |
11 | 11 | ||
12 | #include "os.h" | 12 | #include "os.h" |
13 | #include "S3DVertex.h" | 13 | #include "S3DVertex.h" |
14 | #include "CD3D8Texture.h" | 14 | #include "CD3D8Texture.h" |
15 | #include "CD3D8MaterialRenderer.h" | 15 | #include "CD3D8MaterialRenderer.h" |
16 | #include "CD3D8ShaderMaterialRenderer.h" | 16 | #include "CD3D8ShaderMaterialRenderer.h" |
17 | #include "CD3D8NormalMapRenderer.h" | 17 | #include "CD3D8NormalMapRenderer.h" |
18 | #include "CD3D8ParallaxMapRenderer.h" | 18 | #include "CD3D8ParallaxMapRenderer.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 | 26 | ||
27 | //! constructor | 27 | //! constructor |
28 | CD3D8Driver::CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) | 28 | CD3D8Driver::CD3D8Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io) |
29 | : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), | 29 | : CNullDriver(io, params.WindowSize), CurrentRenderMode(ERM_NONE), |
30 | ResetRenderStates(true), Transformation3DChanged(false), | 30 | ResetRenderStates(true), Transformation3DChanged(false), |
31 | D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), | 31 | D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0), |
32 | WindowId(0), SceneSourceRect(0), | 32 | WindowId(0), SceneSourceRect(0), |
33 | LastVertexType((video::E_VERTEX_TYPE)-1), | 33 | LastVertexType((video::E_VERTEX_TYPE)-1), |
34 | MaxTextureUnits(0), MaxUserClipPlanes(0), | 34 | MaxTextureUnits(0), MaxUserClipPlanes(0), |
35 | MaxLightDistance(0), LastSetLight(-1), DeviceLost(false), | 35 | MaxLightDistance(0), LastSetLight(-1), DeviceLost(false), |
36 | DriverWasReset(true), Params(params) | 36 | DriverWasReset(true), Params(params) |
37 | { | 37 | { |
38 | #ifdef _DEBUG | 38 | #ifdef _DEBUG |
39 | setDebugName("CD3D8Driver"); | 39 | setDebugName("CD3D8Driver"); |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | printVersion(); | 42 | printVersion(); |
43 | 43 | ||
44 | for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 44 | for (u32 i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
45 | CurrentTexture[i] = 0; | 45 | CurrentTexture[i] = 0; |
46 | MaxLightDistance=sqrtf(FLT_MAX); | 46 | MaxLightDistance=sqrtf(FLT_MAX); |
47 | // create sphere map matrix | 47 | // create sphere map matrix |
48 | 48 | ||
49 | SphereMapMatrixD3D8._11 = 0.5f; SphereMapMatrixD3D8._12 = 0.0f; | 49 | SphereMapMatrixD3D8._11 = 0.5f; SphereMapMatrixD3D8._12 = 0.0f; |
50 | SphereMapMatrixD3D8._13 = 0.0f; SphereMapMatrixD3D8._14 = 0.0f; | 50 | SphereMapMatrixD3D8._13 = 0.0f; SphereMapMatrixD3D8._14 = 0.0f; |
51 | SphereMapMatrixD3D8._21 = 0.0f; SphereMapMatrixD3D8._22 =-0.5f; | 51 | SphereMapMatrixD3D8._21 = 0.0f; SphereMapMatrixD3D8._22 =-0.5f; |
52 | SphereMapMatrixD3D8._23 = 0.0f; SphereMapMatrixD3D8._24 = 0.0f; | 52 | SphereMapMatrixD3D8._23 = 0.0f; SphereMapMatrixD3D8._24 = 0.0f; |
53 | SphereMapMatrixD3D8._31 = 0.0f; SphereMapMatrixD3D8._32 = 0.0f; | 53 | SphereMapMatrixD3D8._31 = 0.0f; SphereMapMatrixD3D8._32 = 0.0f; |
54 | SphereMapMatrixD3D8._33 = 1.0f; SphereMapMatrixD3D8._34 = 0.0f; | 54 | SphereMapMatrixD3D8._33 = 1.0f; SphereMapMatrixD3D8._34 = 0.0f; |
55 | SphereMapMatrixD3D8._41 = 0.5f; SphereMapMatrixD3D8._42 = 0.5f; | 55 | SphereMapMatrixD3D8._41 = 0.5f; SphereMapMatrixD3D8._42 = 0.5f; |
56 | SphereMapMatrixD3D8._43 = 0.0f; SphereMapMatrixD3D8._44 = 1.0f; | 56 | SphereMapMatrixD3D8._43 = 0.0f; SphereMapMatrixD3D8._44 = 1.0f; |
57 | 57 | ||
58 | UnitMatrixD3D8 = *(D3DMATRIX*)((void*)core::IdentityMatrix.pointer()); | 58 | UnitMatrixD3D8 = *(D3DMATRIX*)((void*)core::IdentityMatrix.pointer()); |
59 | 59 | ||
60 | // init direct 3d is done in the factory function | 60 | // init direct 3d is done in the factory function |
61 | } | 61 | } |
62 | 62 | ||
63 | 63 | ||
64 | //! destructor | 64 | //! destructor |
65 | CD3D8Driver::~CD3D8Driver() | 65 | CD3D8Driver::~CD3D8Driver() |
66 | { | 66 | { |
67 | deleteMaterialRenders(); | 67 | deleteMaterialRenders(); |
68 | 68 | ||
69 | // drop d3d8 | 69 | // drop d3d8 |
70 | 70 | ||
71 | if (pID3DDevice) | 71 | if (pID3DDevice) |
72 | pID3DDevice->Release(); | 72 | pID3DDevice->Release(); |
73 | 73 | ||
74 | if (pID3D) | 74 | if (pID3D) |
75 | pID3D->Release(); | 75 | pID3D->Release(); |
76 | } | 76 | } |
77 | 77 | ||
78 | 78 | ||
79 | void CD3D8Driver::createMaterialRenderers() | 79 | void CD3D8Driver::createMaterialRenderers() |
80 | { | 80 | { |
81 | // create D3D8 material renderers | 81 | // create D3D8 material renderers |
82 | 82 | ||
83 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID(pID3DDevice, this)); | 83 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID(pID3DDevice, this)); |
84 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); | 84 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SOLID_2_LAYER(pID3DDevice, this)); |
85 | 85 | ||
86 | // add the same renderer for all lightmap types | 86 | // add the same renderer for all lightmap types |
87 | CD3D8MaterialRenderer_LIGHTMAP* lmr = new CD3D8MaterialRenderer_LIGHTMAP(pID3DDevice, this); | 87 | CD3D8MaterialRenderer_LIGHTMAP* lmr = new CD3D8MaterialRenderer_LIGHTMAP(pID3DDevice, this); |
88 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP: | 88 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP: |
89 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: | 89 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_ADD: |
90 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: | 90 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M2: |
91 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: | 91 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_M4: |
92 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: | 92 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING: |
93 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: | 93 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M2: |
94 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: | 94 | addMaterialRenderer(lmr); // for EMT_LIGHTMAP_LIGHTING_M4: |
95 | lmr->drop(); | 95 | lmr->drop(); |
96 | 96 | ||
97 | // add remaining material renderers | 97 | // add remaining material renderers |
98 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); | 98 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_DETAIL_MAP(pID3DDevice, this)); |
99 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); | 99 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_SPHERE_MAP(pID3DDevice, this)); |
100 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); | 100 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_REFLECTION_2_LAYER(pID3DDevice, this)); |
101 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); | 101 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ADD_COLOR(pID3DDevice, this)); |
102 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); | 102 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL(pID3DDevice, this)); |
103 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); | 103 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL_REF(pID3DDevice, this)); |
104 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); | 104 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_VERTEX_ALPHA(pID3DDevice, this)); |
105 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); | 105 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_TRANSPARENT_REFLECTION_2_LAYER(pID3DDevice, this)); |
106 | 106 | ||
107 | // add normal map renderers | 107 | // add normal map renderers |
108 | s32 tmp = 0; | 108 | s32 tmp = 0; |
109 | video::IMaterialRenderer* renderer = 0; | 109 | video::IMaterialRenderer* renderer = 0; |
110 | 110 | ||
111 | renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, | 111 | renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, |
112 | MaterialRenderers[EMT_SOLID].Renderer); | 112 | MaterialRenderers[EMT_SOLID].Renderer); |
113 | renderer->drop(); | 113 | renderer->drop(); |
114 | 114 | ||
115 | renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, | 115 | renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, |
116 | MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); | 116 | MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); |
117 | renderer->drop(); | 117 | renderer->drop(); |
118 | 118 | ||
119 | renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, | 119 | renderer = new CD3D8NormalMapRenderer(pID3DDevice, this, tmp, |
120 | MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); | 120 | MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); |
121 | renderer->drop(); | 121 | renderer->drop(); |
122 | 122 | ||
123 | // add parallax map renderers | 123 | // add parallax map renderers |
124 | 124 | ||
125 | renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, | 125 | renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, |
126 | MaterialRenderers[EMT_SOLID].Renderer); | 126 | MaterialRenderers[EMT_SOLID].Renderer); |
127 | renderer->drop(); | 127 | renderer->drop(); |
128 | 128 | ||
129 | renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, | 129 | renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, |
130 | MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); | 130 | MaterialRenderers[EMT_TRANSPARENT_ADD_COLOR].Renderer); |
131 | renderer->drop(); | 131 | renderer->drop(); |
132 | 132 | ||
133 | renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, | 133 | renderer = new CD3D8ParallaxMapRenderer(pID3DDevice, this, tmp, |
134 | MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); | 134 | MaterialRenderers[EMT_TRANSPARENT_VERTEX_ALPHA].Renderer); |
135 | renderer->drop(); | 135 | renderer->drop(); |
136 | 136 | ||
137 | // add basic 1 texture blending | 137 | // add basic 1 texture blending |
138 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); | 138 | addAndDropMaterialRenderer(new CD3D8MaterialRenderer_ONETEXTURE_BLEND(pID3DDevice, this)); |
139 | } | 139 | } |
140 | 140 | ||
141 | 141 | ||
142 | //! initialises the Direct3D API | 142 | //! initialises the Direct3D API |
143 | bool CD3D8Driver::initDriver(HWND hwnd, bool pureSoftware) | 143 | bool CD3D8Driver::initDriver(HWND hwnd, bool pureSoftware) |
144 | { | 144 | { |
145 | HRESULT hr; | 145 | HRESULT hr; |
146 | typedef IDirect3D8 * (__stdcall *D3DCREATETYPE)(UINT); | 146 | typedef IDirect3D8 * (__stdcall *D3DCREATETYPE)(UINT); |
147 | 147 | ||
148 | #if defined( _IRR_XBOX_PLATFORM_) | 148 | #if defined( _IRR_XBOX_PLATFORM_) |
149 | D3DCREATETYPE d3dCreate = (D3DCREATETYPE) &Direct3DCreate8; | 149 | D3DCREATETYPE d3dCreate = (D3DCREATETYPE) &Direct3DCreate8; |
150 | #else | 150 | #else |
151 | D3DLibrary = LoadLibrary( __TEXT("d3d8.dll") ); | 151 | D3DLibrary = LoadLibrary( __TEXT("d3d8.dll") ); |
152 | 152 | ||
153 | if (!D3DLibrary) | 153 | if (!D3DLibrary) |
154 | { | 154 | { |
155 | os::Printer::log("Error, could not load d3d8.dll.", ELL_ERROR); | 155 | os::Printer::log("Error, could not load d3d8.dll.", ELL_ERROR); |
156 | return false; | 156 | return false; |
157 | } | 157 | } |
158 | 158 | ||
159 | D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate8"); | 159 | D3DCREATETYPE d3dCreate = (D3DCREATETYPE) GetProcAddress(D3DLibrary, "Direct3DCreate8"); |
160 | 160 | ||
161 | if (!d3dCreate) | 161 | if (!d3dCreate) |
162 | { | 162 | { |
163 | os::Printer::log("Error, could not get proc adress of Direct3DCreate8.", ELL_ERROR); | 163 | os::Printer::log("Error, could not get proc adress of Direct3DCreate8.", ELL_ERROR); |
164 | return false; | 164 | return false; |
165 | } | 165 | } |
166 | #endif | 166 | #endif |
167 | 167 | ||
168 | //just like pID3D = Direct3DCreate8(D3D_SDK_VERSION); | 168 | //just like pID3D = Direct3DCreate8(D3D_SDK_VERSION); |
169 | pID3D = (*d3dCreate)(D3D_SDK_VERSION); | 169 | pID3D = (*d3dCreate)(D3D_SDK_VERSION); |
170 | 170 | ||
171 | if (!pID3D) | 171 | if (!pID3D) |
172 | { | 172 | { |
173 | os::Printer::log("Error initializing D3D.", ELL_ERROR); | 173 | os::Printer::log("Error initializing D3D.", ELL_ERROR); |
174 | return false; | 174 | return false; |
175 | } | 175 | } |
176 | 176 | ||
177 | // print device information | 177 | // print device information |
178 | D3DADAPTER_IDENTIFIER8 dai; | 178 | D3DADAPTER_IDENTIFIER8 dai; |
179 | if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, D3DENUM_NO_WHQL_LEVEL, &dai))) | 179 | if (!FAILED(pID3D->GetAdapterIdentifier(Params.DisplayAdapter, D3DENUM_NO_WHQL_LEVEL, &dai))) |
180 | { | 180 | { |
181 | char tmp[512]; | 181 | char tmp[512]; |
182 | 182 | ||
183 | s32 Product = HIWORD(dai.DriverVersion.HighPart); | 183 | s32 Product = HIWORD(dai.DriverVersion.HighPart); |
184 | s32 Version = LOWORD(dai.DriverVersion.HighPart); | 184 | s32 Version = LOWORD(dai.DriverVersion.HighPart); |
185 | s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); | 185 | s32 SubVersion = HIWORD(dai.DriverVersion.LowPart); |
186 | s32 Build = LOWORD(dai.DriverVersion.LowPart); | 186 | s32 Build = LOWORD(dai.DriverVersion.LowPart); |
187 | 187 | ||
188 | sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, | 188 | sprintf(tmp, "%s %s %d.%d.%d.%d", dai.Description, dai.Driver, Product, Version, |
189 | SubVersion, Build); | 189 | SubVersion, Build); |
190 | os::Printer::log(tmp, ELL_INFORMATION); | 190 | os::Printer::log(tmp, ELL_INFORMATION); |
191 | } | 191 | } |
192 | 192 | ||
193 | D3DDISPLAYMODE d3ddm; | 193 | D3DDISPLAYMODE d3ddm; |
194 | hr = pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm); | 194 | hr = pID3D->GetAdapterDisplayMode(Params.DisplayAdapter, &d3ddm); |
195 | if (FAILED(hr)) | 195 | if (FAILED(hr)) |
196 | { | 196 | { |
197 | os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); | 197 | os::Printer::log("Error: Could not get Adapter Display mode.", ELL_ERROR); |
198 | return false; | 198 | return false; |
199 | } | 199 | } |
200 | 200 | ||
201 | ZeroMemory(&present, sizeof(present)); | 201 | ZeroMemory(&present, sizeof(present)); |
202 | 202 | ||
203 | present.SwapEffect = D3DSWAPEFFECT_DISCARD; | 203 | present.SwapEffect = D3DSWAPEFFECT_DISCARD; |
204 | present.Windowed = TRUE; | 204 | present.Windowed = TRUE; |
205 | present.BackBufferFormat = d3ddm.Format; | 205 | present.BackBufferFormat = d3ddm.Format; |
206 | present.EnableAutoDepthStencil = TRUE; | 206 | present.EnableAutoDepthStencil = TRUE; |
207 | 207 | ||
208 | if (Params.Fullscreen) | 208 | if (Params.Fullscreen) |
209 | { | 209 | { |
210 | present.SwapEffect = D3DSWAPEFFECT_FLIP; | 210 | present.SwapEffect = D3DSWAPEFFECT_FLIP; |
211 | present.Windowed = FALSE; | 211 | present.Windowed = FALSE; |
212 | present.BackBufferWidth = Params.WindowSize.Width; | 212 | present.BackBufferWidth = Params.WindowSize.Width; |
213 | present.BackBufferHeight = Params.WindowSize.Height; | 213 | present.BackBufferHeight = Params.WindowSize.Height; |
214 | present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; | 214 | present.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; |
215 | 215 | ||
216 | if (Params.Vsync) | 216 | if (Params.Vsync) |
217 | present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; | 217 | present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_ONE; |
218 | else | 218 | else |
219 | present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; | 219 | present.FullScreen_PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; |
220 | 220 | ||
221 | if (Params.Bits == 32) | 221 | if (Params.Bits == 32) |
222 | present.BackBufferFormat = D3DFMT_X8R8G8B8; | 222 | present.BackBufferFormat = D3DFMT_X8R8G8B8; |
223 | else | 223 | else |
224 | present.BackBufferFormat = D3DFMT_R5G6B5; | 224 | present.BackBufferFormat = D3DFMT_R5G6B5; |
225 | } | 225 | } |
226 | 226 | ||
227 | D3DDEVTYPE devtype = D3DDEVTYPE_HAL; | 227 | D3DDEVTYPE devtype = D3DDEVTYPE_HAL; |
228 | #ifndef _IRR_D3D_NO_SHADER_DEBUGGING | 228 | #ifndef _IRR_D3D_NO_SHADER_DEBUGGING |
229 | devtype = D3DDEVTYPE_REF; | 229 | devtype = D3DDEVTYPE_REF; |
230 | #endif | 230 | #endif |
231 | 231 | ||
232 | // enable anti alias if possible and whished | 232 | // enable anti alias if possible and whished |
233 | if (Params.AntiAlias > 0) | 233 | if (Params.AntiAlias > 0) |
234 | { | 234 | { |
235 | if(Params.AntiAlias > 16) | 235 | if(Params.AntiAlias > 16) |
236 | Params.AntiAlias = 16; | 236 | Params.AntiAlias = 16; |
237 | 237 | ||
238 | while(Params.AntiAlias > 0) | 238 | while(Params.AntiAlias > 0) |
239 | { | 239 | { |
240 | if(!FAILED(pID3D->CheckDeviceMultiSampleType(Params.DisplayAdapter, | 240 | if(!FAILED(pID3D->CheckDeviceMultiSampleType(Params.DisplayAdapter, |
241 | devtype , present.BackBufferFormat, !Params.Fullscreen, | 241 | devtype , present.BackBufferFormat, !Params.Fullscreen, |
242 | (D3DMULTISAMPLE_TYPE)Params.AntiAlias))) | 242 | (D3DMULTISAMPLE_TYPE)Params.AntiAlias))) |
243 | { | 243 | { |
244 | present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias; | 244 | present.MultiSampleType = (D3DMULTISAMPLE_TYPE)Params.AntiAlias; |
245 | present.SwapEffect = D3DSWAPEFFECT_DISCARD; | 245 | present.SwapEffect = D3DSWAPEFFECT_DISCARD; |
246 | break; | 246 | break; |
247 | } | 247 | } |
248 | --Params.AntiAlias; | 248 | --Params.AntiAlias; |
249 | } | 249 | } |
250 | 250 | ||
251 | if(Params.AntiAlias==0) | 251 | if(Params.AntiAlias==0) |
252 | os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); | 252 | os::Printer::log("Anti aliasing disabled because hardware/driver lacks necessary caps.", ELL_WARNING); |
253 | } | 253 | } |
254 | 254 | ||
255 | // check stencil buffer compatibility | 255 | // check stencil buffer compatibility |
256 | if (Params.Stencilbuffer) | 256 | if (Params.Stencilbuffer) |
257 | { | 257 | { |
258 | present.AutoDepthStencilFormat = D3DFMT_D24S8; | 258 | present.AutoDepthStencilFormat = D3DFMT_D24S8; |
259 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, | 259 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, |
260 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, | 260 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, |
261 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) | 261 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) |
262 | { | 262 | { |
263 | #if !defined( _IRR_XBOX_PLATFORM_) | 263 | #if !defined( _IRR_XBOX_PLATFORM_) |
264 | present.AutoDepthStencilFormat = D3DFMT_D24X4S4; | 264 | present.AutoDepthStencilFormat = D3DFMT_D24X4S4; |
265 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, | 265 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, |
266 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, | 266 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, |
267 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) | 267 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) |
268 | { | 268 | { |
269 | present.AutoDepthStencilFormat = D3DFMT_D15S1; | 269 | present.AutoDepthStencilFormat = D3DFMT_D15S1; |
270 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, | 270 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, |
271 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, | 271 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, |
272 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) | 272 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) |
273 | { | 273 | { |
274 | os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); | 274 | os::Printer::log("Device does not support stencilbuffer, disabling stencil buffer.", ELL_WARNING); |
275 | Params.Stencilbuffer = false; | 275 | Params.Stencilbuffer = false; |
276 | } | 276 | } |
277 | } | 277 | } |
278 | #endif | 278 | #endif |
279 | } | 279 | } |
280 | else | 280 | else |
281 | if(FAILED(pID3D->CheckDepthStencilMatch(Params.DisplayAdapter, devtype, | 281 | if(FAILED(pID3D->CheckDepthStencilMatch(Params.DisplayAdapter, devtype, |
282 | present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) | 282 | present.BackBufferFormat, present.BackBufferFormat, present.AutoDepthStencilFormat))) |
283 | { | 283 | { |
284 | os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); | 284 | os::Printer::log("Depth-stencil format is not compatible with display format, disabling stencil buffer.", ELL_WARNING); |
285 | Params.Stencilbuffer = false; | 285 | Params.Stencilbuffer = false; |
286 | } | 286 | } |
287 | } | 287 | } |
288 | // do not use else here to cope with flag change in previous block | 288 | // do not use else here to cope with flag change in previous block |
289 | if (!Params.Stencilbuffer) | 289 | if (!Params.Stencilbuffer) |
290 | { | 290 | { |
291 | #if !defined( _IRR_XBOX_PLATFORM_) | 291 | #if !defined( _IRR_XBOX_PLATFORM_) |
292 | present.AutoDepthStencilFormat = D3DFMT_D32; | 292 | present.AutoDepthStencilFormat = D3DFMT_D32; |
293 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, | 293 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, |
294 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, | 294 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, |
295 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) | 295 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) |
296 | { | 296 | { |
297 | present.AutoDepthStencilFormat = D3DFMT_D24X8; | 297 | present.AutoDepthStencilFormat = D3DFMT_D24X8; |
298 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, | 298 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, |
299 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, | 299 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, |
300 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) | 300 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) |
301 | { | 301 | { |
302 | present.AutoDepthStencilFormat = D3DFMT_D16; | 302 | present.AutoDepthStencilFormat = D3DFMT_D16; |
303 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, | 303 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, |
304 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, | 304 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, |
305 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) | 305 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) |
306 | { | 306 | { |
307 | os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); | 307 | os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); |
308 | return false; | 308 | return false; |
309 | } | 309 | } |
310 | } | 310 | } |
311 | } | 311 | } |
312 | #else | 312 | #else |
313 | present.AutoDepthStencilFormat = D3DFMT_D16; | 313 | present.AutoDepthStencilFormat = D3DFMT_D16; |
314 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, | 314 | if(FAILED(pID3D->CheckDeviceFormat(Params.DisplayAdapter, devtype, |
315 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, | 315 | present.BackBufferFormat, D3DUSAGE_DEPTHSTENCIL, |
316 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) | 316 | D3DRTYPE_SURFACE, present.AutoDepthStencilFormat))) |
317 | { | 317 | { |
318 | os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); | 318 | os::Printer::log("Device does not support required depth buffer.", ELL_WARNING); |
319 | return false; | 319 | return false; |
320 | } | 320 | } |
321 | #endif | 321 | #endif |
322 | } | 322 | } |
323 | 323 | ||
324 | // create device | 324 | // create device |
325 | #if defined( _IRR_XBOX_PLATFORM_) | 325 | #if defined( _IRR_XBOX_PLATFORM_) |
326 | DWORD fpuPrecision = 0; | 326 | DWORD fpuPrecision = 0; |
327 | #else | 327 | #else |
328 | DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; | 328 | DWORD fpuPrecision = Params.HighPrecisionFPU ? D3DCREATE_FPU_PRESERVE : 0; |
329 | DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0; | 329 | DWORD multithreaded = Params.DriverMultithreaded ? D3DCREATE_MULTITHREADED : 0; |
330 | #endif | 330 | #endif |
331 | if (pureSoftware) | 331 | if (pureSoftware) |
332 | { | 332 | { |
333 | hr = pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd, | 333 | hr = pID3D->CreateDevice(Params.DisplayAdapter, D3DDEVTYPE_REF, hwnd, |
334 | fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); | 334 | fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); |
335 | 335 | ||
336 | if (FAILED(hr)) | 336 | if (FAILED(hr)) |
337 | os::Printer::log("Was not able to create Direct3D8 software device.", ELL_ERROR); | 337 | os::Printer::log("Was not able to create Direct3D8 software device.", ELL_ERROR); |
338 | } | 338 | } |
339 | else | 339 | else |
340 | { | 340 | { |
341 | hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, | 341 | hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, |
342 | fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); | 342 | fpuPrecision | multithreaded | D3DCREATE_HARDWARE_VERTEXPROCESSING, &present, &pID3DDevice); |
343 | 343 | ||
344 | if(FAILED(hr)) | 344 | if(FAILED(hr)) |
345 | hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, | 345 | hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, |
346 | fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); | 346 | fpuPrecision | multithreaded | D3DCREATE_MIXED_VERTEXPROCESSING , &present, &pID3DDevice); |
347 | if(FAILED(hr)) | 347 | if(FAILED(hr)) |
348 | hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, | 348 | hr = pID3D->CreateDevice(Params.DisplayAdapter, devtype, hwnd, |
349 | fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); | 349 | fpuPrecision | multithreaded | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &present, &pID3DDevice); |
350 | if (FAILED(hr)) | 350 | if (FAILED(hr)) |
351 | os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); | 351 | os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); |
352 | } | 352 | } |
353 | 353 | ||
354 | if (!pID3DDevice) | 354 | if (!pID3DDevice) |
355 | { | 355 | { |
356 | os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); | 356 | os::Printer::log("Was not able to create Direct3D8 device.", ELL_ERROR); |
357 | return false; | 357 | return false; |
358 | } | 358 | } |
359 | 359 | ||
360 | // get caps | 360 | // get caps |
361 | pID3DDevice->GetDeviceCaps(&Caps); | 361 | pID3DDevice->GetDeviceCaps(&Caps); |
362 | 362 | ||
363 | if (Params.Stencilbuffer && | 363 | if (Params.Stencilbuffer && |
364 | (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || | 364 | (!(Caps.StencilCaps & D3DSTENCILCAPS_DECRSAT) || |
365 | !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || | 365 | !(Caps.StencilCaps & D3DSTENCILCAPS_INCRSAT) || |
366 | !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) | 366 | !(Caps.StencilCaps & D3DSTENCILCAPS_KEEP))) |
367 | { | 367 | { |
368 | os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); | 368 | os::Printer::log("Device not able to use stencil buffer, disabling stencil buffer.", ELL_WARNING); |
369 | Params.Stencilbuffer = false; | 369 | Params.Stencilbuffer = false; |
370 | } | 370 | } |
371 | 371 | ||
372 | // set default vertex shader | 372 | // set default vertex shader |
373 | setVertexShader(EVT_STANDARD); | 373 | setVertexShader(EVT_STANDARD); |
374 | 374 | ||
375 | // enable antialiasing | 375 | // enable antialiasing |
376 | if (Params.AntiAlias>0) | 376 | if (Params.AntiAlias>0) |
377 | pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); | 377 | pID3DDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); |
378 | 378 | ||
379 | // set fog mode | 379 | // set fog mode |
380 | setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); | 380 | setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); |
381 | 381 | ||
382 | // set exposed data | 382 | // set exposed data |
383 | ExposedData.D3D8.D3D8 = pID3D; | 383 | ExposedData.D3D8.D3D8 = pID3D; |
384 | ExposedData.D3D8.D3DDev8 = pID3DDevice; | 384 | ExposedData.D3D8.D3DDev8 = pID3DDevice; |
385 | ExposedData.D3D8.HWnd = hwnd; | 385 | ExposedData.D3D8.HWnd = hwnd; |
386 | 386 | ||
387 | ResetRenderStates = true; | 387 | ResetRenderStates = true; |
388 | 388 | ||
389 | // create materials | 389 | // create materials |
390 | createMaterialRenderers(); | 390 | createMaterialRenderers(); |
391 | 391 | ||
392 | MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); | 392 | MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES); |
393 | MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; | 393 | MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes; |
394 | 394 | ||
395 | DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits); | 395 | DriverAttributes->setAttribute("MaxTextures", (s32)MaxTextureUnits); |
396 | DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures); | 396 | DriverAttributes->setAttribute("MaxSupportedTextures", (s32)Caps.MaxSimultaneousTextures); |
397 | DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights); | 397 | DriverAttributes->setAttribute("MaxLights", (s32)Caps.MaxActiveLights); |
398 | DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy); | 398 | DriverAttributes->setAttribute("MaxAnisotropy", (s32)Caps.MaxAnisotropy); |
399 | DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes); | 399 | DriverAttributes->setAttribute("MaxUserClipPlanes", (s32)Caps.MaxUserClipPlanes); |
400 | DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex); | 400 | DriverAttributes->setAttribute("MaxIndices", (s32)Caps.MaxVertexIndex); |
401 | DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth)); | 401 | DriverAttributes->setAttribute("MaxTextureSize", (s32)core::min_(Caps.MaxTextureHeight,Caps.MaxTextureWidth)); |
402 | DriverAttributes->setAttribute("MaxTextureLODBias", 16.f); | 402 | DriverAttributes->setAttribute("MaxTextureLODBias", 16.f); |
403 | DriverAttributes->setAttribute("Version", 800); | 403 | DriverAttributes->setAttribute("Version", 800); |
404 | DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100); | 404 | DriverAttributes->setAttribute("ShaderLanguageVersion", (s32)Caps.VertexShaderVersion*100); |
405 | DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias); | 405 | DriverAttributes->setAttribute("AntiAlias", Params.AntiAlias); |
406 | 406 | ||
407 | // set the renderstates | 407 | // set the renderstates |
408 | setRenderStates3DMode(); | 408 | setRenderStates3DMode(); |
409 | 409 | ||
410 | // so far so good. | 410 | // so far so good. |
411 | return true; | 411 | return true; |
412 | } | 412 | } |
413 | 413 | ||
414 | 414 | ||
415 | //! applications must call this method before performing any rendering. returns false if failed. | 415 | //! applications must call this method before performing any rendering. returns false if failed. |
416 | bool CD3D8Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, | 416 | bool CD3D8Driver::beginScene(bool backBuffer, bool zBuffer, SColor color, |
417 | const SExposedVideoData& videoData, core::rect<s32>* sourceRect) | 417 | const SExposedVideoData& videoData, core::rect<s32>* sourceRect) |
418 | { | 418 | { |
419 | CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); | 419 | CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); |
420 | WindowId = (HWND)videoData.D3D8.HWnd; | 420 | WindowId = (HWND)videoData.D3D8.HWnd; |
421 | SceneSourceRect = sourceRect; | 421 | SceneSourceRect = sourceRect; |
422 | 422 | ||
423 | if (!pID3DDevice) | 423 | if (!pID3DDevice) |
424 | return false; | 424 | return false; |
425 | 425 | ||
426 | HRESULT hr; | 426 | HRESULT hr; |
427 | if (DeviceLost) | 427 | if (DeviceLost) |
428 | { | 428 | { |
429 | #ifndef _IRR_XBOX_PLATFORM_ | 429 | #ifndef _IRR_XBOX_PLATFORM_ |
430 | if(FAILED(hr = pID3DDevice->TestCooperativeLevel())) | 430 | if(FAILED(hr = pID3DDevice->TestCooperativeLevel())) |
431 | { | 431 | { |
432 | if (hr == D3DERR_DEVICELOST) | 432 | if (hr == D3DERR_DEVICELOST) |
433 | { | 433 | { |
434 | Sleep(100); | 434 | Sleep(100); |
435 | hr = pID3DDevice->TestCooperativeLevel(); | 435 | hr = pID3DDevice->TestCooperativeLevel(); |
436 | if (hr == D3DERR_DEVICELOST) | 436 | if (hr == D3DERR_DEVICELOST) |
437 | return false; | 437 | return false; |
438 | } | 438 | } |
439 | 439 | ||
440 | if ((hr == D3DERR_DEVICENOTRESET) && !reset()) | 440 | if ((hr == D3DERR_DEVICENOTRESET) && !reset()) |
441 | return false; | 441 | return false; |
442 | } | 442 | } |
443 | #endif | 443 | #endif |
444 | } | 444 | } |
445 | 445 | ||
446 | DWORD flags = 0; | 446 | DWORD flags = 0; |
447 | 447 | ||
448 | if (backBuffer) | 448 | if (backBuffer) |
449 | flags |= D3DCLEAR_TARGET; | 449 | flags |= D3DCLEAR_TARGET; |
450 | 450 | ||
451 | if (zBuffer) | 451 | if (zBuffer) |
452 | flags |= D3DCLEAR_ZBUFFER; | 452 | flags |= D3DCLEAR_ZBUFFER; |
453 | 453 | ||
454 | if (Params.Stencilbuffer) | 454 | if (Params.Stencilbuffer) |
455 | flags |= D3DCLEAR_STENCIL; | 455 | flags |= D3DCLEAR_STENCIL; |
456 | 456 | ||
457 | if (flags) | 457 | if (flags) |
458 | { | 458 | { |
459 | hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); | 459 | hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0); |
460 | if (FAILED(hr)) | 460 | if (FAILED(hr)) |
461 | os::Printer::log("Direct3D8 clear failed.", ELL_WARNING); | 461 | os::Printer::log("Direct3D8 clear failed.", ELL_WARNING); |
462 | } | 462 | } |
463 | 463 | ||
464 | hr = pID3DDevice->BeginScene(); | 464 | hr = pID3DDevice->BeginScene(); |
465 | if (FAILED(hr)) | 465 | if (FAILED(hr)) |
466 | { | 466 | { |
467 | os::Printer::log("Direct3D8 begin scene failed.", ELL_WARNING); | 467 | os::Printer::log("Direct3D8 begin scene failed.", ELL_WARNING); |
468 | return false; | 468 | return false; |
469 | } | 469 | } |
470 | 470 | ||
471 | return true; | 471 | return true; |
472 | } | 472 | } |
473 | 473 | ||
474 | 474 | ||
475 | //! applications must call this method after performing any rendering. returns false if failed. | 475 | //! applications must call this method after performing any rendering. returns false if failed. |
476 | bool CD3D8Driver::endScene() | 476 | bool CD3D8Driver::endScene() |
477 | { | 477 | { |
478 | CNullDriver::endScene(); | 478 | CNullDriver::endScene(); |
479 | DriverWasReset=false; | 479 | DriverWasReset=false; |
480 | 480 | ||
481 | HRESULT hr = pID3DDevice->EndScene(); | 481 | HRESULT hr = pID3DDevice->EndScene(); |
482 | if (FAILED(hr)) | 482 | if (FAILED(hr)) |
483 | { | 483 | { |
484 | os::Printer::log("DIRECT3D8 end scene failed.", ELL_WARNING); | 484 | os::Printer::log("DIRECT3D8 end scene failed.", ELL_WARNING); |
485 | return false; | 485 | return false; |
486 | } | 486 | } |
487 | 487 | ||
488 | RECT* srcRct = 0; | 488 | RECT* srcRct = 0; |
489 | RECT sourceRectData; | 489 | RECT sourceRectData; |
490 | if ( SceneSourceRect) | 490 | if ( SceneSourceRect) |
491 | { | 491 | { |
492 | srcRct = &sourceRectData; | 492 | srcRct = &sourceRectData; |
493 | sourceRectData.left = SceneSourceRect->UpperLeftCorner.X; | 493 | sourceRectData.left = SceneSourceRect->UpperLeftCorner.X; |
494 | sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y; | 494 | sourceRectData.top = SceneSourceRect->UpperLeftCorner.Y; |
495 | sourceRectData.right = SceneSourceRect->LowerRightCorner.X; | 495 | sourceRectData.right = SceneSourceRect->LowerRightCorner.X; |
496 | sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; | 496 | sourceRectData.bottom = SceneSourceRect->LowerRightCorner.Y; |
497 | } | 497 | } |
498 | 498 | ||
499 | hr = pID3DDevice->Present(srcRct, NULL, WindowId, NULL); | 499 | hr = pID3DDevice->Present(srcRct, NULL, WindowId, NULL); |
500 | 500 | ||
501 | if (SUCCEEDED(hr)) | 501 | if (SUCCEEDED(hr)) |
502 | return true; | 502 | return true; |
503 | 503 | ||
504 | if (hr == D3DERR_DEVICELOST) | 504 | if (hr == D3DERR_DEVICELOST) |
505 | { | 505 | { |
506 | DeviceLost = true; | 506 | DeviceLost = true; |
507 | os::Printer::log("DIRECT3D8 device lost.", ELL_WARNING); | 507 | os::Printer::log("DIRECT3D8 device lost.", ELL_WARNING); |
508 | } | 508 | } |
509 | else | 509 | else |
510 | os::Printer::log("DIRECT3D8 present failed.", ELL_WARNING); | 510 | os::Printer::log("DIRECT3D8 present failed.", ELL_WARNING); |
511 | return false; | 511 | return false; |
512 | } | 512 | } |
513 | 513 | ||
514 | 514 | ||
515 | //! resets the device | 515 | //! resets the device |
516 | bool CD3D8Driver::reset() | 516 | bool CD3D8Driver::reset() |
517 | { | 517 | { |
518 | u32 i; | 518 | u32 i; |
519 | os::Printer::log("Resetting D3D8 device.", ELL_INFORMATION); | 519 | os::Printer::log("Resetting D3D8 device.", ELL_INFORMATION); |
520 | 520 | ||
521 | for (i=0; i<Textures.size(); ++i) | 521 | for (i=0; i<Textures.size(); ++i) |
522 | { | 522 | { |
523 | if (Textures[i].Surface->isRenderTarget()) | 523 | if (Textures[i].Surface->isRenderTarget()) |
524 | { | 524 | { |
525 | IDirect3DTexture8* tex = ((CD3D8Texture*)(Textures[i].Surface))->getDX8Texture(); | 525 | IDirect3DTexture8* tex = ((CD3D8Texture*)(Textures[i].Surface))->getDX8Texture(); |
526 | if (tex) | 526 | if (tex) |
527 | tex->Release(); | 527 | tex->Release(); |
528 | } | 528 | } |
529 | } | 529 | } |
530 | DriverWasReset=true; | 530 | DriverWasReset=true; |
531 | 531 | ||
532 | HRESULT hr = pID3DDevice->Reset(&present); | 532 | HRESULT hr = pID3DDevice->Reset(&present); |
533 | 533 | ||
534 | for (i=0; i<Textures.size(); ++i) | 534 | for (i=0; i<Textures.size(); ++i) |
535 | { | 535 | { |
536 | if (Textures[i].Surface->isRenderTarget()) | 536 | if (Textures[i].Surface->isRenderTarget()) |
537 | ((CD3D8Texture*)(Textures[i].Surface))->createRenderTarget(); | 537 | ((CD3D8Texture*)(Textures[i].Surface))->createRenderTarget(); |
538 | } | 538 | } |
539 | 539 | ||
540 | if (FAILED(hr)) | 540 | if (FAILED(hr)) |
541 | { | 541 | { |
542 | if (hr == D3DERR_DEVICELOST) | 542 | if (hr == D3DERR_DEVICELOST) |
543 | { | 543 | { |
544 | DeviceLost = true; | 544 | DeviceLost = true; |
545 | os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); | 545 | os::Printer::log("Resetting failed due to device lost.", ELL_WARNING); |
546 | } | 546 | } |
547 | else | 547 | else |
548 | os::Printer::log("Resetting failed.", ELL_WARNING); | 548 | os::Printer::log("Resetting failed.", ELL_WARNING); |
549 | return false; | 549 | return false; |
550 | } | 550 | } |
551 | 551 | ||
552 | DeviceLost = false; | 552 | DeviceLost = false; |
553 | ResetRenderStates = true; | 553 | ResetRenderStates = true; |
554 | LastVertexType = (E_VERTEX_TYPE)-1; | 554 | LastVertexType = (E_VERTEX_TYPE)-1; |
555 | 555 | ||
556 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) | 556 | for (i=0; i<MATERIAL_MAX_TEXTURES; ++i) |
557 | CurrentTexture[i] = 0; | 557 | CurrentTexture[i] = 0; |
558 | 558 | ||
559 | setVertexShader(EVT_STANDARD); | 559 | setVertexShader(EVT_STANDARD); |
560 | setRenderStates3DMode(); | 560 | setRenderStates3DMode(); |
561 | setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); | 561 | setFog(FogColor, FogType, FogStart, FogEnd, FogDensity, PixelFog, RangeFog); |
562 | setAmbientLight(AmbientLight); | 562 | setAmbientLight(AmbientLight); |
563 | 563 | ||
564 | return true; | 564 | return true; |
565 | } | 565 | } |
566 | 566 | ||
567 | 567 | ||
568 | //! queries the features of the driver, returns true if feature is available | 568 | //! queries the features of the driver, returns true if feature is available |
569 | bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const | 569 | bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const |
570 | { | 570 | { |
571 | if (!FeatureEnabled[feature]) | 571 | if (!FeatureEnabled[feature]) |
572 | return false; | 572 | return false; |
573 | 573 | ||
574 | switch (feature) | 574 | switch (feature) |
575 | { | 575 | { |
576 | case EVDF_RENDER_TO_TARGET: | 576 | case EVDF_RENDER_TO_TARGET: |
577 | case EVDF_MULTITEXTURE: | 577 | case EVDF_MULTITEXTURE: |
578 | case EVDF_BILINEAR_FILTER: | 578 | case EVDF_BILINEAR_FILTER: |
579 | return true; | 579 | return true; |
580 | case EVDF_HARDWARE_TL: | 580 | case EVDF_HARDWARE_TL: |
581 | return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; | 581 | return (Caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT) != 0; |
582 | case EVDF_MIP_MAP: | 582 | case EVDF_MIP_MAP: |
583 | return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; | 583 | return (Caps.TextureCaps & D3DPTEXTURECAPS_MIPMAP) != 0; |
584 | case EVDF_STENCIL_BUFFER: | 584 | case EVDF_STENCIL_BUFFER: |
585 | return Params.Stencilbuffer && Caps.StencilCaps; | 585 | return Params.Stencilbuffer && Caps.StencilCaps; |
586 | case EVDF_VERTEX_SHADER_1_1: | 586 | case EVDF_VERTEX_SHADER_1_1: |
587 | return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); | 587 | return Caps.VertexShaderVersion >= D3DVS_VERSION(1,1); |
588 | case EVDF_VERTEX_SHADER_2_0: | 588 | case EVDF_VERTEX_SHADER_2_0: |
589 | return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); | 589 | return Caps.VertexShaderVersion >= D3DVS_VERSION(2,0); |
590 | case EVDF_VERTEX_SHADER_3_0: | 590 | case EVDF_VERTEX_SHADER_3_0: |
591 | return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); | 591 | return Caps.VertexShaderVersion >= D3DVS_VERSION(3,0); |
592 | case EVDF_PIXEL_SHADER_1_1: | 592 | case EVDF_PIXEL_SHADER_1_1: |
593 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); | 593 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,1); |
594 | case EVDF_PIXEL_SHADER_1_2: | 594 | case EVDF_PIXEL_SHADER_1_2: |
595 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); | 595 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,2); |
596 | case EVDF_PIXEL_SHADER_1_3: | 596 | case EVDF_PIXEL_SHADER_1_3: |
597 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); | 597 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,3); |
598 | case EVDF_PIXEL_SHADER_1_4: | 598 | case EVDF_PIXEL_SHADER_1_4: |
599 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); | 599 | return Caps.PixelShaderVersion >= D3DPS_VERSION(1,4); |
600 | case EVDF_PIXEL_SHADER_2_0: | 600 | case EVDF_PIXEL_SHADER_2_0: |
601 | return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); | 601 | return Caps.PixelShaderVersion >= D3DPS_VERSION(2,0); |
602 | case EVDF_PIXEL_SHADER_3_0: | 602 | case EVDF_PIXEL_SHADER_3_0: |
603 | return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); | 603 | return Caps.PixelShaderVersion >= D3DPS_VERSION(3,0); |
604 | case EVDF_TEXTURE_NSQUARE: | 604 | case EVDF_TEXTURE_NSQUARE: |
605 | return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0; | 605 | return (Caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY) == 0; |
606 | case EVDF_TEXTURE_NPOT: | 606 | case EVDF_TEXTURE_NPOT: |
607 | return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; | 607 | return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; |
608 | case EVDF_COLOR_MASK: | 608 | case EVDF_COLOR_MASK: |
609 | return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; | 609 | return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; |
610 | case EVDF_BLEND_OPERATIONS: | 610 | case EVDF_BLEND_OPERATIONS: |
611 | case EVDF_TEXTURE_MATRIX: | 611 | case EVDF_TEXTURE_MATRIX: |
612 | return true; | 612 | return true; |
613 | default: | 613 | default: |
614 | return false; | 614 | return false; |
615 | }; | 615 | }; |
616 | } | 616 | } |
617 | 617 | ||
618 | 618 | ||
619 | //! sets transformation | 619 | //! sets transformation |
620 | void CD3D8Driver::setTransform(E_TRANSFORMATION_STATE state, | 620 | void CD3D8Driver::setTransform(E_TRANSFORMATION_STATE state, |
621 | const core::matrix4& mat) | 621 | const core::matrix4& mat) |
622 | { | 622 | { |
623 | switch(state) | 623 | switch(state) |
624 | { | 624 | { |
625 | case ETS_VIEW: | 625 | case ETS_VIEW: |
626 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); | 626 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)mat.pointer())); |
627 | Transformation3DChanged = true; | 627 | Transformation3DChanged = true; |
628 | break; | 628 | break; |
629 | case ETS_WORLD: | 629 | case ETS_WORLD: |
630 | pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); | 630 | pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); |
631 | Transformation3DChanged = true; | 631 | Transformation3DChanged = true; |
632 | break; | 632 | break; |
633 | case ETS_PROJECTION: | 633 | case ETS_PROJECTION: |
634 | pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); | 634 | pID3DDevice->SetTransform( D3DTS_PROJECTION, (D3DMATRIX*)((void*)mat.pointer())); |
635 | Transformation3DChanged = true; | 635 | Transformation3DChanged = true; |
636 | break; | 636 | break; |
637 | case ETS_COUNT: | 637 | case ETS_COUNT: |
638 | return; | 638 | return; |
639 | default: | 639 | default: |
640 | if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES) | 640 | if (state-ETS_TEXTURE_0 < MATERIAL_MAX_TEXTURES) |
641 | { | 641 | { |
642 | pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); | 642 | pID3DDevice->SetTextureStageState( state - ETS_TEXTURE_0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); |
643 | pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), | 643 | pID3DDevice->SetTransform((D3DTRANSFORMSTATETYPE)(D3DTS_TEXTURE0+ ( state - ETS_TEXTURE_0 )), |
644 | (D3DMATRIX*)((void*)mat.pointer())); | 644 | (D3DMATRIX*)((void*)mat.pointer())); |
645 | } | 645 | } |
646 | break; | 646 | break; |
647 | } | 647 | } |
648 | 648 | ||
649 | Matrices[state] = mat; | 649 | Matrices[state] = mat; |
650 | } | 650 | } |
651 | 651 | ||
652 | 652 | ||
653 | //! sets the current Texture | 653 | //! sets the current Texture |
654 | bool CD3D8Driver::setActiveTexture(u32 stage, const video::ITexture* texture) | 654 | bool CD3D8Driver::setActiveTexture(u32 stage, const video::ITexture* texture) |
655 | { | 655 | { |
656 | if (CurrentTexture[stage] == texture) | 656 | if (CurrentTexture[stage] == texture) |
657 | return true; | 657 | return true; |
658 | 658 | ||
659 | if (texture && (texture->getDriverType() != EDT_DIRECT3D8)) | 659 | if (texture && (texture->getDriverType() != EDT_DIRECT3D8)) |
660 | { | 660 | { |
661 | os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); | 661 | os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); |
662 | return false; | 662 | return false; |
663 | } | 663 | } |
664 | 664 | ||
665 | CurrentTexture[stage] = texture; | 665 | CurrentTexture[stage] = texture; |
666 | 666 | ||
667 | if (!texture) | 667 | if (!texture) |
668 | { | 668 | { |
669 | pID3DDevice->SetTexture(stage, 0); | 669 | pID3DDevice->SetTexture(stage, 0); |
670 | pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); | 670 | pID3DDevice->SetTextureStageState( stage, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); |
671 | } | 671 | } |
672 | else | 672 | else |
673 | { | 673 | { |
674 | pID3DDevice->SetTexture(stage, ((const CD3D8Texture*)texture)->getDX8Texture()); | 674 | pID3DDevice->SetTexture(stage, ((const CD3D8Texture*)texture)->getDX8Texture()); |
675 | } | 675 | } |
676 | return true; | 676 | return true; |
677 | } | 677 | } |
678 | 678 | ||
679 | 679 | ||
680 | //! sets a material | 680 | //! sets a material |
681 | void CD3D8Driver::setMaterial(const SMaterial& material) | 681 | void CD3D8Driver::setMaterial(const SMaterial& material) |
682 | { | 682 | { |
683 | Material = material; | 683 | Material = material; |
684 | OverrideMaterial.apply(Material); | 684 | OverrideMaterial.apply(Material); |
685 | 685 | ||
686 | for (u32 i=0; i<MaxTextureUnits; ++i) | 686 | for (u32 i=0; i<MaxTextureUnits; ++i) |
687 | { | 687 | { |
688 | setActiveTexture(i, Material.getTexture(i)); | 688 | setActiveTexture(i, Material.getTexture(i)); |
689 | setTransform((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), | 689 | setTransform((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), |
690 | material.getTextureMatrix(i)); | 690 | material.getTextureMatrix(i)); |
691 | } | 691 | } |
692 | } | 692 | } |
693 | 693 | ||
694 | 694 | ||
695 | //! returns a device dependent texture from a software surface (IImage) | 695 | //! returns a device dependent texture from a software surface (IImage) |
696 | video::ITexture* CD3D8Driver::createDeviceDependentTexture(IImage* surface,const io::path& name, void* mipmapData) | 696 | video::ITexture* CD3D8Driver::createDeviceDependentTexture(IImage* surface,const io::path& name, void* mipmapData) |
697 | { | 697 | { |
698 | return new CD3D8Texture(surface, this, TextureCreationFlags, name, mipmapData); | 698 | return new CD3D8Texture(surface, this, TextureCreationFlags, name, mipmapData); |
699 | } | 699 | } |
700 | 700 | ||
701 | 701 | ||
702 | //! Enables or disables a texture creation flag. | 702 | //! Enables or disables a texture creation flag. |
703 | void CD3D8Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, | 703 | void CD3D8Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, |
704 | bool enabled) | 704 | bool enabled) |
705 | { | 705 | { |
706 | if (flag == video::ETCF_CREATE_MIP_MAPS && !queryFeature(EVDF_MIP_MAP)) | 706 | if (flag == video::ETCF_CREATE_MIP_MAPS && !queryFeature(EVDF_MIP_MAP)) |
707 | enabled = false; | 707 | enabled = false; |
708 | 708 | ||
709 | CNullDriver::setTextureCreationFlag(flag, enabled); | 709 | CNullDriver::setTextureCreationFlag(flag, enabled); |
710 | } | 710 | } |
711 | 711 | ||
712 | 712 | ||
713 | //! sets a render target | 713 | //! sets a render target |
714 | bool CD3D8Driver::setRenderTarget(video::ITexture* texture, | 714 | bool CD3D8Driver::setRenderTarget(video::ITexture* texture, |
715 | bool clearBackBuffer, bool clearZBuffer, SColor color) | 715 | bool clearBackBuffer, bool clearZBuffer, SColor color) |
716 | { | 716 | { |
717 | // check for right driver type | 717 | // check for right driver type |
718 | 718 | ||
719 | if (texture && texture->getDriverType() != EDT_DIRECT3D8) | 719 | if (texture && texture->getDriverType() != EDT_DIRECT3D8) |
720 | { | 720 | { |
721 | os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); | 721 | os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); |
722 | return false; | 722 | return false; |
723 | } | 723 | } |
724 | 724 | ||
725 | // check for valid render target | 725 | // check for valid render target |
726 | 726 | ||
727 | CD3D8Texture* tex = (CD3D8Texture*)texture; | 727 | CD3D8Texture* tex = (CD3D8Texture*)texture; |
728 | 728 | ||
729 | if (texture && !tex->isRenderTarget()) | 729 | if (texture && !tex->isRenderTarget()) |
730 | { | 730 | { |
731 | os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); | 731 | os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR); |
732 | return false; | 732 | return false; |
733 | } | 733 | } |
734 | 734 | ||
735 | if (texture && (tex->getSize().Width > ScreenSize.Width || | 735 | if (texture && (tex->getSize().Width > ScreenSize.Width || |
736 | tex->getSize().Height > ScreenSize.Height )) | 736 | tex->getSize().Height > ScreenSize.Height )) |
737 | { | 737 | { |
738 | os::Printer::log("Error: Tried to set a render target texture which is bigger than the screen.", ELL_ERROR); | 738 | os::Printer::log("Error: Tried to set a render target texture which is bigger than the screen.", ELL_ERROR); |
739 | return false; | 739 | return false; |
740 | } | 740 | } |
741 | 741 | ||
742 | // check if we should set the previous RT back | 742 | // check if we should set the previous RT back |
743 | 743 | ||
744 | bool ret = true; | 744 | bool ret = true; |
745 | 745 | ||
746 | if (tex == 0) | 746 | if (tex == 0) |
747 | { | 747 | { |
748 | if (PrevRenderTarget) | 748 | if (PrevRenderTarget) |
749 | { | 749 | { |
750 | IDirect3DSurface8* dss = 0; | 750 | IDirect3DSurface8* dss = 0; |
751 | pID3DDevice->GetDepthStencilSurface(&dss); | 751 | pID3DDevice->GetDepthStencilSurface(&dss); |
752 | 752 | ||
753 | if (FAILED(pID3DDevice->SetRenderTarget(PrevRenderTarget, dss))) | 753 | if (FAILED(pID3DDevice->SetRenderTarget(PrevRenderTarget, dss))) |
754 | { | 754 | { |
755 | os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); | 755 | os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR); |
756 | ret = false; | 756 | ret = false; |
757 | } | 757 | } |
758 | 758 | ||
759 | if (dss) | 759 | if (dss) |
760 | dss->Release(); | 760 | dss->Release(); |
761 | 761 | ||
762 | CurrentRendertargetSize = core::dimension2d<u32>(0,0); | 762 | CurrentRendertargetSize = core::dimension2d<u32>(0,0); |
763 | PrevRenderTarget->Release(); | 763 | PrevRenderTarget->Release(); |
764 | PrevRenderTarget = 0; | 764 | PrevRenderTarget = 0; |
765 | } | 765 | } |
766 | } | 766 | } |
767 | else | 767 | else |
768 | { | 768 | { |
769 | // we want to set a new target. so do this. | 769 | // we want to set a new target. so do this. |
770 | 770 | ||
771 | // store previous target | 771 | // store previous target |
772 | 772 | ||
773 | if (!PrevRenderTarget && (FAILED(pID3DDevice->GetRenderTarget(&PrevRenderTarget)))) | 773 | if (!PrevRenderTarget && (FAILED(pID3DDevice->GetRenderTarget(&PrevRenderTarget)))) |
774 | { | 774 | { |
775 | os::Printer::log("Could not get previous render target.", ELL_ERROR); | 775 | os::Printer::log("Could not get previous render target.", ELL_ERROR); |
776 | return false; | 776 | return false; |
777 | } | 777 | } |
778 | 778 | ||
779 | // set new render target | 779 | // set new render target |
780 | 780 | ||
781 | IDirect3DSurface8* dss = 0; | 781 | IDirect3DSurface8* dss = 0; |
782 | pID3DDevice->GetDepthStencilSurface(&dss); | 782 | pID3DDevice->GetDepthStencilSurface(&dss); |
783 | 783 | ||
784 | if (FAILED(pID3DDevice->SetRenderTarget(tex->getRenderTargetSurface(), dss))) | 784 | if (FAILED(pID3DDevice->SetRenderTarget(tex->getRenderTargetSurface(), dss))) |
785 | { | 785 | { |
786 | os::Printer::log("Error: Could not set render target.", ELL_ERROR); | 786 | os::Printer::log("Error: Could not set render target.", ELL_ERROR); |
787 | ret = false; | 787 | ret = false; |
788 | } | 788 | } |
789 | 789 | ||
790 | if (dss) | 790 | if (dss) |
791 | dss->Release(); | 791 | dss->Release(); |
792 | 792 | ||
793 | CurrentRendertargetSize = tex->getSize(); | 793 | CurrentRendertargetSize = tex->getSize(); |
794 | } | 794 | } |
795 | Transformation3DChanged = true; | 795 | Transformation3DChanged = true; |
796 | 796 | ||
797 | if (clearBackBuffer || clearZBuffer) | 797 | if (clearBackBuffer || clearZBuffer) |
798 | { | 798 | { |
799 | DWORD flags = 0; | 799 | DWORD flags = 0; |
800 | 800 | ||
801 | if (clearBackBuffer) | 801 | if (clearBackBuffer) |
802 | flags |= D3DCLEAR_TARGET; | 802 | flags |= D3DCLEAR_TARGET; |
803 | 803 | ||
804 | if (clearZBuffer) | 804 | if (clearZBuffer) |
805 | flags |= D3DCLEAR_ZBUFFER; | 805 | flags |= D3DCLEAR_ZBUFFER; |
806 | 806 | ||
807 | pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); | 807 | pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0); |
808 | } | 808 | } |
809 | 809 | ||
810 | return ret; | 810 | return ret; |
811 | } | 811 | } |
812 | 812 | ||
813 | 813 | ||
814 | //! Creates a render target texture. | 814 | //! Creates a render target texture. |
815 | ITexture* CD3D8Driver::addRenderTargetTexture( | 815 | ITexture* CD3D8Driver::addRenderTargetTexture( |
816 | const core::dimension2d<u32>& size, const io::path& name, | 816 | const core::dimension2d<u32>& size, const io::path& name, |
817 | const ECOLOR_FORMAT format) | 817 | const ECOLOR_FORMAT format) |
818 | { | 818 | { |
819 | CD3D8Texture* tex = new CD3D8Texture(this, size, name); | 819 | CD3D8Texture* tex = new CD3D8Texture(this, size, name); |
820 | if (tex) | 820 | if (tex) |
821 | { | 821 | { |
822 | if (!tex->Texture) | 822 | if (!tex->Texture) |
823 | { | 823 | { |
824 | tex->drop(); | 824 | tex->drop(); |
825 | return 0; | 825 | return 0; |
826 | } | 826 | } |
827 | addTexture(tex); | 827 | addTexture(tex); |
828 | tex->drop(); | 828 | tex->drop(); |
829 | } | 829 | } |
830 | return tex; | 830 | return tex; |
831 | } | 831 | } |
832 | 832 | ||
833 | 833 | ||
834 | //! sets a viewport | 834 | //! sets a viewport |
835 | void CD3D8Driver::setViewPort(const core::rect<s32>& area) | 835 | void CD3D8Driver::setViewPort(const core::rect<s32>& area) |
836 | { | 836 | { |
837 | core::rect<s32> vp(area); | 837 | core::rect<s32> vp(area); |
838 | core::rect<s32> rendert(0,0, ScreenSize.Width, ScreenSize.Height); | 838 | core::rect<s32> rendert(0,0, ScreenSize.Width, ScreenSize.Height); |
839 | vp.clipAgainst(rendert); | 839 | vp.clipAgainst(rendert); |
840 | 840 | ||
841 | D3DVIEWPORT8 viewPort; | 841 | D3DVIEWPORT8 viewPort; |
842 | viewPort.X = vp.UpperLeftCorner.X; | 842 | viewPort.X = vp.UpperLeftCorner.X; |
843 | viewPort.Y = vp.UpperLeftCorner.Y; | 843 | viewPort.Y = vp.UpperLeftCorner.Y; |
844 | viewPort.Width = vp.getWidth(); | 844 | viewPort.Width = vp.getWidth(); |
845 | viewPort.Height = vp.getHeight(); | 845 | viewPort.Height = vp.getHeight(); |
846 | viewPort.MinZ = 0.0f; | 846 | viewPort.MinZ = 0.0f; |
847 | viewPort.MaxZ = 1.0f; | 847 | viewPort.MaxZ = 1.0f; |
848 | 848 | ||
849 | HRESULT hr = D3DERR_INVALIDCALL; | 849 | HRESULT hr = D3DERR_INVALIDCALL; |
850 | if (vp.getHeight()>0 && vp.getWidth()>0) | 850 | if (vp.getHeight()>0 && vp.getWidth()>0) |
851 | hr = pID3DDevice->SetViewport(&viewPort); | 851 | hr = pID3DDevice->SetViewport(&viewPort); |
852 | 852 | ||
853 | if (FAILED(hr)) | 853 | if (FAILED(hr)) |
854 | os::Printer::log("Failed setting the viewport.", ELL_WARNING); | 854 | os::Printer::log("Failed setting the viewport.", ELL_WARNING); |
855 | 855 | ||
856 | ViewPort = vp; | 856 | ViewPort = vp; |
857 | } | 857 | } |
858 | 858 | ||
859 | 859 | ||
860 | //! gets the area of the current viewport | 860 | //! gets the area of the current viewport |
861 | const core::rect<s32>& CD3D8Driver::getViewPort() const | 861 | const core::rect<s32>& CD3D8Driver::getViewPort() const |
862 | { | 862 | { |
863 | return ViewPort; | 863 | return ViewPort; |
864 | } | 864 | } |
865 | 865 | ||
866 | 866 | ||
867 | //! draws a vertex primitive list | 867 | //! draws a vertex primitive list |
868 | void CD3D8Driver::drawVertexPrimitiveList(const void* vertices, | 868 | void CD3D8Driver::drawVertexPrimitiveList(const void* vertices, |
869 | u32 vertexCount, const void* indexList, u32 primitiveCount, | 869 | u32 vertexCount, const void* indexList, u32 primitiveCount, |
870 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, | 870 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, |
871 | E_INDEX_TYPE iType) | 871 | E_INDEX_TYPE iType) |
872 | { | 872 | { |
873 | if (!checkPrimitiveCount(primitiveCount)) | 873 | if (!checkPrimitiveCount(primitiveCount)) |
874 | return; | 874 | return; |
875 | 875 | ||
876 | CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); | 876 | CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); |
877 | 877 | ||
878 | if (!vertexCount || !primitiveCount) | 878 | if (!vertexCount || !primitiveCount) |
879 | return; | 879 | return; |
880 | 880 | ||
881 | draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, | 881 | draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, |
882 | vType, pType, iType, true); | 882 | vType, pType, iType, true); |
883 | } | 883 | } |
884 | 884 | ||
885 | 885 | ||
886 | //! draws a vertex primitive list in 2d | 886 | //! draws a vertex primitive list in 2d |
887 | void CD3D8Driver::draw2DVertexPrimitiveList(const void* vertices, | 887 | void CD3D8Driver::draw2DVertexPrimitiveList(const void* vertices, |
888 | u32 vertexCount, const void* indexList, u32 primitiveCount, | 888 | u32 vertexCount, const void* indexList, u32 primitiveCount, |
889 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, | 889 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, |
890 | E_INDEX_TYPE iType) | 890 | E_INDEX_TYPE iType) |
891 | { | 891 | { |
892 | if (!checkPrimitiveCount(primitiveCount)) | 892 | if (!checkPrimitiveCount(primitiveCount)) |
893 | return; | 893 | return; |
894 | 894 | ||
895 | CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); | 895 | CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType,iType); |
896 | 896 | ||
897 | if (!vertexCount || !primitiveCount) | 897 | if (!vertexCount || !primitiveCount) |
898 | return; | 898 | return; |
899 | 899 | ||
900 | draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, | 900 | draw2D3DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, |
901 | vType, pType, iType, false); | 901 | vType, pType, iType, false); |
902 | } | 902 | } |
903 | 903 | ||
904 | 904 | ||
905 | void CD3D8Driver::draw2D3DVertexPrimitiveList(const void* vertices, | 905 | void CD3D8Driver::draw2D3DVertexPrimitiveList(const void* vertices, |
906 | u32 vertexCount, const void* indexList, u32 primitiveCount, | 906 | u32 vertexCount, const void* indexList, u32 primitiveCount, |
907 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, | 907 | E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, |
908 | E_INDEX_TYPE iType, bool is3D) | 908 | E_INDEX_TYPE iType, bool is3D) |
909 | { | 909 | { |
910 | setVertexShader(vType); | 910 | setVertexShader(vType); |
911 | 911 | ||
912 | const u32 stride = getVertexPitchFromType(vType); | 912 | const u32 stride = getVertexPitchFromType(vType); |
913 | 913 | ||
914 | D3DFORMAT indexType=D3DFMT_UNKNOWN; | 914 | D3DFORMAT indexType=D3DFMT_UNKNOWN; |
915 | switch (iType) | 915 | switch (iType) |
916 | { | 916 | { |
917 | case (EIT_16BIT): | 917 | case (EIT_16BIT): |
918 | { | 918 | { |
919 | indexType=D3DFMT_INDEX16; | 919 | indexType=D3DFMT_INDEX16; |
920 | break; | 920 | break; |
921 | } | 921 | } |
922 | case (EIT_32BIT): | 922 | case (EIT_32BIT): |
923 | { | 923 | { |
924 | indexType=D3DFMT_INDEX32; | 924 | indexType=D3DFMT_INDEX32; |
925 | break; | 925 | break; |
926 | } | 926 | } |
927 | } | 927 | } |
928 | 928 | ||
929 | if (is3D) | 929 | if (is3D) |
930 | { | 930 | { |
931 | if (!setRenderStates3DMode()) | 931 | if (!setRenderStates3DMode()) |
932 | return; | 932 | return; |
933 | } | 933 | } |
934 | else | 934 | else |
935 | { | 935 | { |
936 | if (Material.MaterialType==EMT_ONETEXTURE_BLEND) | 936 | if (Material.MaterialType==EMT_ONETEXTURE_BLEND) |
937 | { | 937 | { |
938 | E_BLEND_FACTOR srcFact; | 938 | E_BLEND_FACTOR srcFact; |
939 | E_BLEND_FACTOR dstFact; | 939 | E_BLEND_FACTOR dstFact; |
940 | E_MODULATE_FUNC modulo; | 940 | E_MODULATE_FUNC modulo; |
941 | u32 alphaSource; | 941 | u32 alphaSource; |
942 | unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); | 942 | unpack_textureBlendFunc ( srcFact, dstFact, modulo, alphaSource, Material.MaterialTypeParam); |
943 | setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); | 943 | setRenderStates2DMode(alphaSource&video::EAS_VERTEX_COLOR, (Material.getTexture(0) != 0), (alphaSource&video::EAS_TEXTURE) != 0); |
944 | } | 944 | } |
945 | else | 945 | else |
946 | setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); | 946 | setRenderStates2DMode(Material.MaterialType==EMT_TRANSPARENT_VERTEX_ALPHA, (Material.getTexture(0) != 0), Material.MaterialType==EMT_TRANSPARENT_ALPHA_CHANNEL); |
947 | } | 947 | } |
948 | 948 | ||
949 | switch (pType) | 949 | switch (pType) |
950 | { | 950 | { |
951 | case scene::EPT_POINT_SPRITES: | 951 | case scene::EPT_POINT_SPRITES: |
952 | case scene::EPT_POINTS: | 952 | case scene::EPT_POINTS: |
953 | { | 953 | { |
954 | f32 tmp=Material.Thickness/getScreenSize().Height; | 954 | f32 tmp=Material.Thickness/getScreenSize().Height; |
955 | if (pType==scene::EPT_POINT_SPRITES) | 955 | if (pType==scene::EPT_POINT_SPRITES) |
956 | pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); | 956 | pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); |
957 | pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); | 957 | pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); |
958 | pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&tmp)); | 958 | pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&tmp)); |
959 | tmp=1.0f; | 959 | tmp=1.0f; |
960 | pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp)); | 960 | pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp)); |
961 | pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp)); | 961 | pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp)); |
962 | pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp)); | 962 | pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp)); |
963 | tmp=0.0f; | 963 | tmp=0.0f; |
964 | pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp)); | 964 | pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp)); |
965 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, | 965 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_POINTLIST, 0, vertexCount, |
966 | primitiveCount, indexList, indexType, vertices, stride); | 966 | primitiveCount, indexList, indexType, vertices, stride); |
967 | pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); | 967 | pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE); |
968 | if (pType==scene::EPT_POINT_SPRITES) | 968 | if (pType==scene::EPT_POINT_SPRITES) |
969 | pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); | 969 | pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE); |
970 | } | 970 | } |
971 | break; | 971 | break; |
972 | case scene::EPT_LINE_STRIP: | 972 | case scene::EPT_LINE_STRIP: |
973 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, | 973 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, |
974 | primitiveCount, indexList, indexType, vertices, stride); | 974 | primitiveCount, indexList, indexType, vertices, stride); |
975 | break; | 975 | break; |
976 | case scene::EPT_LINE_LOOP: | 976 | case scene::EPT_LINE_LOOP: |
977 | { | 977 | { |
978 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, | 978 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINESTRIP, 0, vertexCount, |
979 | primitiveCount - 1, indexList, indexType, vertices, stride); | 979 | primitiveCount - 1, indexList, indexType, vertices, stride); |
980 | u16 tmpIndices[] = {primitiveCount - 1, 0}; | 980 | u16 tmpIndices[] = {primitiveCount - 1, 0}; |
981 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, | 981 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, |
982 | 1, tmpIndices, indexType, vertices, stride); | 982 | 1, tmpIndices, indexType, vertices, stride); |
983 | } | 983 | } |
984 | break; | 984 | break; |
985 | case scene::EPT_LINES: | 985 | case scene::EPT_LINES: |
986 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, | 986 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST, 0, vertexCount, |
987 | primitiveCount, indexList, indexType, vertices, stride); | 987 | primitiveCount, indexList, indexType, vertices, stride); |
988 | break; | 988 | break; |
989 | case scene::EPT_TRIANGLE_STRIP: | 989 | case scene::EPT_TRIANGLE_STRIP: |
990 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, | 990 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLESTRIP, 0, vertexCount, |
991 | primitiveCount, indexList, indexType, vertices, stride); | 991 | primitiveCount, indexList, indexType, vertices, stride); |
992 | break; | 992 | break; |
993 | case scene::EPT_TRIANGLE_FAN: | 993 | case scene::EPT_TRIANGLE_FAN: |
994 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, | 994 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLEFAN, 0, vertexCount, |
995 | primitiveCount, indexList, indexType, vertices, stride); | 995 | primitiveCount, indexList, indexType, vertices, stride); |
996 | break; | 996 | break; |
997 | case scene::EPT_TRIANGLES: | 997 | case scene::EPT_TRIANGLES: |
998 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, | 998 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, vertexCount, |
999 | primitiveCount, indexList, indexType, vertices, stride); | 999 | primitiveCount, indexList, indexType, vertices, stride); |
1000 | break; | 1000 | break; |
1001 | } | 1001 | } |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | 1004 | ||
1005 | //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. | 1005 | //! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted. |
1006 | void CD3D8Driver::draw2DImage(const video::ITexture* texture, | 1006 | void CD3D8Driver::draw2DImage(const video::ITexture* texture, |
1007 | const core::position2d<s32>& pos, | 1007 | const core::position2d<s32>& pos, |
1008 | const core::rect<s32>& sourceRect, | 1008 | const core::rect<s32>& sourceRect, |
1009 | const core::rect<s32>* clipRect, SColor color, | 1009 | const core::rect<s32>* clipRect, SColor color, |
1010 | bool useAlphaChannelOfTexture) | 1010 | bool useAlphaChannelOfTexture) |
1011 | { | 1011 | { |
1012 | if (!texture) | 1012 | if (!texture) |
1013 | return; | 1013 | return; |
1014 | 1014 | ||
1015 | if (!sourceRect.isValid()) | 1015 | if (!sourceRect.isValid()) |
1016 | return; | 1016 | return; |
1017 | 1017 | ||
1018 | if (!setActiveTexture(0, texture)) | 1018 | if (!setActiveTexture(0, texture)) |
1019 | return; | 1019 | return; |
1020 | 1020 | ||
1021 | core::position2d<s32> targetPos = pos; | 1021 | core::position2d<s32> targetPos = pos; |
1022 | core::position2d<s32> sourcePos = sourceRect.UpperLeftCorner; | 1022 | core::position2d<s32> sourcePos = sourceRect.UpperLeftCorner; |
1023 | // This needs to be signed as it may go negative. | 1023 | // This needs to be signed as it may go negative. |
1024 | core::dimension2d<s32> sourceSize(sourceRect.getSize()); | 1024 | core::dimension2d<s32> sourceSize(sourceRect.getSize()); |
1025 | const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); | 1025 | const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); |
1026 | 1026 | ||
1027 | if (clipRect) | 1027 | if (clipRect) |
1028 | { | 1028 | { |
1029 | if (targetPos.X < clipRect->UpperLeftCorner.X) | 1029 | if (targetPos.X < clipRect->UpperLeftCorner.X) |
1030 | { | 1030 | { |
1031 | sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; | 1031 | sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X; |
1032 | if (sourceSize.Width <= 0) | 1032 | if (sourceSize.Width <= 0) |
1033 | return; | 1033 | return; |
1034 | 1034 | ||
1035 | sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; | 1035 | sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X; |
1036 | targetPos.X = clipRect->UpperLeftCorner.X; | 1036 | targetPos.X = clipRect->UpperLeftCorner.X; |
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) | 1039 | if (targetPos.X + (s32)sourceSize.Width > clipRect->LowerRightCorner.X) |
1040 | { | 1040 | { |
1041 | sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; | 1041 | sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X; |
1042 | if (sourceSize.Width <= 0) | 1042 | if (sourceSize.Width <= 0) |
1043 | return; | 1043 | return; |
1044 | } | 1044 | } |
1045 | 1045 | ||
1046 | if (targetPos.Y < clipRect->UpperLeftCorner.Y) | 1046 | if (targetPos.Y < clipRect->UpperLeftCorner.Y) |
1047 | { | 1047 | { |
1048 | sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; | 1048 | sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y; |
1049 | if (sourceSize.Height <= 0) | 1049 | if (sourceSize.Height <= 0) |
1050 | return; | 1050 | return; |
1051 | 1051 | ||
1052 | sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; | 1052 | sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y; |
1053 | targetPos.Y = clipRect->UpperLeftCorner.Y; | 1053 | targetPos.Y = clipRect->UpperLeftCorner.Y; |
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) | 1056 | if (targetPos.Y + (s32)sourceSize.Height > clipRect->LowerRightCorner.Y) |
1057 | { | 1057 | { |
1058 | sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; | 1058 | sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y; |
1059 | if (sourceSize.Height <= 0) | 1059 | if (sourceSize.Height <= 0) |
1060 | return; | 1060 | return; |
1061 | } | 1061 | } |
1062 | } | 1062 | } |
1063 | 1063 | ||
1064 | // clip these coordinates | 1064 | // clip these coordinates |
1065 | 1065 | ||
1066 | if (targetPos.X<0) | 1066 | if (targetPos.X<0) |
1067 | { | 1067 | { |
1068 | sourceSize.Width += targetPos.X; | 1068 | sourceSize.Width += targetPos.X; |
1069 | if (sourceSize.Width <= 0) | 1069 | if (sourceSize.Width <= 0) |
1070 | return; | 1070 | return; |
1071 | 1071 | ||
1072 | sourcePos.X -= targetPos.X; | 1072 | sourcePos.X -= targetPos.X; |
1073 | targetPos.X = 0; | 1073 | targetPos.X = 0; |
1074 | } | 1074 | } |
1075 | 1075 | ||
1076 | if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) | 1076 | if (targetPos.X + sourceSize.Width > (s32)renderTargetSize.Width) |
1077 | { | 1077 | { |
1078 | sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; | 1078 | sourceSize.Width -= (targetPos.X + sourceSize.Width) - renderTargetSize.Width; |
1079 | if (sourceSize.Width <= 0) | 1079 | if (sourceSize.Width <= 0) |
1080 | return; | 1080 | return; |
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | if (targetPos.Y<0) | 1083 | if (targetPos.Y<0) |
1084 | { | 1084 | { |
1085 | sourceSize.Height += targetPos.Y; | 1085 | sourceSize.Height += targetPos.Y; |
1086 | if (sourceSize.Height <= 0) | 1086 | if (sourceSize.Height <= 0) |
1087 | return; | 1087 | return; |
1088 | 1088 | ||
1089 | sourcePos.Y -= targetPos.Y; | 1089 | sourcePos.Y -= targetPos.Y; |
1090 | targetPos.Y = 0; | 1090 | targetPos.Y = 0; |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) | 1093 | if (targetPos.Y + sourceSize.Height > (s32)renderTargetSize.Height) |
1094 | { | 1094 | { |
1095 | sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; | 1095 | sourceSize.Height -= (targetPos.Y + sourceSize.Height) - renderTargetSize.Height; |
1096 | if (sourceSize.Height <= 0) | 1096 | if (sourceSize.Height <= 0) |
1097 | return; | 1097 | return; |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | // ok, we've clipped everything. | 1100 | // ok, we've clipped everything. |
1101 | // now draw it. | 1101 | // now draw it. |
1102 | 1102 | ||
1103 | core::rect<f32> tcoords; | 1103 | core::rect<f32> tcoords; |
1104 | tcoords.UpperLeftCorner.X = (f32)sourcePos.X / texture->getOriginalSize().Width ; | 1104 | tcoords.UpperLeftCorner.X = (f32)sourcePos.X / texture->getOriginalSize().Width ; |
1105 | tcoords.UpperLeftCorner.Y = (f32)sourcePos.Y / texture->getOriginalSize().Height; | 1105 | tcoords.UpperLeftCorner.Y = (f32)sourcePos.Y / texture->getOriginalSize().Height; |
1106 | tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + (f32)sourceSize.Width / texture->getOriginalSize().Width; | 1106 | tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + (f32)sourceSize.Width / texture->getOriginalSize().Width; |
1107 | tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + (f32)sourceSize.Height / texture->getOriginalSize().Height; | 1107 | tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + (f32)sourceSize.Height / texture->getOriginalSize().Height; |
1108 | 1108 | ||
1109 | const core::rect<s32> poss(targetPos, sourceSize); | 1109 | const core::rect<s32> poss(targetPos, sourceSize); |
1110 | 1110 | ||
1111 | setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); | 1111 | setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); |
1112 | 1112 | ||
1113 | S3DVertex vtx[4]; | 1113 | S3DVertex vtx[4]; |
1114 | vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, | 1114 | vtx[0] = S3DVertex((f32)poss.UpperLeftCorner.X, |
1115 | (f32)poss.UpperLeftCorner.Y, 0.0f, | 1115 | (f32)poss.UpperLeftCorner.Y, 0.0f, |
1116 | 0.0f, 0.0f, 0.0f, color, | 1116 | 0.0f, 0.0f, 0.0f, color, |
1117 | tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); | 1117 | tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); |
1118 | vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, | 1118 | vtx[1] = S3DVertex((f32)poss.LowerRightCorner.X, |
1119 | (f32)poss.UpperLeftCorner.Y, 0.0f, | 1119 | (f32)poss.UpperLeftCorner.Y, 0.0f, |
1120 | 0.0f, 0.0f, 0.0f, color, | 1120 | 0.0f, 0.0f, 0.0f, color, |
1121 | tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); | 1121 | tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); |
1122 | vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, | 1122 | vtx[2] = S3DVertex((f32)poss.LowerRightCorner.X, |
1123 | (f32)poss.LowerRightCorner.Y, 0.0f, | 1123 | (f32)poss.LowerRightCorner.Y, 0.0f, |
1124 | 0.0f, 0.0f, 0.0f, color, | 1124 | 0.0f, 0.0f, 0.0f, color, |
1125 | tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); | 1125 | tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); |
1126 | vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, | 1126 | vtx[3] = S3DVertex((f32)poss.UpperLeftCorner.X, |
1127 | (f32)poss.LowerRightCorner.Y, 0.0f, | 1127 | (f32)poss.LowerRightCorner.Y, 0.0f, |
1128 | 0.0f, 0.0f, 0.0f, color, | 1128 | 0.0f, 0.0f, 0.0f, color, |
1129 | tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); | 1129 | tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); |
1130 | 1130 | ||
1131 | const s16 indices[6] = {0,1,2,0,2,3}; | 1131 | const s16 indices[6] = {0,1,2,0,2,3}; |
1132 | 1132 | ||
1133 | setVertexShader(EVT_STANDARD); | 1133 | setVertexShader(EVT_STANDARD); |
1134 | 1134 | ||
1135 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], | 1135 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], |
1136 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); | 1136 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); |
1137 | } | 1137 | } |
1138 | 1138 | ||
1139 | 1139 | ||
1140 | void CD3D8Driver::draw2DImage(const video::ITexture* texture, | 1140 | void CD3D8Driver::draw2DImage(const video::ITexture* texture, |
1141 | const core::rect<s32>& destRect, | 1141 | const core::rect<s32>& destRect, |
1142 | const core::rect<s32>& sourceRect, | 1142 | const core::rect<s32>& sourceRect, |
1143 | const core::rect<s32>* clipRect, | 1143 | const core::rect<s32>* clipRect, |
1144 | const video::SColor* const colors, | 1144 | const video::SColor* const colors, |
1145 | bool useAlphaChannelOfTexture) | 1145 | bool useAlphaChannelOfTexture) |
1146 | { | 1146 | { |
1147 | if(!texture) | 1147 | if(!texture) |
1148 | return; | 1148 | return; |
1149 | 1149 | ||
1150 | const core::dimension2d<u32>& ss = texture->getOriginalSize(); | 1150 | const core::dimension2d<u32>& ss = texture->getOriginalSize(); |
1151 | core::rect<f32> tcoords; | 1151 | core::rect<f32> tcoords; |
1152 | tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; | 1152 | tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; |
1153 | tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; | 1153 | tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; |
1154 | tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; | 1154 | tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width; |
1155 | tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; | 1155 | tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height; |
1156 | 1156 | ||
1157 | core::rect<s32> clippedRect(destRect); | 1157 | core::rect<s32> clippedRect(destRect); |
1158 | if (clipRect) | 1158 | if (clipRect) |
1159 | { | 1159 | { |
1160 | clippedRect.clipAgainst(*clipRect); | 1160 | clippedRect.clipAgainst(*clipRect); |
1161 | 1161 | ||
1162 | //tcoords must be clipped by the same factors | 1162 | //tcoords must be clipped by the same factors |
1163 | const f32 tcWidth = tcoords.getWidth(); | 1163 | const f32 tcWidth = tcoords.getWidth(); |
1164 | const f32 tcHeight = tcoords.getHeight(); | 1164 | const f32 tcHeight = tcoords.getHeight(); |
1165 | 1165 | ||
1166 | const f32 invDestRectWidth = 1.f / (f32)(destRect.getWidth()); | 1166 | const f32 invDestRectWidth = 1.f / (f32)(destRect.getWidth()); |
1167 | f32 scale = (f32)(clippedRect.UpperLeftCorner.X - destRect.UpperLeftCorner.X) * invDestRectWidth; | 1167 | f32 scale = (f32)(clippedRect.UpperLeftCorner.X - destRect.UpperLeftCorner.X) * invDestRectWidth; |
1168 | tcoords.UpperLeftCorner.X += scale * tcWidth; | 1168 | tcoords.UpperLeftCorner.X += scale * tcWidth; |
1169 | scale = (f32)(destRect.LowerRightCorner.X - clippedRect.LowerRightCorner.X) * invDestRectWidth; | 1169 | scale = (f32)(destRect.LowerRightCorner.X - clippedRect.LowerRightCorner.X) * invDestRectWidth; |
1170 | tcoords.LowerRightCorner.X -= scale * tcWidth; | 1170 | tcoords.LowerRightCorner.X -= scale * tcWidth; |
1171 | 1171 | ||
1172 | const f32 invDestRectHeight = 1.f / (f32)(destRect.getHeight()); | 1172 | const f32 invDestRectHeight = 1.f / (f32)(destRect.getHeight()); |
1173 | scale = (f32)(clippedRect.UpperLeftCorner.Y - destRect.UpperLeftCorner.Y) * invDestRectHeight; | 1173 | scale = (f32)(clippedRect.UpperLeftCorner.Y - destRect.UpperLeftCorner.Y) * invDestRectHeight; |
1174 | tcoords.UpperLeftCorner.Y += scale * tcHeight; | 1174 | tcoords.UpperLeftCorner.Y += scale * tcHeight; |
1175 | scale = (f32)(destRect.LowerRightCorner.Y - clippedRect.LowerRightCorner.Y) * invDestRectHeight; | 1175 | scale = (f32)(destRect.LowerRightCorner.Y - clippedRect.LowerRightCorner.Y) * invDestRectHeight; |
1176 | tcoords.LowerRightCorner.Y -= scale * tcHeight; | 1176 | tcoords.LowerRightCorner.Y -= scale * tcHeight; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | const video::SColor temp[4] = | 1179 | const video::SColor temp[4] = |
1180 | { | 1180 | { |
1181 | 0xFFFFFFFF, | 1181 | 0xFFFFFFFF, |
1182 | 0xFFFFFFFF, | 1182 | 0xFFFFFFFF, |
1183 | 0xFFFFFFFF, | 1183 | 0xFFFFFFFF, |
1184 | 0xFFFFFFFF | 1184 | 0xFFFFFFFF |
1185 | }; | 1185 | }; |
1186 | 1186 | ||
1187 | const video::SColor* const useColor = colors ? colors : temp; | 1187 | const video::SColor* const useColor = colors ? colors : temp; |
1188 | 1188 | ||
1189 | S3DVertex vtx[4]; // clock wise | 1189 | S3DVertex vtx[4]; // clock wise |
1190 | vtx[0] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, | 1190 | vtx[0] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, |
1191 | 0.0f, 0.0f, 0.0f, useColor[0], | 1191 | 0.0f, 0.0f, 0.0f, useColor[0], |
1192 | tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); | 1192 | tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y); |
1193 | vtx[1] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, | 1193 | vtx[1] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.UpperLeftCorner.Y, 0.0f, |
1194 | 0.0f, 0.0f, 0.0f, useColor[3], | 1194 | 0.0f, 0.0f, 0.0f, useColor[3], |
1195 | tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); | 1195 | tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y); |
1196 | vtx[2] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, | 1196 | vtx[2] = S3DVertex((f32)clippedRect.LowerRightCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, |
1197 | 0.0f, 0.0f, 0.0f, useColor[2], | 1197 | 0.0f, 0.0f, 0.0f, useColor[2], |
1198 | tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); | 1198 | tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y); |
1199 | vtx[3] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, | 1199 | vtx[3] = S3DVertex((f32)clippedRect.UpperLeftCorner.X, (f32)clippedRect.LowerRightCorner.Y, 0.0f, |
1200 | 0.0f, 0.0f, 0.0f, useColor[1], | 1200 | 0.0f, 0.0f, 0.0f, useColor[1], |
1201 | tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); | 1201 | tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y); |
1202 | 1202 | ||
1203 | const s16 indices[6] = {0,1,2,0,2,3}; | 1203 | const s16 indices[6] = {0,1,2,0,2,3}; |
1204 | 1204 | ||
1205 | setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || | 1205 | setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || |
1206 | useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, | 1206 | useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, |
1207 | true, useAlphaChannelOfTexture); | 1207 | true, useAlphaChannelOfTexture); |
1208 | 1208 | ||
1209 | setActiveTexture(0, texture); | 1209 | setActiveTexture(0, texture); |
1210 | 1210 | ||
1211 | setVertexShader(EVT_STANDARD); | 1211 | setVertexShader(EVT_STANDARD); |
1212 | 1212 | ||
1213 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], | 1213 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], |
1214 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); | 1214 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); |
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | 1217 | ||
1218 | //!Draws an 2d rectangle with a gradient. | 1218 | //!Draws an 2d rectangle with a gradient. |
1219 | void CD3D8Driver::draw2DRectangle(const core::rect<s32>& position, | 1219 | void CD3D8Driver::draw2DRectangle(const core::rect<s32>& position, |
1220 | SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, | 1220 | SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, |
1221 | SColor colorRightDown, const core::rect<s32>* clip) | 1221 | SColor colorRightDown, const core::rect<s32>* clip) |
1222 | { | 1222 | { |
1223 | core::rect<s32> pos(position); | 1223 | core::rect<s32> pos(position); |
1224 | 1224 | ||
1225 | if (clip) | 1225 | if (clip) |
1226 | pos.clipAgainst(*clip); | 1226 | pos.clipAgainst(*clip); |
1227 | 1227 | ||
1228 | if (!pos.isValid()) | 1228 | if (!pos.isValid()) |
1229 | return; | 1229 | return; |
1230 | 1230 | ||
1231 | S3DVertex vtx[4]; | 1231 | S3DVertex vtx[4]; |
1232 | vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, | 1232 | vtx[0] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, |
1233 | 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); | 1233 | 0.0f, 0.0f, 0.0f, colorLeftUp, 0.0f, 0.0f); |
1234 | vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, | 1234 | vtx[1] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f, |
1235 | 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); | 1235 | 0.0f, 0.0f, 0.0f, colorRightUp, 0.0f, 1.0f); |
1236 | vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, | 1236 | vtx[2] = S3DVertex((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, |
1237 | 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); | 1237 | 0.0f, 0.0f, 0.0f, colorRightDown, 1.0f, 0.0f); |
1238 | vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, | 1238 | vtx[3] = S3DVertex((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f, |
1239 | 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); | 1239 | 0.0f, 0.0f, 0.0f, colorLeftDown, 1.0f, 1.0f); |
1240 | 1240 | ||
1241 | const s16 indices[6] = {0,1,2,0,2,3}; | 1241 | const s16 indices[6] = {0,1,2,0,2,3}; |
1242 | 1242 | ||
1243 | setRenderStates2DMode( | 1243 | setRenderStates2DMode( |
1244 | colorLeftUp.getAlpha() < 255 || | 1244 | colorLeftUp.getAlpha() < 255 || |
1245 | colorRightUp.getAlpha() < 255 || | 1245 | colorRightUp.getAlpha() < 255 || |
1246 | colorLeftDown.getAlpha() < 255 || | 1246 | colorLeftDown.getAlpha() < 255 || |
1247 | colorRightDown.getAlpha() < 255, false, false); | 1247 | colorRightDown.getAlpha() < 255, false, false); |
1248 | 1248 | ||
1249 | setActiveTexture(0,0); | 1249 | setActiveTexture(0,0); |
1250 | 1250 | ||
1251 | setVertexShader(EVT_STANDARD); | 1251 | setVertexShader(EVT_STANDARD); |
1252 | 1252 | ||
1253 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], | 1253 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], |
1254 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); | 1254 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); |
1255 | } | 1255 | } |
1256 | 1256 | ||
1257 | 1257 | ||
1258 | //! Draws a 2d line. | 1258 | //! Draws a 2d line. |
1259 | void CD3D8Driver::draw2DLine(const core::position2d<s32>& start, | 1259 | void CD3D8Driver::draw2DLine(const core::position2d<s32>& start, |
1260 | const core::position2d<s32>& end, | 1260 | const core::position2d<s32>& end, |
1261 | SColor color) | 1261 | SColor color) |
1262 | { | 1262 | { |
1263 | if (start==end) | 1263 | if (start==end) |
1264 | drawPixel(start.X, start.Y, color); | 1264 | drawPixel(start.X, start.Y, color); |
1265 | else | 1265 | else |
1266 | { | 1266 | { |
1267 | // thanks to Vash TheStampede who sent in his implementation | 1267 | // thanks to Vash TheStampede who sent in his implementation |
1268 | S3DVertex vtx[2]; | 1268 | S3DVertex vtx[2]; |
1269 | vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f, | 1269 | vtx[0] = S3DVertex((f32)start.X+0.375f, (f32)start.Y+0.375f, 0.0f, |
1270 | 0.0f, 0.0f, 0.0f, // normal | 1270 | 0.0f, 0.0f, 0.0f, // normal |
1271 | color, 0.0f, 0.0f); // texture | 1271 | color, 0.0f, 0.0f); // texture |
1272 | 1272 | ||
1273 | vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f, | 1273 | vtx[1] = S3DVertex((f32)end.X+0.375f, (f32)end.Y+0.375f, 0.0f, |
1274 | 0.0f, 0.0f, 0.0f, | 1274 | 0.0f, 0.0f, 0.0f, |
1275 | color, 0.0f, 0.0f); | 1275 | color, 0.0f, 0.0f); |
1276 | 1276 | ||
1277 | setRenderStates2DMode(color.getAlpha() < 255, false, false); | 1277 | setRenderStates2DMode(color.getAlpha() < 255, false, false); |
1278 | setActiveTexture(0,0); | 1278 | setActiveTexture(0,0); |
1279 | 1279 | ||
1280 | setVertexShader(EVT_STANDARD); | 1280 | setVertexShader(EVT_STANDARD); |
1281 | 1281 | ||
1282 | pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &vtx[0], sizeof(S3DVertex)); | 1282 | pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, &vtx[0], sizeof(S3DVertex)); |
1283 | } | 1283 | } |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | 1286 | ||
1287 | //! Draws a pixel | 1287 | //! Draws a pixel |
1288 | void CD3D8Driver::drawPixel(u32 x, u32 y, const SColor & color) | 1288 | void CD3D8Driver::drawPixel(u32 x, u32 y, const SColor & color) |
1289 | { | 1289 | { |
1290 | const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); | 1290 | const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); |
1291 | if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) | 1291 | if (x > (u32)renderTargetSize.Width || y > (u32)renderTargetSize.Height) |
1292 | return; | 1292 | return; |
1293 | 1293 | ||
1294 | setRenderStates2DMode(color.getAlpha() < 255, false, false); | 1294 | setRenderStates2DMode(color.getAlpha() < 255, false, false); |
1295 | setActiveTexture(0,0); | 1295 | setActiveTexture(0,0); |
1296 | 1296 | ||
1297 | setVertexShader(EVT_STANDARD); | 1297 | setVertexShader(EVT_STANDARD); |
1298 | 1298 | ||
1299 | S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); | 1299 | S3DVertex vertex((f32)x+0.375f, (f32)y+0.375f, 0.f, 0.f, 0.f, 0.f, color, 0.f, 0.f); |
1300 | 1300 | ||
1301 | pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); | 1301 | pID3DDevice->DrawPrimitiveUP(D3DPT_POINTLIST, 1, &vertex, sizeof(vertex)); |
1302 | } | 1302 | } |
1303 | 1303 | ||
1304 | 1304 | ||
1305 | //! sets right vertex shader | 1305 | //! sets right vertex shader |
1306 | void CD3D8Driver::setVertexShader(E_VERTEX_TYPE newType) | 1306 | void CD3D8Driver::setVertexShader(E_VERTEX_TYPE newType) |
1307 | { | 1307 | { |
1308 | // Because we don't know if a vertex shader was set in a material instead of a | 1308 | // Because we don't know if a vertex shader was set in a material instead of a |
1309 | // fvf, this call cannot be prevented in D3D8. | 1309 | // fvf, this call cannot be prevented in D3D8. |
1310 | //if (newType != LastVertexType) | 1310 | //if (newType != LastVertexType) |
1311 | { | 1311 | { |
1312 | LastVertexType = newType; | 1312 | LastVertexType = newType; |
1313 | HRESULT hr = 0; | 1313 | HRESULT hr = 0; |
1314 | 1314 | ||
1315 | switch(newType) | 1315 | switch(newType) |
1316 | { | 1316 | { |
1317 | case EVT_STANDARD: | 1317 | case EVT_STANDARD: |
1318 | hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); | 1318 | hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1); |
1319 | break; | 1319 | break; |
1320 | case EVT_2TCOORDS: | 1320 | case EVT_2TCOORDS: |
1321 | hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); | 1321 | hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2); |
1322 | break; | 1322 | break; |
1323 | case EVT_TANGENTS: | 1323 | case EVT_TANGENTS: |
1324 | hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | | 1324 | hr = pID3DDevice->SetVertexShader(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX3 | |
1325 | D3DFVF_TEXCOORDSIZE2(0) | // real texture coord | 1325 | D3DFVF_TEXCOORDSIZE2(0) | // real texture coord |
1326 | D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent | 1326 | D3DFVF_TEXCOORDSIZE3(1) | // misuse texture coord 2 for tangent |
1327 | D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal | 1327 | D3DFVF_TEXCOORDSIZE3(2) // misuse texture coord 3 for binormal |
1328 | ); | 1328 | ); |
1329 | break; | 1329 | break; |
1330 | } | 1330 | } |
1331 | 1331 | ||
1332 | if (FAILED(hr)) | 1332 | if (FAILED(hr)) |
1333 | { | 1333 | { |
1334 | os::Printer::log("Could not set vertex Shader.", ELL_ERROR); | 1334 | os::Printer::log("Could not set vertex Shader.", ELL_ERROR); |
1335 | return; | 1335 | return; |
1336 | } | 1336 | } |
1337 | } | 1337 | } |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | 1340 | ||
1341 | //! sets the needed renderstates | 1341 | //! sets the needed renderstates |
1342 | bool CD3D8Driver::setRenderStates3DMode() | 1342 | bool CD3D8Driver::setRenderStates3DMode() |
1343 | { | 1343 | { |
1344 | if (!pID3DDevice) | 1344 | if (!pID3DDevice) |
1345 | return false; | 1345 | return false; |
1346 | 1346 | ||
1347 | if (CurrentRenderMode != ERM_3D) | 1347 | if (CurrentRenderMode != ERM_3D) |
1348 | { | 1348 | { |
1349 | // switch back the matrices | 1349 | // switch back the matrices |
1350 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); | 1350 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); |
1351 | pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); | 1351 | pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); |
1352 | pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); | 1352 | pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); |
1353 | 1353 | ||
1354 | pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); | 1354 | pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); |
1355 | 1355 | ||
1356 | ResetRenderStates = true; | 1356 | ResetRenderStates = true; |
1357 | } | 1357 | } |
1358 | 1358 | ||
1359 | if (ResetRenderStates || LastMaterial != Material) | 1359 | if (ResetRenderStates || LastMaterial != Material) |
1360 | { | 1360 | { |
1361 | // unset old material | 1361 | // unset old material |
1362 | 1362 | ||
1363 | if (CurrentRenderMode == ERM_3D && | 1363 | if (CurrentRenderMode == ERM_3D && |
1364 | LastMaterial.MaterialType != Material.MaterialType && | 1364 | LastMaterial.MaterialType != Material.MaterialType && |
1365 | LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) | 1365 | LastMaterial.MaterialType >= 0 && LastMaterial.MaterialType < (s32)MaterialRenderers.size()) |
1366 | MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); | 1366 | MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); |
1367 | 1367 | ||
1368 | // set new material. | 1368 | // set new material. |
1369 | 1369 | ||
1370 | if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) | 1370 | if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) |
1371 | MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( | 1371 | MaterialRenderers[Material.MaterialType].Renderer->OnSetMaterial( |
1372 | Material, LastMaterial, ResetRenderStates, this); | 1372 | Material, LastMaterial, ResetRenderStates, this); |
1373 | } | 1373 | } |
1374 | 1374 | ||
1375 | bool shaderOK = true; | 1375 | bool shaderOK = true; |
1376 | 1376 | ||
1377 | if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) | 1377 | if (Material.MaterialType >= 0 && Material.MaterialType < (s32)MaterialRenderers.size()) |
1378 | shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); | 1378 | shaderOK = MaterialRenderers[Material.MaterialType].Renderer->OnRender(this, LastVertexType); |
1379 | 1379 | ||
1380 | LastMaterial = Material; | 1380 | LastMaterial = Material; |
1381 | 1381 | ||
1382 | ResetRenderStates = false; | 1382 | ResetRenderStates = false; |
1383 | 1383 | ||
1384 | CurrentRenderMode = ERM_3D; | 1384 | CurrentRenderMode = ERM_3D; |
1385 | 1385 | ||
1386 | return shaderOK; | 1386 | return shaderOK; |
1387 | } | 1387 | } |
1388 | 1388 | ||
1389 | 1389 | ||
1390 | //! Map Irrlicht texture wrap mode to native values | 1390 | //! Map Irrlicht texture wrap mode to native values |
1391 | D3DTEXTUREADDRESS CD3D8Driver::getTextureWrapMode(const u8 clamp) | 1391 | D3DTEXTUREADDRESS CD3D8Driver::getTextureWrapMode(const u8 clamp) |
1392 | { | 1392 | { |
1393 | switch (clamp) | 1393 | switch (clamp) |
1394 | { | 1394 | { |
1395 | case ETC_REPEAT: | 1395 | case ETC_REPEAT: |
1396 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP) | 1396 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_WRAP) |
1397 | return D3DTADDRESS_WRAP; | 1397 | return D3DTADDRESS_WRAP; |
1398 | case ETC_CLAMP: | 1398 | case ETC_CLAMP: |
1399 | case ETC_CLAMP_TO_EDGE: | 1399 | case ETC_CLAMP_TO_EDGE: |
1400 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) | 1400 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_CLAMP) |
1401 | return D3DTADDRESS_CLAMP; | 1401 | return D3DTADDRESS_CLAMP; |
1402 | case ETC_MIRROR: | 1402 | case ETC_MIRROR: |
1403 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) | 1403 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRROR) |
1404 | return D3DTADDRESS_MIRROR; | 1404 | return D3DTADDRESS_MIRROR; |
1405 | case ETC_CLAMP_TO_BORDER: | 1405 | case ETC_CLAMP_TO_BORDER: |
1406 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) | 1406 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_BORDER) |
1407 | return D3DTADDRESS_BORDER; | 1407 | return D3DTADDRESS_BORDER; |
1408 | else | 1408 | else |
1409 | return D3DTADDRESS_CLAMP; | 1409 | return D3DTADDRESS_CLAMP; |
1410 | case ETC_MIRROR_CLAMP: | 1410 | case ETC_MIRROR_CLAMP: |
1411 | case ETC_MIRROR_CLAMP_TO_EDGE: | 1411 | case ETC_MIRROR_CLAMP_TO_EDGE: |
1412 | case ETC_MIRROR_CLAMP_TO_BORDER: | 1412 | case ETC_MIRROR_CLAMP_TO_BORDER: |
1413 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE) | 1413 | if (Caps.TextureAddressCaps & D3DPTADDRESSCAPS_MIRRORONCE) |
1414 | return D3DTADDRESS_MIRRORONCE; | 1414 | return D3DTADDRESS_MIRRORONCE; |
1415 | else | 1415 | else |
1416 | return D3DTADDRESS_CLAMP; | 1416 | return D3DTADDRESS_CLAMP; |
1417 | default: | 1417 | default: |
1418 | return D3DTADDRESS_WRAP; | 1418 | return D3DTADDRESS_WRAP; |
1419 | } | 1419 | } |
1420 | } | 1420 | } |
1421 | 1421 | ||
1422 | 1422 | ||
1423 | //! Can be called by an IMaterialRenderer to make its work easier. | 1423 | //! Can be called by an IMaterialRenderer to make its work easier. |
1424 | void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, | 1424 | void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMaterial& lastmaterial, |
1425 | bool resetAllRenderstates) | 1425 | bool resetAllRenderstates) |
1426 | { | 1426 | { |
1427 | if (resetAllRenderstates || | 1427 | if (resetAllRenderstates || |
1428 | lastmaterial.AmbientColor != material.AmbientColor || | 1428 | lastmaterial.AmbientColor != material.AmbientColor || |
1429 | lastmaterial.DiffuseColor != material.DiffuseColor || | 1429 | lastmaterial.DiffuseColor != material.DiffuseColor || |
1430 | lastmaterial.SpecularColor != material.SpecularColor || | 1430 | lastmaterial.SpecularColor != material.SpecularColor || |
1431 | lastmaterial.EmissiveColor != material.EmissiveColor || | 1431 | lastmaterial.EmissiveColor != material.EmissiveColor || |
1432 | lastmaterial.Shininess != material.Shininess) | 1432 | lastmaterial.Shininess != material.Shininess) |
1433 | { | 1433 | { |
1434 | D3DMATERIAL8 mat; | 1434 | D3DMATERIAL8 mat; |
1435 | mat.Diffuse = colorToD3D(material.DiffuseColor); | 1435 | mat.Diffuse = colorToD3D(material.DiffuseColor); |
1436 | mat.Ambient = colorToD3D(material.AmbientColor); | 1436 | mat.Ambient = colorToD3D(material.AmbientColor); |
1437 | mat.Specular = colorToD3D(material.SpecularColor); | 1437 | mat.Specular = colorToD3D(material.SpecularColor); |
1438 | mat.Emissive = colorToD3D(material.EmissiveColor); | 1438 | mat.Emissive = colorToD3D(material.EmissiveColor); |
1439 | mat.Power = material.Shininess; | 1439 | mat.Power = material.Shininess; |
1440 | pID3DDevice->SetMaterial(&mat); | 1440 | pID3DDevice->SetMaterial(&mat); |
1441 | } | 1441 | } |
1442 | 1442 | ||
1443 | if (lastmaterial.ColorMaterial != material.ColorMaterial) | 1443 | if (lastmaterial.ColorMaterial != material.ColorMaterial) |
1444 | { | 1444 | { |
1445 | pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE)); | 1445 | pID3DDevice->SetRenderState(D3DRS_COLORVERTEX, (material.ColorMaterial != ECM_NONE)); |
1446 | pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, | 1446 | pID3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE, |
1447 | ((material.ColorMaterial == ECM_DIFFUSE)|| | 1447 | ((material.ColorMaterial == ECM_DIFFUSE)|| |
1448 | (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); | 1448 | (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); |
1449 | pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, | 1449 | pID3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE, |
1450 | ((material.ColorMaterial == ECM_AMBIENT)|| | 1450 | ((material.ColorMaterial == ECM_AMBIENT)|| |
1451 | (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); | 1451 | (material.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT))?D3DMCS_COLOR1:D3DMCS_MATERIAL); |
1452 | pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, | 1452 | pID3DDevice->SetRenderState(D3DRS_EMISSIVEMATERIALSOURCE, |
1453 | (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); | 1453 | (material.ColorMaterial == ECM_EMISSIVE)?D3DMCS_COLOR1:D3DMCS_MATERIAL); |
1454 | pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, | 1454 | pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, |
1455 | (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); | 1455 | (material.ColorMaterial == ECM_SPECULAR)?D3DMCS_COLOR1:D3DMCS_MATERIAL); |
1456 | } | 1456 | } |
1457 | 1457 | ||
1458 | // fillmode | 1458 | // fillmode |
1459 | if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) | 1459 | if (resetAllRenderstates || lastmaterial.Wireframe != material.Wireframe || lastmaterial.PointCloud != material.PointCloud) |
1460 | { | 1460 | { |
1461 | if (material.Wireframe) | 1461 | if (material.Wireframe) |
1462 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); | 1462 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); |
1463 | else | 1463 | else |
1464 | if (material.PointCloud) | 1464 | if (material.PointCloud) |
1465 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); | 1465 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_POINT); |
1466 | else | 1466 | else |
1467 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); | 1467 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); |
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | // shademode | 1470 | // shademode |
1471 | if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) | 1471 | if (resetAllRenderstates || lastmaterial.GouraudShading != material.GouraudShading) |
1472 | { | 1472 | { |
1473 | if (material.GouraudShading) | 1473 | if (material.GouraudShading) |
1474 | pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); | 1474 | pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); |
1475 | else | 1475 | else |
1476 | pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); | 1476 | pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); |
1477 | } | 1477 | } |
1478 | 1478 | ||
1479 | // lighting | 1479 | // lighting |
1480 | if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) | 1480 | if (resetAllRenderstates || lastmaterial.Lighting != material.Lighting) |
1481 | { | 1481 | { |
1482 | if (material.Lighting) | 1482 | if (material.Lighting) |
1483 | pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); | 1483 | pID3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE); |
1484 | else | 1484 | else |
1485 | pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); | 1485 | pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); |
1486 | } | 1486 | } |
1487 | 1487 | ||
1488 | // zbuffer | 1488 | // zbuffer |
1489 | if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) | 1489 | if (resetAllRenderstates || lastmaterial.ZBuffer != material.ZBuffer) |
1490 | { | 1490 | { |
1491 | switch (material.ZBuffer) | 1491 | switch (material.ZBuffer) |
1492 | { | 1492 | { |
1493 | case ECFN_NEVER: | 1493 | case ECFN_NEVER: |
1494 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); | 1494 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); |
1495 | break; | 1495 | break; |
1496 | case ECFN_LESSEQUAL: | 1496 | case ECFN_LESSEQUAL: |
1497 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | 1497 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); |
1498 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); | 1498 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESSEQUAL); |
1499 | break; | 1499 | break; |
1500 | case ECFN_EQUAL: | 1500 | case ECFN_EQUAL: |
1501 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | 1501 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); |
1502 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); | 1502 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); |
1503 | break; | 1503 | break; |
1504 | case ECFN_LESS: | 1504 | case ECFN_LESS: |
1505 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | 1505 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); |
1506 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); | 1506 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS); |
1507 | break; | 1507 | break; |
1508 | case ECFN_NOTEQUAL: | 1508 | case ECFN_NOTEQUAL: |
1509 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | 1509 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); |
1510 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); | 1510 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_NOTEQUAL); |
1511 | break; | 1511 | break; |
1512 | case ECFN_GREATEREQUAL: | 1512 | case ECFN_GREATEREQUAL: |
1513 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | 1513 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); |
1514 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); | 1514 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATEREQUAL); |
1515 | break; | 1515 | break; |
1516 | case ECFN_GREATER: | 1516 | case ECFN_GREATER: |
1517 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | 1517 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); |
1518 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); | 1518 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_GREATER); |
1519 | break; | 1519 | break; |
1520 | case ECFN_ALWAYS: | 1520 | case ECFN_ALWAYS: |
1521 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); | 1521 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE); |
1522 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); | 1522 | pID3DDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); |
1523 | break; | 1523 | break; |
1524 | } | 1524 | } |
1525 | } | 1525 | } |
1526 | 1526 | ||
1527 | // zwrite | 1527 | // zwrite |
1528 | // if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable) | 1528 | // if (resetAllRenderstates || lastmaterial.ZWriteEnable != material.ZWriteEnable) |
1529 | { | 1529 | { |
1530 | if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) | 1530 | if (material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent())) |
1531 | pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); | 1531 | pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE); |
1532 | else | 1532 | else |
1533 | pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); | 1533 | pID3DDevice->SetRenderState( D3DRS_ZWRITEENABLE, FALSE); |
1534 | } | 1534 | } |
1535 | 1535 | ||
1536 | // back face culling | 1536 | // back face culling |
1537 | if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) | 1537 | if (resetAllRenderstates || (lastmaterial.FrontfaceCulling != material.FrontfaceCulling) || (lastmaterial.BackfaceCulling != material.BackfaceCulling)) |
1538 | { | 1538 | { |
1539 | // if (material.FrontfaceCulling && material.BackfaceCulling) | 1539 | // if (material.FrontfaceCulling && material.BackfaceCulling) |
1540 | // pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW); | 1540 | // pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW|D3DCULL_CCW); |
1541 | // else | 1541 | // else |
1542 | if (material.FrontfaceCulling) | 1542 | if (material.FrontfaceCulling) |
1543 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); | 1543 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW); |
1544 | else | 1544 | else |
1545 | if (material.BackfaceCulling) | 1545 | if (material.BackfaceCulling) |
1546 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); | 1546 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW); |
1547 | else | 1547 | else |
1548 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); | 1548 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); |
1549 | } | 1549 | } |
1550 | 1550 | ||
1551 | // fog | 1551 | // fog |
1552 | if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) | 1552 | if (resetAllRenderstates || lastmaterial.FogEnable != material.FogEnable) |
1553 | { | 1553 | { |
1554 | pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); | 1554 | pID3DDevice->SetRenderState(D3DRS_FOGENABLE, material.FogEnable); |
1555 | } | 1555 | } |
1556 | 1556 | ||
1557 | // specular highlights | 1557 | // specular highlights |
1558 | if (resetAllRenderstates || !core::equals(lastmaterial.Shininess, material.Shininess)) | 1558 | if (resetAllRenderstates || !core::equals(lastmaterial.Shininess, material.Shininess)) |
1559 | { | 1559 | { |
1560 | bool enable = (material.Shininess!=0); | 1560 | bool enable = (material.Shininess!=0); |
1561 | pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); | 1561 | pID3DDevice->SetRenderState(D3DRS_SPECULARENABLE, enable); |
1562 | pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable); | 1562 | pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, enable); |
1563 | pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); | 1563 | pID3DDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL); |
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | // normalization | 1566 | // normalization |
1567 | if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) | 1567 | if (resetAllRenderstates || lastmaterial.NormalizeNormals != material.NormalizeNormals) |
1568 | { | 1568 | { |
1569 | pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); | 1569 | pID3DDevice->SetRenderState(D3DRS_NORMALIZENORMALS, material.NormalizeNormals); |
1570 | } | 1570 | } |
1571 | 1571 | ||
1572 | // Color Mask | 1572 | // Color Mask |
1573 | if (queryFeature(EVDF_COLOR_MASK) && | 1573 | if (queryFeature(EVDF_COLOR_MASK) && |
1574 | (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask)) | 1574 | (resetAllRenderstates || lastmaterial.ColorMask != material.ColorMask)) |
1575 | { | 1575 | { |
1576 | const DWORD flag = | 1576 | const DWORD flag = |
1577 | ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | | 1577 | ((material.ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) | |
1578 | ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | | 1578 | ((material.ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) | |
1579 | ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | | 1579 | ((material.ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) | |
1580 | ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); | 1580 | ((material.ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0); |
1581 | pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); | 1581 | pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); |
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | if (queryFeature(EVDF_BLEND_OPERATIONS) && | 1584 | if (queryFeature(EVDF_BLEND_OPERATIONS) && |
1585 | (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation)) | 1585 | (resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation)) |
1586 | { | 1586 | { |
1587 | if (material.BlendOperation==EBO_NONE) | 1587 | if (material.BlendOperation==EBO_NONE) |
1588 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); | 1588 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); |
1589 | else | 1589 | else |
1590 | { | 1590 | { |
1591 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); | 1591 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); |
1592 | switch (material.BlendOperation) | 1592 | switch (material.BlendOperation) |
1593 | { | 1593 | { |
1594 | case EBO_MAX: | 1594 | case EBO_MAX: |
1595 | case EBO_MAX_FACTOR: | 1595 | case EBO_MAX_FACTOR: |
1596 | case EBO_MAX_ALPHA: | 1596 | case EBO_MAX_ALPHA: |
1597 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); | 1597 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX); |
1598 | break; | 1598 | break; |
1599 | case EBO_MIN: | 1599 | case EBO_MIN: |
1600 | case EBO_MIN_FACTOR: | 1600 | case EBO_MIN_FACTOR: |
1601 | case EBO_MIN_ALPHA: | 1601 | case EBO_MIN_ALPHA: |
1602 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); | 1602 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN); |
1603 | break; | 1603 | break; |
1604 | case EBO_SUBTRACT: | 1604 | case EBO_SUBTRACT: |
1605 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); | 1605 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); |
1606 | break; | 1606 | break; |
1607 | case EBO_REVSUBTRACT: | 1607 | case EBO_REVSUBTRACT: |
1608 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); | 1608 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT); |
1609 | break; | 1609 | break; |
1610 | default: | 1610 | default: |
1611 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); | 1611 | pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); |
1612 | break; | 1612 | break; |
1613 | } | 1613 | } |
1614 | } | 1614 | } |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | // Polygon offset | 1617 | // Polygon offset |
1618 | if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || | 1618 | if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates || |
1619 | lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || | 1619 | lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection || |
1620 | lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) | 1620 | lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor)) |
1621 | { | 1621 | { |
1622 | pID3DDevice->SetRenderState(D3DRS_ZBIAS, material.PolygonOffsetFactor); | 1622 | pID3DDevice->SetRenderState(D3DRS_ZBIAS, material.PolygonOffsetFactor); |
1623 | } | 1623 | } |
1624 | 1624 | ||
1625 | // thickness | 1625 | // thickness |
1626 | if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) | 1626 | if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) |
1627 | { | 1627 | { |
1628 | pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&material.Thickness)); | 1628 | pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&material.Thickness)); |
1629 | } | 1629 | } |
1630 | 1630 | ||
1631 | // texture address mode | 1631 | // texture address mode |
1632 | for (u32 st=0; st<MaxTextureUnits; ++st) | 1632 | for (u32 st=0; st<MaxTextureUnits; ++st) |
1633 | { | 1633 | { |
1634 | if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias) | 1634 | if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias) |
1635 | { | 1635 | { |
1636 | const float tmp = material.TextureLayer[st].LODBias * 0.125f; | 1636 | const float tmp = material.TextureLayer[st].LODBias * 0.125f; |
1637 | pID3DDevice->SetTextureStageState(st, D3DTSS_MIPMAPLODBIAS, *(DWORD*)(&tmp)); | 1637 | pID3DDevice->SetTextureStageState(st, D3DTSS_MIPMAPLODBIAS, *(DWORD*)(&tmp)); |
1638 | } | 1638 | } |
1639 | 1639 | ||
1640 | if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) | 1640 | if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) |
1641 | pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); | 1641 | pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSU, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); |
1642 | // If separate UV not supported reuse U for V | 1642 | // If separate UV not supported reuse U for V |
1643 | if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV)) | 1643 | if (!(Caps.TextureAddressCaps & D3DPTADDRESSCAPS_INDEPENDENTUV)) |
1644 | pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); | 1644 | pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapU)); |
1645 | else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV) | 1645 | else if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapV != material.TextureLayer[st].TextureWrapV) |
1646 | pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV)); | 1646 | pID3DDevice->SetTextureStageState(st, D3DTSS_ADDRESSV, getTextureWrapMode(material.TextureLayer[st].TextureWrapV)); |
1647 | 1647 | ||
1648 | // Bilinear and/or trilinear | 1648 | // Bilinear and/or trilinear |
1649 | if (resetAllRenderstates || | 1649 | if (resetAllRenderstates || |
1650 | lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || | 1650 | lastmaterial.TextureLayer[st].BilinearFilter != material.TextureLayer[st].BilinearFilter || |
1651 | lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || | 1651 | lastmaterial.TextureLayer[st].TrilinearFilter != material.TextureLayer[st].TrilinearFilter || |
1652 | lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter || | 1652 | lastmaterial.TextureLayer[st].AnisotropicFilter != material.TextureLayer[st].AnisotropicFilter || |
1653 | lastmaterial.UseMipMaps != material.UseMipMaps) | 1653 | lastmaterial.UseMipMaps != material.UseMipMaps) |
1654 | { | 1654 | { |
1655 | if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter>1) | 1655 | if (material.TextureLayer[st].BilinearFilter || material.TextureLayer[st].TrilinearFilter || material.TextureLayer[st].AnisotropicFilter>1) |
1656 | { | 1656 | { |
1657 | const D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && | 1657 | const D3DTEXTUREFILTERTYPE tftMag = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) && |
1658 | material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; | 1658 | material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; |
1659 | const D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && | 1659 | const D3DTEXTUREFILTERTYPE tftMin = ((Caps.TextureFilterCaps & D3DPTFILTERCAPS_MINFANISOTROPIC) && |
1660 | material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; | 1660 | material.TextureLayer[st].AnisotropicFilter) ? D3DTEXF_ANISOTROPIC : D3DTEXF_LINEAR; |
1661 | const D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE; | 1661 | const D3DTEXTUREFILTERTYPE tftMip = material.UseMipMaps? (material.TextureLayer[st].TrilinearFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE; |
1662 | 1662 | ||
1663 | if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC) | 1663 | if (tftMag==D3DTEXF_ANISOTROPIC || tftMin == D3DTEXF_ANISOTROPIC) |
1664 | pID3DDevice->SetTextureStageState(st, D3DTSS_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy)); | 1664 | pID3DDevice->SetTextureStageState(st, D3DTSS_MAXANISOTROPY, core::min_((DWORD)material.TextureLayer[st].AnisotropicFilter, Caps.MaxAnisotropy)); |
1665 | pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, tftMag); | 1665 | pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, tftMag); |
1666 | pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, tftMin); | 1666 | pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, tftMin); |
1667 | pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, tftMip); | 1667 | pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, tftMip); |
1668 | } | 1668 | } |
1669 | else | 1669 | else |
1670 | { | 1670 | { |
1671 | pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, D3DTEXF_POINT); | 1671 | pID3DDevice->SetTextureStageState(st, D3DTSS_MINFILTER, D3DTEXF_POINT); |
1672 | pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, D3DTEXF_NONE); | 1672 | pID3DDevice->SetTextureStageState(st, D3DTSS_MIPFILTER, D3DTEXF_NONE); |
1673 | pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, D3DTEXF_POINT); | 1673 | pID3DDevice->SetTextureStageState(st, D3DTSS_MAGFILTER, D3DTEXF_POINT); |
1674 | } | 1674 | } |
1675 | } | 1675 | } |
1676 | } | 1676 | } |
1677 | } | 1677 | } |
1678 | 1678 | ||
1679 | 1679 | ||
1680 | //! sets the needed renderstates | 1680 | //! sets the needed renderstates |
1681 | void CD3D8Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) | 1681 | void CD3D8Driver::setRenderStatesStencilShadowMode(bool zfail, u32 debugDataVisible) |
1682 | { | 1682 | { |
1683 | if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && | 1683 | if ((CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && |
1684 | CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || | 1684 | CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS) || |
1685 | Transformation3DChanged) | 1685 | Transformation3DChanged) |
1686 | { | 1686 | { |
1687 | // unset last 3d material | 1687 | // unset last 3d material |
1688 | if (CurrentRenderMode == ERM_3D && | 1688 | if (CurrentRenderMode == ERM_3D && |
1689 | static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) | 1689 | static_cast<u32>(Material.MaterialType) < MaterialRenderers.size()) |
1690 | { | 1690 | { |
1691 | MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); | 1691 | MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial(); |
1692 | ResetRenderStates = true; | 1692 | ResetRenderStates = true; |
1693 | } | 1693 | } |
1694 | // switch back the matrices | 1694 | // switch back the matrices |
1695 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); | 1695 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)&Matrices[ETS_VIEW])); |
1696 | pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); | 1696 | pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)&Matrices[ETS_WORLD])); |
1697 | pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); | 1697 | pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)&Matrices[ETS_PROJECTION])); |
1698 | 1698 | ||
1699 | Transformation3DChanged = false; | 1699 | Transformation3DChanged = false; |
1700 | 1700 | ||
1701 | setActiveTexture(0,0); | 1701 | setActiveTexture(0,0); |
1702 | setActiveTexture(1,0); | 1702 | setActiveTexture(1,0); |
1703 | setActiveTexture(2,0); | 1703 | setActiveTexture(2,0); |
1704 | setActiveTexture(3,0); | 1704 | setActiveTexture(3,0); |
1705 | 1705 | ||
1706 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); | 1706 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); |
1707 | 1707 | ||
1708 | pID3DDevice->SetVertexShader(D3DFVF_XYZ); | 1708 | pID3DDevice->SetVertexShader(D3DFVF_XYZ); |
1709 | LastVertexType = (video::E_VERTEX_TYPE)(-1); | 1709 | LastVertexType = (video::E_VERTEX_TYPE)(-1); |
1710 | 1710 | ||
1711 | pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); | 1711 | pID3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); |
1712 | pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); | 1712 | pID3DDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); |
1713 | pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); | 1713 | pID3DDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT); |
1714 | //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); | 1714 | //pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); |
1715 | //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); | 1715 | //pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); |
1716 | 1716 | ||
1717 | pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); | 1717 | pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); |
1718 | pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0); | 1718 | pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x0); |
1719 | pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); | 1719 | pID3DDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff); |
1720 | pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); | 1720 | pID3DDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff); |
1721 | if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) | 1721 | if (!(debugDataVisible & (scene::EDS_SKELETON|scene::EDS_MESH_WIRE_OVERLAY))) |
1722 | pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); | 1722 | pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); |
1723 | if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)) | 1723 | if ((debugDataVisible & scene::EDS_MESH_WIRE_OVERLAY)) |
1724 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); | 1724 | pID3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME); |
1725 | } | 1725 | } |
1726 | 1726 | ||
1727 | if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) | 1727 | if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZPASS && !zfail) |
1728 | { | 1728 | { |
1729 | // USE THE ZPASS METHOD | 1729 | // USE THE ZPASS METHOD |
1730 | pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); | 1730 | pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); |
1731 | pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); | 1731 | pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP); |
1732 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); | 1732 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR); |
1733 | } | 1733 | } |
1734 | else | 1734 | else |
1735 | if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) | 1735 | if (CurrentRenderMode != ERM_SHADOW_VOLUME_ZFAIL && zfail) |
1736 | { | 1736 | { |
1737 | // USE THE ZFAIL METHOD | 1737 | // USE THE ZFAIL METHOD |
1738 | pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); | 1738 | pID3DDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP); |
1739 | pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); | 1739 | pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR); |
1740 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); | 1740 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP); |
1741 | } | 1741 | } |
1742 | 1742 | ||
1743 | CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; | 1743 | CurrentRenderMode = zfail ? ERM_SHADOW_VOLUME_ZFAIL : ERM_SHADOW_VOLUME_ZPASS; |
1744 | } | 1744 | } |
1745 | 1745 | ||
1746 | 1746 | ||
1747 | //! sets the needed renderstates | 1747 | //! sets the needed renderstates |
1748 | void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha) | 1748 | void CD3D8Driver::setRenderStatesStencilFillMode(bool alpha) |
1749 | { | 1749 | { |
1750 | if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) | 1750 | if (CurrentRenderMode != ERM_STENCIL_FILL || Transformation3DChanged) |
1751 | { | 1751 | { |
1752 | pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D8); | 1752 | pID3DDevice->SetTransform(D3DTS_VIEW, &UnitMatrixD3D8); |
1753 | pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); | 1753 | pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); |
1754 | pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D8); | 1754 | pID3DDevice->SetTransform(D3DTS_PROJECTION, &UnitMatrixD3D8); |
1755 | 1755 | ||
1756 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); | 1756 | pID3DDevice->SetRenderState(D3DRS_ZENABLE, FALSE); |
1757 | pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); | 1757 | pID3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE); |
1758 | pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); | 1758 | pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); |
1759 | 1759 | ||
1760 | pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); | 1760 | pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); |
1761 | pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); | 1761 | pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE); |
1762 | pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); | 1762 | pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); |
1763 | pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); | 1763 | pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); |
1764 | pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); | 1764 | pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); |
1765 | pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); | 1765 | pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE); |
1766 | 1766 | ||
1767 | pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1 ); | 1767 | pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1 ); |
1768 | pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); | 1768 | pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); |
1769 | //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); | 1769 | //pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_GREATEREQUAL); |
1770 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); | 1770 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ); |
1771 | pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); | 1771 | pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ); |
1772 | pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); | 1772 | pID3DDevice->SetRenderState( D3DRS_STENCILMASK, 0xffffffff ); |
1773 | pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); | 1773 | pID3DDevice->SetRenderState( D3DRS_STENCILWRITEMASK, 0xffffffff ); |
1774 | 1774 | ||
1775 | pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); | 1775 | pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW); |
1776 | 1776 | ||
1777 | Transformation3DChanged = false; | 1777 | Transformation3DChanged = false; |
1778 | 1778 | ||
1779 | if (alpha) | 1779 | if (alpha) |
1780 | { | 1780 | { |
1781 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); | 1781 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); |
1782 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); | 1782 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); |
1783 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); | 1783 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); |
1784 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); | 1784 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); |
1785 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); | 1785 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE ); |
1786 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); | 1786 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); |
1787 | pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); | 1787 | pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); |
1788 | pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); | 1788 | pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); |
1789 | } | 1789 | } |
1790 | else | 1790 | else |
1791 | { | 1791 | { |
1792 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); | 1792 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE ); |
1793 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); | 1793 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); |
1794 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); | 1794 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); |
1795 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); | 1795 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); |
1796 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); | 1796 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); |
1797 | } | 1797 | } |
1798 | } | 1798 | } |
1799 | 1799 | ||
1800 | CurrentRenderMode = ERM_STENCIL_FILL; | 1800 | CurrentRenderMode = ERM_STENCIL_FILL; |
1801 | } | 1801 | } |
1802 | 1802 | ||
1803 | 1803 | ||
1804 | //! sets the needed renderstates | 1804 | //! sets the needed renderstates |
1805 | void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) | 1805 | void CD3D8Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChannel) |
1806 | { | 1806 | { |
1807 | if (!pID3DDevice) | 1807 | if (!pID3DDevice) |
1808 | return; | 1808 | return; |
1809 | 1809 | ||
1810 | if (CurrentRenderMode != ERM_2D || Transformation3DChanged) | 1810 | if (CurrentRenderMode != ERM_2D || Transformation3DChanged) |
1811 | { | 1811 | { |
1812 | // unset last 3d material | 1812 | // unset last 3d material |
1813 | if (CurrentRenderMode == ERM_3D) | 1813 | if (CurrentRenderMode == ERM_3D) |
1814 | { | 1814 | { |
1815 | if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) | 1815 | if (static_cast<u32>(LastMaterial.MaterialType) < MaterialRenderers.size()) |
1816 | MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); | 1816 | MaterialRenderers[LastMaterial.MaterialType].Renderer->OnUnsetMaterial(); |
1817 | } | 1817 | } |
1818 | if (!OverrideMaterial2DEnabled) | 1818 | if (!OverrideMaterial2DEnabled) |
1819 | { | 1819 | { |
1820 | setBasicRenderStates(InitMaterial2D, LastMaterial, true); | 1820 | setBasicRenderStates(InitMaterial2D, LastMaterial, true); |
1821 | LastMaterial=InitMaterial2D; | 1821 | LastMaterial=InitMaterial2D; |
1822 | 1822 | ||
1823 | // fix everything that is wrongly set by SMaterial default | 1823 | // fix everything that is wrongly set by SMaterial default |
1824 | pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); | 1824 | pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); |
1825 | pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); | 1825 | pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); |
1826 | pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); | 1826 | pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE); |
1827 | pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); | 1827 | pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); |
1828 | pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); | 1828 | pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE); |
1829 | pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); | 1829 | pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); |
1830 | 1830 | ||
1831 | pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); | 1831 | pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); |
1832 | 1832 | ||
1833 | } | 1833 | } |
1834 | pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); | 1834 | pID3DDevice->SetTransform(D3DTS_WORLD, &UnitMatrixD3D8); |
1835 | core::matrix4 m; | 1835 | core::matrix4 m; |
1836 | m.setTranslation(core::vector3df(-0.5f,-0.5f,0)); | 1836 | m.setTranslation(core::vector3df(-0.5f,-0.5f,0)); |
1837 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer())); | 1837 | pID3DDevice->SetTransform(D3DTS_VIEW, (D3DMATRIX*)((void*)m.pointer())); |
1838 | 1838 | ||
1839 | const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); | 1839 | const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); |
1840 | m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0); | 1840 | m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0, 1.0); |
1841 | m.setTranslation(core::vector3df(-1,1,0)); | 1841 | m.setTranslation(core::vector3df(-1,1,0)); |
1842 | pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer())); | 1842 | pID3DDevice->SetTransform(D3DTS_PROJECTION, (D3DMATRIX*)((void*)m.pointer())); |
1843 | 1843 | ||
1844 | Transformation3DChanged = false; | 1844 | Transformation3DChanged = false; |
1845 | } | 1845 | } |
1846 | if (OverrideMaterial2DEnabled) | 1846 | if (OverrideMaterial2DEnabled) |
1847 | { | 1847 | { |
1848 | OverrideMaterial2D.Lighting=false; | 1848 | OverrideMaterial2D.Lighting=false; |
1849 | setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); | 1849 | setBasicRenderStates(OverrideMaterial2D, LastMaterial, false); |
1850 | LastMaterial = OverrideMaterial2D; | 1850 | LastMaterial = OverrideMaterial2D; |
1851 | } | 1851 | } |
1852 | 1852 | ||
1853 | // no alphaChannel without texture | 1853 | // no alphaChannel without texture |
1854 | alphaChannel &= texture; | 1854 | alphaChannel &= texture; |
1855 | 1855 | ||
1856 | if (alpha || alphaChannel) | 1856 | if (alpha || alphaChannel) |
1857 | { | 1857 | { |
1858 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); | 1858 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); |
1859 | pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); | 1859 | pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); |
1860 | pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); | 1860 | pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); |
1861 | } | 1861 | } |
1862 | else | 1862 | else |
1863 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); | 1863 | pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); |
1864 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); | 1864 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); |
1865 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); | 1865 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); |
1866 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); | 1866 | pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); |
1867 | if (texture) | 1867 | if (texture) |
1868 | { | 1868 | { |
1869 | setTransform(ETS_TEXTURE_0, core::IdentityMatrix); | 1869 | setTransform(ETS_TEXTURE_0, core::IdentityMatrix); |
1870 | // Due to the transformation change, the previous line would call a reset each frame | 1870 | // Due to the transformation change, the previous line would call a reset each frame |
1871 | // but we can safely reset the variable as it was false before | 1871 | // but we can safely reset the variable as it was false before |
1872 | Transformation3DChanged=false; | 1872 | Transformation3DChanged=false; |
1873 | } | 1873 | } |
1874 | if (alphaChannel) | 1874 | if (alphaChannel) |
1875 | { | 1875 | { |
1876 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | 1876 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); |
1877 | 1877 | ||
1878 | if (alpha) | 1878 | if (alpha) |
1879 | { | 1879 | { |
1880 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | 1880 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); |
1881 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); | 1881 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); |
1882 | } | 1882 | } |
1883 | else | 1883 | else |
1884 | { | 1884 | { |
1885 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); | 1885 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); |
1886 | } | 1886 | } |
1887 | 1887 | ||
1888 | } | 1888 | } |
1889 | else | 1889 | else |
1890 | { | 1890 | { |
1891 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); | 1891 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); |
1892 | if (alpha) | 1892 | if (alpha) |
1893 | { | 1893 | { |
1894 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); | 1894 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2); |
1895 | } | 1895 | } |
1896 | else | 1896 | else |
1897 | { | 1897 | { |
1898 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); | 1898 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); |
1899 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); | 1899 | pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE); |
1900 | } | 1900 | } |
1901 | } | 1901 | } |
1902 | 1902 | ||
1903 | CurrentRenderMode = ERM_2D; | 1903 | CurrentRenderMode = ERM_2D; |
1904 | } | 1904 | } |
1905 | 1905 | ||
1906 | 1906 | ||
1907 | //! deletes all dynamic lights there are | 1907 | //! deletes all dynamic lights there are |
1908 | void CD3D8Driver::deleteAllDynamicLights() | 1908 | void CD3D8Driver::deleteAllDynamicLights() |
1909 | { | 1909 | { |
1910 | for (s32 i=0; i<LastSetLight+1; ++i) | 1910 | for (s32 i=0; i<LastSetLight+1; ++i) |
1911 | pID3DDevice->LightEnable(i, false); | 1911 | pID3DDevice->LightEnable(i, false); |
1912 | 1912 | ||
1913 | LastSetLight = -1; | 1913 | LastSetLight = -1; |
1914 | 1914 | ||
1915 | CNullDriver::deleteAllDynamicLights(); | 1915 | CNullDriver::deleteAllDynamicLights(); |
1916 | } | 1916 | } |
1917 | 1917 | ||
1918 | 1918 | ||
1919 | //! adds a dynamic light | 1919 | //! adds a dynamic light |
1920 | s32 CD3D8Driver::addDynamicLight(const SLight& dl) | 1920 | s32 CD3D8Driver::addDynamicLight(const SLight& dl) |
1921 | { | 1921 | { |
1922 | CNullDriver::addDynamicLight(dl); | 1922 | CNullDriver::addDynamicLight(dl); |
1923 | 1923 | ||
1924 | D3DLIGHT8 light; | 1924 | D3DLIGHT8 light; |
1925 | 1925 | ||
1926 | switch (dl.Type) | 1926 | switch (dl.Type) |
1927 | { | 1927 | { |
1928 | case ELT_POINT: | 1928 | case ELT_POINT: |
1929 | light.Type = D3DLIGHT_POINT; | 1929 | light.Type = D3DLIGHT_POINT; |
1930 | break; | 1930 | break; |
1931 | case ELT_SPOT: | 1931 | case ELT_SPOT: |
1932 | light.Type = D3DLIGHT_SPOT; | 1932 | light.Type = D3DLIGHT_SPOT; |
1933 | break; | 1933 | break; |
1934 | case ELT_DIRECTIONAL: | 1934 | case ELT_DIRECTIONAL: |
1935 | light.Type = D3DLIGHT_DIRECTIONAL; | 1935 | light.Type = D3DLIGHT_DIRECTIONAL; |
1936 | break; | 1936 | break; |
1937 | } | 1937 | } |
1938 | 1938 | ||
1939 | light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); | 1939 | light.Position = *(D3DVECTOR*)((void*)(&dl.Position)); |
1940 | light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); | 1940 | light.Direction = *(D3DVECTOR*)((void*)(&dl.Direction)); |
1941 | 1941 | ||
1942 | light.Range = core::min_(dl.Radius, MaxLightDistance); | 1942 | light.Range = core::min_(dl.Radius, MaxLightDistance); |
1943 | light.Falloff = dl.Falloff; | 1943 | light.Falloff = dl.Falloff; |
1944 | 1944 | ||
1945 | light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); | 1945 | light.Diffuse = *(D3DCOLORVALUE*)((void*)(&dl.DiffuseColor)); |
1946 | light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); | 1946 | light.Specular = *(D3DCOLORVALUE*)((void*)(&dl.SpecularColor)); |
1947 | light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); | 1947 | light.Ambient = *(D3DCOLORVALUE*)((void*)(&dl.AmbientColor)); |
1948 | 1948 | ||
1949 | light.Attenuation0 = dl.Attenuation.X; | 1949 | light.Attenuation0 = dl.Attenuation.X; |
1950 | light.Attenuation1 = dl.Attenuation.Y; | 1950 | light.Attenuation1 = dl.Attenuation.Y; |
1951 | light.Attenuation2 = dl.Attenuation.Z; | 1951 | light.Attenuation2 = dl.Attenuation.Z; |
1952 | 1952 | ||
1953 | light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; | 1953 | light.Theta = dl.InnerCone * 2.0f * core::DEGTORAD; |
1954 | light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; | 1954 | light.Phi = dl.OuterCone * 2.0f * core::DEGTORAD; |
1955 | 1955 | ||
1956 | ++LastSetLight; | 1956 | ++LastSetLight; |
1957 | 1957 | ||
1958 | if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light)) | 1958 | if(D3D_OK == pID3DDevice->SetLight(LastSetLight, &light)) |
1959 | { | 1959 | { |
1960 | // I don't care if this succeeds | 1960 | // I don't care if this succeeds |
1961 | (void)pID3DDevice->LightEnable(LastSetLight, true); | 1961 | (void)pID3DDevice->LightEnable(LastSetLight, true); |
1962 | return LastSetLight; | 1962 | return LastSetLight; |
1963 | } | 1963 | } |
1964 | 1964 | ||
1965 | return -1; | 1965 | return -1; |
1966 | } | 1966 | } |
1967 | 1967 | ||
1968 | 1968 | ||
1969 | void CD3D8Driver::turnLightOn(s32 lightIndex, bool turnOn) | 1969 | void CD3D8Driver::turnLightOn(s32 lightIndex, bool turnOn) |
1970 | { | 1970 | { |
1971 | if(lightIndex < 0 || lightIndex > LastSetLight) | 1971 | if(lightIndex < 0 || lightIndex > LastSetLight) |
1972 | return; | 1972 | return; |
1973 | 1973 | ||
1974 | (void)pID3DDevice->LightEnable(lightIndex, turnOn); | 1974 | (void)pID3DDevice->LightEnable(lightIndex, turnOn); |
1975 | } | 1975 | } |
1976 | 1976 | ||
1977 | 1977 | ||
1978 | //! returns the maximal amount of dynamic lights the device can handle | 1978 | //! returns the maximal amount of dynamic lights the device can handle |
1979 | u32 CD3D8Driver::getMaximalDynamicLightAmount() const | 1979 | u32 CD3D8Driver::getMaximalDynamicLightAmount() const |
1980 | { | 1980 | { |
1981 | return Caps.MaxActiveLights; | 1981 | return Caps.MaxActiveLights; |
1982 | } | 1982 | } |
1983 | 1983 | ||
1984 | 1984 | ||
1985 | //! Sets the dynamic ambient light color. The default color is | 1985 | //! Sets the dynamic ambient light color. The default color is |
1986 | //! (0,0,0,0) which means it is dark. | 1986 | //! (0,0,0,0) which means it is dark. |
1987 | //! \param color: New color of the ambient light. | 1987 | //! \param color: New color of the ambient light. |
1988 | void CD3D8Driver::setAmbientLight(const SColorf& color) | 1988 | void CD3D8Driver::setAmbientLight(const SColorf& color) |
1989 | { | 1989 | { |
1990 | if (!pID3DDevice) | 1990 | if (!pID3DDevice) |
1991 | return; | 1991 | return; |
1992 | 1992 | ||
1993 | AmbientLight = color; | 1993 | AmbientLight = color; |
1994 | D3DCOLOR col = color.toSColor().color; | 1994 | D3DCOLOR col = color.toSColor().color; |
1995 | pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); | 1995 | pID3DDevice->SetRenderState(D3DRS_AMBIENT, col); |
1996 | } | 1996 | } |
1997 | 1997 | ||
1998 | 1998 | ||
1999 | //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 | 1999 | //! \return Returns the name of the video driver. Example: In case of the DIRECT3D8 |
2000 | //! driver, it would return "Direct3D8.1". | 2000 | //! driver, it would return "Direct3D8.1". |
2001 | const wchar_t* CD3D8Driver::getName() const | 2001 | const wchar_t* CD3D8Driver::getName() const |
2002 | { | 2002 | { |
2003 | return L"Direct3D 8.1"; | 2003 | return L"Direct3D 8.1"; |
2004 | } | 2004 | } |
2005 | 2005 | ||
2006 | 2006 | ||
2007 | //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do | 2007 | //! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do |
2008 | //! this: First, draw all geometry. Then use this method, to draw the shadow | 2008 | //! this: First, draw all geometry. Then use this method, to draw the shadow |
2009 | //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. | 2009 | //! volume. Then, use IVideoDriver::drawStencilShadow() to visualize the shadow. |
2010 | void CD3D8Driver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) | 2010 | void CD3D8Driver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible) |
2011 | { | 2011 | { |
2012 | const u32 count = triangles.size(); | 2012 | const u32 count = triangles.size(); |
2013 | if (!Params.Stencilbuffer || !count) | 2013 | if (!Params.Stencilbuffer || !count) |
2014 | return; | 2014 | return; |
2015 | 2015 | ||
2016 | setRenderStatesStencilShadowMode(zfail, debugDataVisible); | 2016 | setRenderStatesStencilShadowMode(zfail, debugDataVisible); |
2017 | 2017 | ||
2018 | if (!zfail) | 2018 | if (!zfail) |
2019 | { | 2019 | { |
2020 | // ZPASS Method | 2020 | // ZPASS Method |
2021 | 2021 | ||
2022 | // Draw front-side of shadow volume in stencil only | 2022 | // Draw front-side of shadow volume in stencil only |
2023 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW ); | 2023 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW ); |
2024 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT); | 2024 | pID3DDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCRSAT); |
2025 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); | 2025 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); |
2026 | 2026 | ||
2027 | // Now reverse cull order so front sides of shadow volume are written. | 2027 | // Now reverse cull order so front sides of shadow volume are written. |
2028 | pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); | 2028 | pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW ); |
2029 | pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT); | 2029 | pID3DDevice->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECRSAT); |
2030 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); | 2030 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); |
2031 | } | 2031 | } |
2032 | else | 2032 | else |
2033 | { | 2033 | { |
2034 | // ZFAIL Method | 2034 | // ZFAIL Method |
2035 | 2035 | ||
2036 | // Draw front-side of shadow volume in stencil only | 2036 | // Draw front-side of shadow volume in stencil only |
2037 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW ); | 2037 | pID3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW ); |
2038 | pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT ); | 2038 | pID3DDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCRSAT ); |
2039 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); | 2039 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); |
2040 | 2040 | ||
2041 | // Now reverse cull order so front sides of shadow volume are written. | 2041 | // Now reverse cull order so front sides of shadow volume are written. |
2042 | pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); | 2042 | pID3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); |
2043 | pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT ); | 2043 | pID3DDevice->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECRSAT ); |
2044 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); | 2044 | pID3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, count / 3, triangles.const_pointer(), sizeof(core::vector3df)); |
2045 | } | 2045 | } |
2046 | } | 2046 | } |
2047 | 2047 | ||
2048 | 2048 | ||
2049 | //! Fills the stencil shadow with color. After the shadow volume has been drawn | 2049 | //! Fills the stencil shadow with color. After the shadow volume has been drawn |
2050 | //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this | 2050 | //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this |
2051 | //! to draw the color of the shadow. | 2051 | //! to draw the color of the shadow. |
2052 | void CD3D8Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, | 2052 | void CD3D8Driver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, |
2053 | video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) | 2053 | video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) |
2054 | { | 2054 | { |
2055 | if (!Params.Stencilbuffer) | 2055 | if (!Params.Stencilbuffer) |
2056 | return; | 2056 | return; |
2057 | 2057 | ||
2058 | S3DVertex vtx[4]; | 2058 | S3DVertex vtx[4]; |
2059 | vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); | 2059 | vtx[0] = S3DVertex(1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftUpEdge, 0.0f, 0.0f); |
2060 | vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); | 2060 | vtx[1] = S3DVertex(1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightUpEdge, 0.0f, 1.0f); |
2061 | vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); | 2061 | vtx[2] = S3DVertex(-1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, leftDownEdge, 1.0f, 0.0f); |
2062 | vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); | 2062 | vtx[3] = S3DVertex(-1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, rightDownEdge, 1.0f, 1.0f); |
2063 | 2063 | ||
2064 | const s16 indices[6] = {0,1,2,1,3,2}; | 2064 | const s16 indices[6] = {0,1,2,1,3,2}; |
2065 | 2065 | ||
2066 | setRenderStatesStencilFillMode( | 2066 | setRenderStatesStencilFillMode( |
2067 | leftUpEdge.getAlpha() < 255 || | 2067 | leftUpEdge.getAlpha() < 255 || |
2068 | rightUpEdge.getAlpha() < 255 || | 2068 | rightUpEdge.getAlpha() < 255 || |
2069 | leftDownEdge.getAlpha() < 255 || | 2069 | leftDownEdge.getAlpha() < 255 || |
2070 | rightDownEdge.getAlpha() < 255); | 2070 | rightDownEdge.getAlpha() < 255); |
2071 | 2071 | ||
2072 | setActiveTexture(0,0); | 2072 | setActiveTexture(0,0); |
2073 | 2073 | ||
2074 | setVertexShader(EVT_STANDARD); | 2074 | setVertexShader(EVT_STANDARD); |
2075 | 2075 | ||
2076 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], | 2076 | pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], |
2077 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); | 2077 | D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex)); |
2078 | 2078 | ||
2079 | if (clearStencilBuffer) | 2079 | if (clearStencilBuffer) |
2080 | pID3DDevice->Clear(0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); | 2080 | pID3DDevice->Clear(0, NULL, D3DCLEAR_STENCIL,0, 1.0, 0); |
2081 | } | 2081 | } |
2082 | 2082 | ||
2083 | 2083 | ||
2084 | //! Returns the maximum amount of primitives (mostly vertices) which | 2084 | //! Returns the maximum amount of primitives (mostly vertices) which |
2085 | //! the device is able to render with one drawIndexedTriangleList | 2085 | //! the device is able to render with one drawIndexedTriangleList |
2086 | //! call. | 2086 | //! call. |
2087 | u32 CD3D8Driver::getMaximalPrimitiveCount() const | 2087 | u32 CD3D8Driver::getMaximalPrimitiveCount() const |
2088 | { | 2088 | { |
2089 | return Caps.MaxPrimitiveCount; | 2089 | return Caps.MaxPrimitiveCount; |
2090 | } | 2090 | } |
2091 | 2091 | ||
2092 | 2092 | ||
2093 | //! Sets the fog mode. | 2093 | //! Sets the fog mode. |
2094 | void CD3D8Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, | 2094 | void CD3D8Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, |
2095 | f32 end, f32 density, bool pixelFog, bool rangeFog) | 2095 | f32 end, f32 density, bool pixelFog, bool rangeFog) |
2096 | { | 2096 | { |
2097 | CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); | 2097 | CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog); |
2098 | 2098 | ||
2099 | if (!pID3DDevice) | 2099 | if (!pID3DDevice) |
2100 | return; | 2100 | return; |
2101 | 2101 | ||
2102 | pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); | 2102 | pID3DDevice->SetRenderState(D3DRS_FOGCOLOR, color.color); |
2103 | 2103 | ||
2104 | pID3DDevice->SetRenderState( | 2104 | pID3DDevice->SetRenderState( |
2105 | #if defined( _IRR_XBOX_PLATFORM_) | 2105 | #if defined( _IRR_XBOX_PLATFORM_) |
2106 | D3DRS_FOGTABLEMODE, | 2106 | D3DRS_FOGTABLEMODE, |
2107 | #else | 2107 | #else |
2108 | pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, | 2108 | pixelFog ? D3DRS_FOGTABLEMODE : D3DRS_FOGVERTEXMODE, |
2109 | #endif | 2109 | #endif |
2110 | (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2); | 2110 | (fogType==EFT_FOG_LINEAR)? D3DFOG_LINEAR : (fogType==EFT_FOG_EXP)?D3DFOG_EXP:D3DFOG_EXP2); |
2111 | 2111 | ||
2112 | if (fogType==EFT_FOG_LINEAR) | 2112 | if (fogType==EFT_FOG_LINEAR) |
2113 | { | 2113 | { |
2114 | pID3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start)); | 2114 | pID3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start)); |
2115 | pID3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end)); | 2115 | pID3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end)); |
2116 | } | 2116 | } |
2117 | else | 2117 | else |
2118 | pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)(&density)); | 2118 | pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)(&density)); |
2119 | 2119 | ||
2120 | if(!pixelFog) | 2120 | if(!pixelFog) |
2121 | pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); | 2121 | pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); |
2122 | } | 2122 | } |
2123 | 2123 | ||
2124 | 2124 | ||
2125 | //! Draws a 3d line. | 2125 | //! Draws a 3d line. |
2126 | void CD3D8Driver::draw3DLine(const core::vector3df& start, | 2126 | void CD3D8Driver::draw3DLine(const core::vector3df& start, |
2127 | const core::vector3df& end, SColor color) | 2127 | const core::vector3df& end, SColor color) |
2128 | { | 2128 | { |
2129 | setVertexShader(EVT_STANDARD); | 2129 | setVertexShader(EVT_STANDARD); |
2130 | setRenderStates3DMode(); | 2130 | setRenderStates3DMode(); |
2131 | video::S3DVertex v[2]; | 2131 | video::S3DVertex v[2]; |
2132 | v[0].Color = color; | 2132 | v[0].Color = color; |
2133 | v[1].Color = color; | 2133 | v[1].Color = color; |
2134 | v[0].Pos = start; | 2134 | v[0].Pos = start; |
2135 | v[1].Pos = end; | 2135 | v[1].Pos = end; |
2136 | 2136 | ||
2137 | pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); | 2137 | pID3DDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1, v, sizeof(S3DVertex)); |
2138 | } | 2138 | } |
2139 | 2139 | ||
2140 | 2140 | ||
2141 | void CD3D8Driver::OnResize(const core::dimension2d<u32>& size) | 2141 | void CD3D8Driver::OnResize(const core::dimension2d<u32>& size) |
2142 | { | 2142 | { |
2143 | if (!pID3DDevice) | 2143 | if (!pID3DDevice) |
2144 | return; | 2144 | return; |
2145 | 2145 | ||
2146 | CNullDriver::OnResize(size); | 2146 | CNullDriver::OnResize(size); |
2147 | reset(); | 2147 | reset(); |
2148 | } | 2148 | } |
2149 | 2149 | ||
2150 | 2150 | ||
2151 | //! Returns type of video driver | 2151 | //! Returns type of video driver |
2152 | E_DRIVER_TYPE CD3D8Driver::getDriverType() const | 2152 | E_DRIVER_TYPE CD3D8Driver::getDriverType() const |
2153 | { | 2153 | { |
2154 | return EDT_DIRECT3D8; | 2154 | return EDT_DIRECT3D8; |
2155 | } | 2155 | } |
2156 | 2156 | ||
2157 | 2157 | ||
2158 | //! Returns the transformation set by setTransform | 2158 | //! Returns the transformation set by setTransform |
2159 | const core::matrix4& CD3D8Driver::getTransform(E_TRANSFORMATION_STATE state) const | 2159 | const core::matrix4& CD3D8Driver::getTransform(E_TRANSFORMATION_STATE state) const |
2160 | { | 2160 | { |
2161 | return Matrices[state]; | 2161 | return Matrices[state]; |
2162 | } | 2162 | } |
2163 | 2163 | ||
2164 | 2164 | ||
2165 | //! Sets a vertex shader constant. | 2165 | //! Sets a vertex shader constant. |
2166 | void CD3D8Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) | 2166 | void CD3D8Driver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) |
2167 | { | 2167 | { |
2168 | if (data) | 2168 | if (data) |
2169 | pID3DDevice->SetVertexShaderConstant(startRegister, data, constantAmount); | 2169 | pID3DDevice->SetVertexShaderConstant(startRegister, data, constantAmount); |
2170 | } | 2170 | } |
2171 | 2171 | ||
2172 | 2172 | ||
2173 | //! Sets a pixel shader constant. | 2173 | //! Sets a pixel shader constant. |
2174 | void CD3D8Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) | 2174 | void CD3D8Driver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) |
2175 | { | 2175 | { |
2176 | if (data) | 2176 | if (data) |
2177 | pID3DDevice->SetPixelShaderConstant(startRegister, data, constantAmount); | 2177 | pID3DDevice->SetPixelShaderConstant(startRegister, data, constantAmount); |
2178 | } | 2178 | } |
2179 | 2179 | ||
2180 | 2180 | ||
2181 | //! Sets a constant for the vertex shader based on a name. | 2181 | //! Sets a constant for the vertex shader based on a name. |
2182 | bool CD3D8Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) | 2182 | bool CD3D8Driver::setVertexShaderConstant(const c8* name, const f32* floats, int count) |
2183 | { | 2183 | { |
2184 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); | 2184 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); |
2185 | return false; | 2185 | return false; |
2186 | } | 2186 | } |
2187 | 2187 | ||
2188 | 2188 | ||
2189 | //! Bool interface for the above. | 2189 | //! Bool interface for the above. |
2190 | bool CD3D8Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) | 2190 | bool CD3D8Driver::setVertexShaderConstant(const c8* name, const bool* bools, int count) |
2191 | { | 2191 | { |
2192 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); | 2192 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); |
2193 | return false; | 2193 | return false; |
2194 | } | 2194 | } |
2195 | 2195 | ||
2196 | 2196 | ||
2197 | //! Int interface for the above. | 2197 | //! Int interface for the above. |
2198 | bool CD3D8Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) | 2198 | bool CD3D8Driver::setVertexShaderConstant(const c8* name, const s32* ints, int count) |
2199 | { | 2199 | { |
2200 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); | 2200 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); |
2201 | return false; | 2201 | return false; |
2202 | } | 2202 | } |
2203 | 2203 | ||
2204 | 2204 | ||
2205 | //! Sets a constant for the pixel shader based on a name. | 2205 | //! Sets a constant for the pixel shader based on a name. |
2206 | bool CD3D8Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) | 2206 | bool CD3D8Driver::setPixelShaderConstant(const c8* name, const f32* floats, int count) |
2207 | { | 2207 | { |
2208 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); | 2208 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); |
2209 | return false; | 2209 | return false; |
2210 | } | 2210 | } |
2211 | 2211 | ||
2212 | 2212 | ||
2213 | //! Bool interface for the above. | 2213 | //! Bool interface for the above. |
2214 | bool CD3D8Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) | 2214 | bool CD3D8Driver::setPixelShaderConstant(const c8* name, const bool* bools, int count) |
2215 | { | 2215 | { |
2216 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); | 2216 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); |
2217 | return false; | 2217 | return false; |
2218 | } | 2218 | } |
2219 | 2219 | ||
2220 | 2220 | ||
2221 | //! Int interface for the above. | 2221 | //! Int interface for the above. |
2222 | bool CD3D8Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) | 2222 | bool CD3D8Driver::setPixelShaderConstant(const c8* name, const s32* ints, int count) |
2223 | { | 2223 | { |
2224 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); | 2224 | os::Printer::log("Cannot set constant, no HLSL supported in D3D8"); |
2225 | return false; | 2225 | return false; |
2226 | } | 2226 | } |
2227 | 2227 | ||
2228 | 2228 | ||
2229 | //! Adds a new material renderer to the VideoDriver, using pixel and/or | 2229 | //! Adds a new material renderer to the VideoDriver, using pixel and/or |
2230 | //! vertex shaders to render geometry. | 2230 | //! vertex shaders to render geometry. |
2231 | s32 CD3D8Driver::addShaderMaterial(const c8* vertexShaderProgram, | 2231 | s32 CD3D8Driver::addShaderMaterial(const c8* vertexShaderProgram, |
2232 | const c8* pixelShaderProgram, | 2232 | const c8* pixelShaderProgram, |
2233 | IShaderConstantSetCallBack* callback, | 2233 | IShaderConstantSetCallBack* callback, |
2234 | E_MATERIAL_TYPE baseMaterial, s32 userData) | 2234 | E_MATERIAL_TYPE baseMaterial, s32 userData) |
2235 | { | 2235 | { |
2236 | s32 nr = -1; | 2236 | s32 nr = -1; |
2237 | CD3D8ShaderMaterialRenderer* r = new CD3D8ShaderMaterialRenderer( | 2237 | CD3D8ShaderMaterialRenderer* r = new CD3D8ShaderMaterialRenderer( |
2238 | pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, | 2238 | pID3DDevice, this, nr, vertexShaderProgram, pixelShaderProgram, |
2239 | callback, getMaterialRenderer(baseMaterial), userData); | 2239 | callback, getMaterialRenderer(baseMaterial), userData); |
2240 | 2240 | ||
2241 | r->drop(); | 2241 | r->drop(); |
2242 | return nr; | 2242 | return nr; |
2243 | } | 2243 | } |
2244 | 2244 | ||
2245 | 2245 | ||
2246 | //! Returns a pointer to the IVideoDriver interface. (Implementation for | 2246 | //! Returns a pointer to the IVideoDriver interface. (Implementation for |
2247 | //! IMaterialRendererServices) | 2247 | //! IMaterialRendererServices) |
2248 | IVideoDriver* CD3D8Driver::getVideoDriver() | 2248 | IVideoDriver* CD3D8Driver::getVideoDriver() |
2249 | { | 2249 | { |
2250 | return this; | 2250 | return this; |
2251 | } | 2251 | } |
2252 | 2252 | ||
2253 | 2253 | ||
2254 | //! Clears the ZBuffer. | 2254 | //! Clears the ZBuffer. |
2255 | void CD3D8Driver::clearZBuffer() | 2255 | void CD3D8Driver::clearZBuffer() |
2256 | { | 2256 | { |
2257 | const HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); | 2257 | const HRESULT hr = pID3DDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0, 0); |
2258 | 2258 | ||
2259 | if (FAILED(hr)) | 2259 | if (FAILED(hr)) |
2260 | os::Printer::log("CD3D8Driver clearZBuffer() failed.", ELL_WARNING); | 2260 | os::Printer::log("CD3D8Driver clearZBuffer() failed.", ELL_WARNING); |
2261 | } | 2261 | } |
2262 | 2262 | ||
2263 | 2263 | ||
2264 | //! Returns an image created from the last rendered frame. | 2264 | //! Returns an image created from the last rendered frame. |
2265 | IImage* CD3D8Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) | 2265 | IImage* CD3D8Driver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) |
2266 | { | 2266 | { |
2267 | #if defined( _IRR_XBOX_PLATFORM_) | 2267 | #if defined( _IRR_XBOX_PLATFORM_) |
2268 | return 0; | 2268 | return 0; |
2269 | #else | 2269 | #else |
2270 | if (target != video::ERT_FRAME_BUFFER) | 2270 | if (target != video::ERT_FRAME_BUFFER) |
2271 | return 0; | 2271 | return 0; |
2272 | 2272 | ||
2273 | // query the screen dimensions of the current adapter | 2273 | // query the screen dimensions of the current adapter |
2274 | D3DDISPLAYMODE displayMode; | 2274 | D3DDISPLAYMODE displayMode; |
2275 | pID3DDevice->GetDisplayMode(&displayMode); | 2275 | pID3DDevice->GetDisplayMode(&displayMode); |
2276 | 2276 | ||
2277 | if (format==video::ECF_UNKNOWN) | 2277 | if (format==video::ECF_UNKNOWN) |
2278 | format=video::ECF_A8R8G8B8; | 2278 | format=video::ECF_A8R8G8B8; |
2279 | 2279 | ||
2280 | // create the image surface to store the front buffer image [always A8R8G8B8] | 2280 | // create the image surface to store the front buffer image [always A8R8G8B8] |
2281 | HRESULT hr; | 2281 | HRESULT hr; |
2282 | LPDIRECT3DSURFACE8 lpSurface; | 2282 | LPDIRECT3DSURFACE8 lpSurface; |
2283 | if (FAILED(hr = pID3DDevice->CreateImageSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, &lpSurface))) | 2283 | if (FAILED(hr = pID3DDevice->CreateImageSurface(displayMode.Width, displayMode.Height, D3DFMT_A8R8G8B8, &lpSurface))) |
2284 | return 0; | 2284 | return 0; |
2285 | 2285 | ||
2286 | // read the front buffer into the image surface | 2286 | // read the front buffer into the image surface |
2287 | if (FAILED(hr = pID3DDevice->GetFrontBuffer(lpSurface))) | 2287 | if (FAILED(hr = pID3DDevice->GetFrontBuffer(lpSurface))) |
2288 | { | 2288 | { |
2289 | lpSurface->Release(); | 2289 | lpSurface->Release(); |
2290 | return 0; | 2290 | return 0; |
2291 | } | 2291 | } |
2292 | 2292 | ||
2293 | RECT clientRect; | 2293 | RECT clientRect; |
2294 | { | 2294 | { |
2295 | POINT clientPoint; | 2295 | POINT clientPoint; |
2296 | clientPoint.x = 0; | 2296 | clientPoint.x = 0; |
2297 | clientPoint.y = 0; | 2297 | clientPoint.y = 0; |
2298 | 2298 | ||
2299 | ClientToScreen( (HWND)getExposedVideoData().D3D8.HWnd, &clientPoint ); | 2299 | ClientToScreen( (HWND)getExposedVideoData().D3D8.HWnd, &clientPoint ); |
2300 | 2300 | ||
2301 | clientRect.left = clientPoint.x; | 2301 | clientRect.left = clientPoint.x; |
2302 | clientRect.top = clientPoint.y; | 2302 | clientRect.top = clientPoint.y; |
2303 | clientRect.right = clientRect.left + ScreenSize.Width; | 2303 | clientRect.right = clientRect.left + ScreenSize.Width; |
2304 | clientRect.bottom = clientRect.top + ScreenSize.Height; | 2304 | clientRect.bottom = clientRect.top + ScreenSize.Height; |
2305 | 2305 | ||
2306 | // window can be off-screen partly, we can't take screenshots from that | 2306 | // window can be off-screen partly, we can't take screenshots from that |
2307 | clientRect.left = core::max_(clientRect.left, 0l); | 2307 | clientRect.left = core::max_(clientRect.left, 0l); |
2308 | clientRect.top = core::max_(clientRect.top, 0l); | 2308 | clientRect.top = core::max_(clientRect.top, 0l); |
2309 | clientRect.right = core::min_(clientRect.right, (long)displayMode.Width); | 2309 | clientRect.right = core::min_(clientRect.right, (long)displayMode.Width); |
2310 | clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height ); | 2310 | clientRect.bottom = core::min_(clientRect.bottom, (long)displayMode.Height ); |
2311 | } | 2311 | } |
2312 | 2312 | ||
2313 | // lock our area of the surface | 2313 | // lock our area of the surface |
2314 | D3DLOCKED_RECT lockedRect; | 2314 | D3DLOCKED_RECT lockedRect; |
2315 | if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) | 2315 | if (FAILED(lpSurface->LockRect(&lockedRect, &clientRect, D3DLOCK_READONLY))) |
2316 | { | 2316 | { |
2317 | lpSurface->Release(); | 2317 | lpSurface->Release(); |
2318 | return 0; | 2318 | return 0; |
2319 | } | 2319 | } |
2320 | 2320 | ||
2321 | irr::core::dimension2d<u32> shotSize; | 2321 | irr::core::dimension2d<u32> shotSize; |
2322 | shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) ); | 2322 | shotSize.Width = core::min_( ScreenSize.Width, (u32)(clientRect.right-clientRect.left) ); |
2323 | shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) ); | 2323 | shotSize.Height = core::min_( ScreenSize.Height, (u32)(clientRect.bottom-clientRect.top) ); |
2324 | 2324 | ||
2325 | // this could throw, but we aren't going to worry about that case very much | 2325 | // this could throw, but we aren't going to worry about that case very much |
2326 | IImage* newImage = createImage(format, shotSize); | 2326 | IImage* newImage = createImage(format, shotSize); |
2327 | 2327 | ||
2328 | if (newImage) | 2328 | if (newImage) |
2329 | { | 2329 | { |
2330 | // d3d pads the image, so we need to copy the correct number of bytes | 2330 | // d3d pads the image, so we need to copy the correct number of bytes |
2331 | u32* dP = (u32*)newImage->lock(); | 2331 | u32* dP = (u32*)newImage->lock(); |
2332 | u8 * sP = (u8 *)lockedRect.pBits; | 2332 | u8 * sP = (u8 *)lockedRect.pBits; |
2333 | 2333 | ||
2334 | // If the display mode format doesn't promise anything about the Alpha value | 2334 | // If the display mode format doesn't promise anything about the Alpha value |
2335 | // and it appears that it's not presenting 255, then we should manually | 2335 | // and it appears that it's not presenting 255, then we should manually |
2336 | // set each pixel alpha value to 255. | 2336 | // set each pixel alpha value to 255. |
2337 | if(D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000))) | 2337 | if(D3DFMT_X8R8G8B8 == displayMode.Format && (0xFF000000 != (*dP & 0xFF000000))) |
2338 | { | 2338 | { |
2339 | for (u32 y = 0; y < shotSize.Height; ++y) | 2339 | for (u32 y = 0; y < shotSize.Height; ++y) |
2340 | { | 2340 | { |
2341 | for(u32 x = 0; x < shotSize.Width; ++x) | 2341 | for(u32 x = 0; x < shotSize.Width; ++x) |
2342 | { | 2342 | { |
2343 | newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000); | 2343 | newImage->setPixel(x,y,*((u32*)sP) | 0xFF000000); |
2344 | sP += 4; | 2344 | sP += 4; |
2345 | } | 2345 | } |
2346 | 2346 | ||
2347 | sP += lockedRect.Pitch - (4 * shotSize.Width); | 2347 | sP += lockedRect.Pitch - (4 * shotSize.Width); |
2348 | } | 2348 | } |
2349 | } | 2349 | } |
2350 | else | 2350 | else |
2351 | { | 2351 | { |
2352 | for (u32 y = 0; y < shotSize.Height; ++y) | 2352 | for (u32 y = 0; y < shotSize.Height; ++y) |
2353 | { | 2353 | { |
2354 | convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format); | 2354 | convertColor(sP, video::ECF_A8R8G8B8, shotSize.Width, dP, format); |
2355 | sP += lockedRect.Pitch; | 2355 | sP += lockedRect.Pitch; |
2356 | dP += shotSize.Width; | 2356 | dP += shotSize.Width; |
2357 | } | 2357 | } |
2358 | } | 2358 | } |
2359 | 2359 | ||
2360 | newImage->unlock(); | 2360 | newImage->unlock(); |
2361 | } | 2361 | } |
2362 | 2362 | ||
2363 | // we can unlock and release the surface | 2363 | // we can unlock and release the surface |
2364 | lpSurface->UnlockRect(); | 2364 | lpSurface->UnlockRect(); |
2365 | 2365 | ||
2366 | // release the image surface | 2366 | // release the image surface |
2367 | lpSurface->Release(); | 2367 | lpSurface->Release(); |
2368 | 2368 | ||
2369 | // return status of save operation to caller | 2369 | // return status of save operation to caller |
2370 | return newImage; | 2370 | return newImage; |
2371 | #endif | 2371 | #endif |
2372 | } | 2372 | } |
2373 | 2373 | ||
2374 | 2374 | ||
2375 | // returns the current size of the screen or rendertarget | 2375 | // returns the current size of the screen or rendertarget |
2376 | const core::dimension2d<u32>& CD3D8Driver::getCurrentRenderTargetSize() const | 2376 | const core::dimension2d<u32>& CD3D8Driver::getCurrentRenderTargetSize() const |
2377 | { | 2377 | { |
2378 | if ( CurrentRendertargetSize.Width == 0 ) | 2378 | if ( CurrentRendertargetSize.Width == 0 ) |
2379 | return ScreenSize; | 2379 | return ScreenSize; |
2380 | else | 2380 | else |
2381 | return CurrentRendertargetSize; | 2381 | return CurrentRendertargetSize; |
2382 | } | 2382 | } |
2383 | 2383 | ||
2384 | 2384 | ||
2385 | // Set/unset a clipping plane. | 2385 | // Set/unset a clipping plane. |
2386 | bool CD3D8Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) | 2386 | bool CD3D8Driver::setClipPlane(u32 index, const core::plane3df& plane, bool enable) |
2387 | { | 2387 | { |
2388 | #if defined( _IRR_XBOX_PLATFORM_) | 2388 | #if defined( _IRR_XBOX_PLATFORM_) |
2389 | return false; | 2389 | return false; |
2390 | #else | 2390 | #else |
2391 | if (index >= MaxUserClipPlanes) | 2391 | if (index >= MaxUserClipPlanes) |
2392 | return false; | 2392 | return false; |
2393 | pID3DDevice->SetClipPlane(index, (const float*)&plane); | 2393 | pID3DDevice->SetClipPlane(index, (const float*)&plane); |
2394 | enableClipPlane(index, enable); | 2394 | enableClipPlane(index, enable); |
2395 | return true; | 2395 | return true; |
2396 | #endif | 2396 | #endif |
2397 | } | 2397 | } |
2398 | 2398 | ||
2399 | 2399 | ||
2400 | // Enable/disable a clipping plane. | 2400 | // Enable/disable a clipping plane. |
2401 | void CD3D8Driver::enableClipPlane(u32 index, bool enable) | 2401 | void CD3D8Driver::enableClipPlane(u32 index, bool enable) |
2402 | { | 2402 | { |
2403 | #if defined( _IRR_XBOX_PLATFORM_) | 2403 | #if defined( _IRR_XBOX_PLATFORM_) |
2404 | return; | 2404 | return; |
2405 | #else | 2405 | #else |
2406 | if (index >= MaxUserClipPlanes) | 2406 | if (index >= MaxUserClipPlanes) |
2407 | return; | 2407 | return; |
2408 | DWORD renderstate; | 2408 | DWORD renderstate; |
2409 | pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); | 2409 | pID3DDevice->GetRenderState(D3DRS_CLIPPLANEENABLE, &renderstate); |
2410 | if (enable) | 2410 | if (enable) |
2411 | renderstate |= (1 << index); | 2411 | renderstate |= (1 << index); |
2412 | else | 2412 | else |
2413 | renderstate &= ~(1 << index); | 2413 | renderstate &= ~(1 << index); |
2414 | pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); | 2414 | pID3DDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, renderstate); |
2415 | #endif | 2415 | #endif |
2416 | } | 2416 | } |
2417 | 2417 | ||
2418 | 2418 | ||
2419 | core::dimension2du CD3D8Driver::getMaxTextureSize() const | 2419 | core::dimension2du CD3D8Driver::getMaxTextureSize() const |
2420 | { | 2420 | { |
2421 | return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight); | 2421 | return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight); |
2422 | } | 2422 | } |
2423 | 2423 | ||
2424 | 2424 | ||
2425 | } // end namespace video | 2425 | } // end namespace video |
2426 | } // end namespace irr | 2426 | } // end namespace irr |
2427 | 2427 | ||
2428 | #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ | 2428 | #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ |
2429 | 2429 | ||
2430 | 2430 | ||
2431 | namespace irr | 2431 | namespace irr |
2432 | { | 2432 | { |
2433 | namespace video | 2433 | namespace video |
2434 | { | 2434 | { |
2435 | 2435 | ||
2436 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ | 2436 | #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ |
2437 | //! creates a video driver | 2437 | //! creates a video driver |
2438 | IVideoDriver* createDirectX8Driver(const SIrrlichtCreationParameters& params, | 2438 | IVideoDriver* createDirectX8Driver(const SIrrlichtCreationParameters& params, |
2439 | io::IFileSystem* io, HWND window) | 2439 | io::IFileSystem* io, HWND window) |
2440 | { | 2440 | { |
2441 | const bool pureSoftware = false; | 2441 | const bool pureSoftware = false; |
2442 | CD3D8Driver* dx8 = new CD3D8Driver(params, io); | 2442 | CD3D8Driver* dx8 = new CD3D8Driver(params, io); |
2443 | 2443 | ||
2444 | if (!dx8->initDriver(window, pureSoftware)) | 2444 | if (!dx8->initDriver(window, pureSoftware)) |
2445 | { | 2445 | { |
2446 | dx8->drop(); | 2446 | dx8->drop(); |
2447 | dx8 = 0; | 2447 | dx8 = 0; |
2448 | } | 2448 | } |
2449 | 2449 | ||
2450 | return dx8; | 2450 | return dx8; |
2451 | } | 2451 | } |
2452 | #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ | 2452 | #endif // _IRR_COMPILE_WITH_DIRECT3D_8_ |
2453 | 2453 | ||
2454 | } // end namespace video | 2454 | } // end namespace video |
2455 | } // end namespace irr | 2455 | } // end namespace irr |