aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver.cpp')
-rw-r--r--libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver.cpp1946
1 files changed, 973 insertions, 973 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver.cpp b/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver.cpp
index e079b07..794b79b 100644
--- a/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver.cpp
+++ b/libraries/irrlicht-1.8/source/Irrlicht/CSoftwareDriver.cpp
@@ -1,973 +1,973 @@
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#include "CSoftwareDriver.h" 6#include "CSoftwareDriver.h"
7 7
8#ifdef _IRR_COMPILE_WITH_SOFTWARE_ 8#ifdef _IRR_COMPILE_WITH_SOFTWARE_
9 9
10#include "CSoftwareTexture.h" 10#include "CSoftwareTexture.h"
11#include "CBlit.h" 11#include "CBlit.h"
12#include "os.h" 12#include "os.h"
13#include "S3DVertex.h" 13#include "S3DVertex.h"
14 14
15namespace irr 15namespace irr
16{ 16{
17namespace video 17namespace video
18{ 18{
19 19
20 20
21//! constructor 21//! constructor
22CSoftwareDriver::CSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) 22CSoftwareDriver::CSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter)
23: CNullDriver(io, windowSize), BackBuffer(0), Presenter(presenter), WindowId(0), 23: CNullDriver(io, windowSize), BackBuffer(0), Presenter(presenter), WindowId(0),
24 SceneSourceRect(0), RenderTargetTexture(0), RenderTargetSurface(0), 24 SceneSourceRect(0), RenderTargetTexture(0), RenderTargetSurface(0),
25 CurrentTriangleRenderer(0), ZBuffer(0), Texture(0) 25 CurrentTriangleRenderer(0), ZBuffer(0), Texture(0)
26{ 26{
27 #ifdef _DEBUG 27 #ifdef _DEBUG
28 setDebugName("CSoftwareDriver"); 28 setDebugName("CSoftwareDriver");
29 #endif 29 #endif
30 30
31 // create backbuffer 31 // create backbuffer
32 32
33 BackBuffer = new CImage(ECF_A1R5G5B5, windowSize); 33 BackBuffer = new CImage(ECF_A1R5G5B5, windowSize);
34 if (BackBuffer) 34 if (BackBuffer)
35 { 35 {
36 BackBuffer->fill(SColor(0)); 36 BackBuffer->fill(SColor(0));
37 37
38 // create z buffer 38 // create z buffer
39 ZBuffer = video::createZBuffer(BackBuffer->getDimension()); 39 ZBuffer = video::createZBuffer(BackBuffer->getDimension());
40 } 40 }
41 41
42 DriverAttributes->setAttribute("MaxTextures", 1); 42 DriverAttributes->setAttribute("MaxTextures", 1);
43 DriverAttributes->setAttribute("MaxIndices", 1<<16); 43 DriverAttributes->setAttribute("MaxIndices", 1<<16);
44 DriverAttributes->setAttribute("MaxTextureSize", 1024); 44 DriverAttributes->setAttribute("MaxTextureSize", 1024);
45 DriverAttributes->setAttribute("Version", 1); 45 DriverAttributes->setAttribute("Version", 1);
46 46
47 // create triangle renderers 47 // create triangle renderers
48 48
49 TriangleRenderers[ETR_FLAT] = createTriangleRendererFlat(ZBuffer); 49 TriangleRenderers[ETR_FLAT] = createTriangleRendererFlat(ZBuffer);
50 TriangleRenderers[ETR_FLAT_WIRE] = createTriangleRendererFlatWire(ZBuffer); 50 TriangleRenderers[ETR_FLAT_WIRE] = createTriangleRendererFlatWire(ZBuffer);
51 TriangleRenderers[ETR_GOURAUD] = createTriangleRendererGouraud(ZBuffer); 51 TriangleRenderers[ETR_GOURAUD] = createTriangleRendererGouraud(ZBuffer);
52 TriangleRenderers[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire(ZBuffer); 52 TriangleRenderers[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire(ZBuffer);
53 TriangleRenderers[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat(ZBuffer); 53 TriangleRenderers[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat(ZBuffer);
54 TriangleRenderers[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire(ZBuffer); 54 TriangleRenderers[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire(ZBuffer);
55 TriangleRenderers[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud(ZBuffer); 55 TriangleRenderers[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud(ZBuffer);
56 TriangleRenderers[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire(ZBuffer); 56 TriangleRenderers[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire(ZBuffer);
57 TriangleRenderers[ETR_TEXTURE_GOURAUD_NOZ] = createTriangleRendererTextureGouraudNoZ(); 57 TriangleRenderers[ETR_TEXTURE_GOURAUD_NOZ] = createTriangleRendererTextureGouraudNoZ();
58 TriangleRenderers[ETR_TEXTURE_GOURAUD_ADD] = createTriangleRendererTextureGouraudAdd(ZBuffer); 58 TriangleRenderers[ETR_TEXTURE_GOURAUD_ADD] = createTriangleRendererTextureGouraudAdd(ZBuffer);
59 59
60 // select render target 60 // select render target
61 61
62 setRenderTarget(BackBuffer); 62 setRenderTarget(BackBuffer);
63 63
64 // select the right renderer 64 // select the right renderer
65 65
66 selectRightTriangleRenderer(); 66 selectRightTriangleRenderer();
67} 67}
68 68
69 69
70 70
71//! destructor 71//! destructor
72CSoftwareDriver::~CSoftwareDriver() 72CSoftwareDriver::~CSoftwareDriver()
73{ 73{
74 // delete Backbuffer 74 // delete Backbuffer
75 if (BackBuffer) 75 if (BackBuffer)
76 BackBuffer->drop(); 76 BackBuffer->drop();
77 77
78 // delete triangle renderers 78 // delete triangle renderers
79 79
80 for (s32 i=0; i<ETR_COUNT; ++i) 80 for (s32 i=0; i<ETR_COUNT; ++i)
81 if (TriangleRenderers[i]) 81 if (TriangleRenderers[i])
82 TriangleRenderers[i]->drop(); 82 TriangleRenderers[i]->drop();
83 83
84 // delete zbuffer 84 // delete zbuffer
85 85
86 if (ZBuffer) 86 if (ZBuffer)
87 ZBuffer->drop(); 87 ZBuffer->drop();
88 88
89 // delete current texture 89 // delete current texture
90 90
91 if (Texture) 91 if (Texture)
92 Texture->drop(); 92 Texture->drop();
93 93
94 if (RenderTargetTexture) 94 if (RenderTargetTexture)
95 RenderTargetTexture->drop(); 95 RenderTargetTexture->drop();
96 96
97 if (RenderTargetSurface) 97 if (RenderTargetSurface)
98 RenderTargetSurface->drop(); 98 RenderTargetSurface->drop();
99} 99}
100 100
101 101
102 102
103//! switches to a triangle renderer 103//! switches to a triangle renderer
104void CSoftwareDriver::switchToTriangleRenderer(ETriangleRenderer renderer) 104void CSoftwareDriver::switchToTriangleRenderer(ETriangleRenderer renderer)
105{ 105{
106 video::IImage* s = 0; 106 video::IImage* s = 0;
107 if (Texture) 107 if (Texture)
108 s = ((CSoftwareTexture*)Texture)->getTexture(); 108 s = ((CSoftwareTexture*)Texture)->getTexture();
109 109
110 CurrentTriangleRenderer = TriangleRenderers[renderer]; 110 CurrentTriangleRenderer = TriangleRenderers[renderer];
111 CurrentTriangleRenderer->setBackfaceCulling(Material.BackfaceCulling == true); 111 CurrentTriangleRenderer->setBackfaceCulling(Material.BackfaceCulling == true);
112 CurrentTriangleRenderer->setTexture(s); 112 CurrentTriangleRenderer->setTexture(s);
113 CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort); 113 CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort);
114} 114}
115 115
116 116
117//! void selects the right triangle renderer based on the render states. 117//! void selects the right triangle renderer based on the render states.
118void CSoftwareDriver::selectRightTriangleRenderer() 118void CSoftwareDriver::selectRightTriangleRenderer()
119{ 119{
120 120
121 ETriangleRenderer renderer = ETR_FLAT; 121 ETriangleRenderer renderer = ETR_FLAT;
122 122
123 if (Texture) 123 if (Texture)
124 { 124 {
125 if (!Material.GouraudShading) 125 if (!Material.GouraudShading)
126 renderer = (!Material.Wireframe) ? ETR_TEXTURE_FLAT : ETR_TEXTURE_FLAT_WIRE; 126 renderer = (!Material.Wireframe) ? ETR_TEXTURE_FLAT : ETR_TEXTURE_FLAT_WIRE;
127 else 127 else
128 { 128 {
129 if (Material.Wireframe) 129 if (Material.Wireframe)
130 renderer = ETR_TEXTURE_GOURAUD_WIRE; 130 renderer = ETR_TEXTURE_GOURAUD_WIRE;
131 else 131 else
132 { 132 {
133 if (Material.MaterialType == EMT_TRANSPARENT_ADD_COLOR || 133 if (Material.MaterialType == EMT_TRANSPARENT_ADD_COLOR ||
134 Material.MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL || 134 Material.MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL ||
135 Material.MaterialType == EMT_TRANSPARENT_VERTEX_ALPHA) 135 Material.MaterialType == EMT_TRANSPARENT_VERTEX_ALPHA)
136 { 136 {
137 // simply draw all transparent stuff with the same renderer. at 137 // simply draw all transparent stuff with the same renderer. at
138 // least it is transparent then. 138 // least it is transparent then.
139 renderer = ETR_TEXTURE_GOURAUD_ADD; 139 renderer = ETR_TEXTURE_GOURAUD_ADD;
140 } 140 }
141 else 141 else
142 if ((Material.ZBuffer==ECFN_NEVER) && !Material.ZWriteEnable) 142 if ((Material.ZBuffer==ECFN_NEVER) && !Material.ZWriteEnable)
143 renderer = ETR_TEXTURE_GOURAUD_NOZ; 143 renderer = ETR_TEXTURE_GOURAUD_NOZ;
144 else 144 else
145 { 145 {
146 renderer = ETR_TEXTURE_GOURAUD; 146 renderer = ETR_TEXTURE_GOURAUD;
147 } 147 }
148 } 148 }
149 } 149 }
150 } 150 }
151 else 151 else
152 { 152 {
153 if (!Material.GouraudShading) 153 if (!Material.GouraudShading)
154 renderer = (!Material.Wireframe) ? ETR_FLAT : ETR_FLAT_WIRE; 154 renderer = (!Material.Wireframe) ? ETR_FLAT : ETR_FLAT_WIRE;
155 else 155 else
156 renderer = (!Material.Wireframe) ? ETR_GOURAUD : ETR_GOURAUD_WIRE; 156 renderer = (!Material.Wireframe) ? ETR_GOURAUD : ETR_GOURAUD_WIRE;
157 } 157 }
158 158
159 switchToTriangleRenderer(renderer); 159 switchToTriangleRenderer(renderer);
160} 160}
161 161
162 162
163//! queries the features of the driver, returns true if feature is available 163//! queries the features of the driver, returns true if feature is available
164bool CSoftwareDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const 164bool CSoftwareDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
165{ 165{
166 switch (feature) 166 switch (feature)
167 { 167 {
168 case EVDF_RENDER_TO_TARGET: 168 case EVDF_RENDER_TO_TARGET:
169 case EVDF_TEXTURE_NSQUARE: 169 case EVDF_TEXTURE_NSQUARE:
170 return FeatureEnabled[feature]; 170 return FeatureEnabled[feature];
171 default: 171 default:
172 return false; 172 return false;
173 }; 173 };
174} 174}
175 175
176 176
177//! sets transformation 177//! sets transformation
178void CSoftwareDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) 178void CSoftwareDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
179{ 179{
180 TransformationMatrix[state] = mat; 180 TransformationMatrix[state] = mat;
181} 181}
182 182
183 183
184//! sets the current Texture 184//! sets the current Texture
185bool CSoftwareDriver::setActiveTexture(u32 stage, video::ITexture* texture) 185bool CSoftwareDriver::setActiveTexture(u32 stage, video::ITexture* texture)
186{ 186{
187 if (texture && texture->getDriverType() != EDT_SOFTWARE) 187 if (texture && texture->getDriverType() != EDT_SOFTWARE)
188 { 188 {
189 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); 189 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
190 return false; 190 return false;
191 } 191 }
192 192
193 if (Texture) 193 if (Texture)
194 Texture->drop(); 194 Texture->drop();
195 195
196 Texture = texture; 196 Texture = texture;
197 197
198 if (Texture) 198 if (Texture)
199 Texture->grab(); 199 Texture->grab();
200 200
201 selectRightTriangleRenderer(); 201 selectRightTriangleRenderer();
202 return true; 202 return true;
203} 203}
204 204
205 205
206//! sets a material 206//! sets a material
207void CSoftwareDriver::setMaterial(const SMaterial& material) 207void CSoftwareDriver::setMaterial(const SMaterial& material)
208{ 208{
209 Material = material; 209 Material = material;
210 OverrideMaterial.apply(Material); 210 OverrideMaterial.apply(Material);
211 211
212 for (u32 i = 0; i < 1; ++i) 212 for (u32 i = 0; i < 1; ++i)
213 { 213 {
214 setActiveTexture(i, Material.getTexture(i)); 214 setActiveTexture(i, Material.getTexture(i));
215 setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ), 215 setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ),
216 material.getTextureMatrix(i)); 216 material.getTextureMatrix(i));
217 } 217 }
218} 218}
219 219
220 220
221//! clears the zbuffer 221//! clears the zbuffer
222bool CSoftwareDriver::beginScene(bool backBuffer, bool zBuffer, SColor color, 222bool CSoftwareDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
223 const SExposedVideoData& videoData, core::rect<s32>* sourceRect) 223 const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
224{ 224{
225 CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect); 225 CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect);
226 WindowId=videoData.D3D9.HWnd; 226 WindowId=videoData.D3D9.HWnd;
227 SceneSourceRect = sourceRect; 227 SceneSourceRect = sourceRect;
228 228
229 if (backBuffer && BackBuffer) 229 if (backBuffer && BackBuffer)
230 BackBuffer->fill(color); 230 BackBuffer->fill(color);
231 231
232 if (ZBuffer && zBuffer) 232 if (ZBuffer && zBuffer)
233 ZBuffer->clear(); 233 ZBuffer->clear();
234 234
235 return true; 235 return true;
236} 236}
237 237
238 238
239//! presents the rendered scene on the screen, returns false if failed 239//! presents the rendered scene on the screen, returns false if failed
240bool CSoftwareDriver::endScene() 240bool CSoftwareDriver::endScene()
241{ 241{
242 CNullDriver::endScene(); 242 CNullDriver::endScene();
243 243
244 return Presenter->present(BackBuffer, WindowId, SceneSourceRect); 244 return Presenter->present(BackBuffer, WindowId, SceneSourceRect);
245} 245}
246 246
247 247
248//! returns a device dependent texture from a software surface (IImage) 248//! returns a device dependent texture from a software surface (IImage)
249//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES 249//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
250ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData) 250ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
251{ 251{
252 return new CSoftwareTexture(surface, name, false, mipmapData); 252 return new CSoftwareTexture(surface, name, false, mipmapData);
253} 253}
254 254
255 255
256//! sets a render target 256//! sets a render target
257bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, 257bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
258 bool clearZBuffer, SColor color) 258 bool clearZBuffer, SColor color)
259{ 259{
260 if (texture && texture->getDriverType() != EDT_SOFTWARE) 260 if (texture && texture->getDriverType() != EDT_SOFTWARE)
261 { 261 {
262 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR); 262 os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
263 return false; 263 return false;
264 } 264 }
265 265
266 if (RenderTargetTexture) 266 if (RenderTargetTexture)
267 RenderTargetTexture->drop(); 267 RenderTargetTexture->drop();
268 268
269 RenderTargetTexture = texture; 269 RenderTargetTexture = texture;
270 270
271 if (RenderTargetTexture) 271 if (RenderTargetTexture)
272 { 272 {
273 RenderTargetTexture->grab(); 273 RenderTargetTexture->grab();
274 setRenderTarget(((CSoftwareTexture*)RenderTargetTexture)->getTexture()); 274 setRenderTarget(((CSoftwareTexture*)RenderTargetTexture)->getTexture());
275 } 275 }
276 else 276 else
277 { 277 {
278 setRenderTarget(BackBuffer); 278 setRenderTarget(BackBuffer);
279 } 279 }
280 280
281 if (RenderTargetSurface && (clearBackBuffer || clearZBuffer)) 281 if (RenderTargetSurface && (clearBackBuffer || clearZBuffer))
282 { 282 {
283 if (clearZBuffer) 283 if (clearZBuffer)
284 ZBuffer->clear(); 284 ZBuffer->clear();
285 285
286 if (clearBackBuffer) 286 if (clearBackBuffer)
287 RenderTargetSurface->fill(color); 287 RenderTargetSurface->fill(color);
288 } 288 }
289 289
290 return true; 290 return true;
291} 291}
292 292
293 293
294//! sets a render target 294//! sets a render target
295void CSoftwareDriver::setRenderTarget(video::CImage* image) 295void CSoftwareDriver::setRenderTarget(video::CImage* image)
296{ 296{
297 if (RenderTargetSurface) 297 if (RenderTargetSurface)
298 RenderTargetSurface->drop(); 298 RenderTargetSurface->drop();
299 299
300 RenderTargetSurface = image; 300 RenderTargetSurface = image;
301 RenderTargetSize.Width = 0; 301 RenderTargetSize.Width = 0;
302 RenderTargetSize.Height = 0; 302 RenderTargetSize.Height = 0;
303 Render2DTranslation.X = 0; 303 Render2DTranslation.X = 0;
304 Render2DTranslation.Y = 0; 304 Render2DTranslation.Y = 0;
305 305
306 if (RenderTargetSurface) 306 if (RenderTargetSurface)
307 { 307 {
308 RenderTargetSurface->grab(); 308 RenderTargetSurface->grab();
309 RenderTargetSize = RenderTargetSurface->getDimension(); 309 RenderTargetSize = RenderTargetSurface->getDimension();
310 } 310 }
311 311
312 setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height)); 312 setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height));
313 313
314 if (ZBuffer) 314 if (ZBuffer)
315 ZBuffer->setSize(RenderTargetSize); 315 ZBuffer->setSize(RenderTargetSize);
316} 316}
317 317
318 318
319//! sets a viewport 319//! sets a viewport
320void CSoftwareDriver::setViewPort(const core::rect<s32>& area) 320void CSoftwareDriver::setViewPort(const core::rect<s32>& area)
321{ 321{
322 ViewPort = area; 322 ViewPort = area;
323 323
324 //TODO: the clipping is not correct, because the projection is affected. 324 //TODO: the clipping is not correct, because the projection is affected.
325 // to correct this, ViewPortSize and Render2DTranslation will have to be corrected. 325 // to correct this, ViewPortSize and Render2DTranslation will have to be corrected.
326 core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height); 326 core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height);
327 ViewPort.clipAgainst(rendert); 327 ViewPort.clipAgainst(rendert);
328 328
329 ViewPortSize = core::dimension2du(ViewPort.getSize()); 329 ViewPortSize = core::dimension2du(ViewPort.getSize());
330 Render2DTranslation.X = (ViewPortSize.Width / 2) + ViewPort.UpperLeftCorner.X; 330 Render2DTranslation.X = (ViewPortSize.Width / 2) + ViewPort.UpperLeftCorner.X;
331 Render2DTranslation.Y = ViewPort.UpperLeftCorner.Y + ViewPortSize.Height - (ViewPortSize.Height / 2);// + ViewPort.UpperLeftCorner.Y; 331 Render2DTranslation.Y = ViewPort.UpperLeftCorner.Y + ViewPortSize.Height - (ViewPortSize.Height / 2);// + ViewPort.UpperLeftCorner.Y;
332 332
333 if (CurrentTriangleRenderer) 333 if (CurrentTriangleRenderer)
334 CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort); 334 CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort);
335} 335}
336 336
337 337
338void CSoftwareDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount, 338void CSoftwareDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
339 const void* indexList, u32 primitiveCount, 339 const void* indexList, u32 primitiveCount,
340 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) 340 E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
341 341
342{ 342{
343 switch (iType) 343 switch (iType)
344 { 344 {
345 case (EIT_16BIT): 345 case (EIT_16BIT):
346 { 346 {
347 drawVertexPrimitiveList16(vertices, vertexCount, (const u16*)indexList, primitiveCount, vType, pType); 347 drawVertexPrimitiveList16(vertices, vertexCount, (const u16*)indexList, primitiveCount, vType, pType);
348 break; 348 break;
349 } 349 }
350 case (EIT_32BIT): 350 case (EIT_32BIT):
351 { 351 {
352 os::Printer::log("Software driver can not render 32bit buffers", ELL_ERROR); 352 os::Printer::log("Software driver can not render 32bit buffers", ELL_ERROR);
353 break; 353 break;
354 } 354 }
355 } 355 }
356} 356}
357 357
358 358
359//! draws a vertex primitive list 359//! draws a vertex primitive list
360void CSoftwareDriver::drawVertexPrimitiveList16(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType) 360void CSoftwareDriver::drawVertexPrimitiveList16(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType)
361{ 361{
362 const u16* indexPointer=0; 362 const u16* indexPointer=0;
363 core::array<u16> newBuffer; 363 core::array<u16> newBuffer;
364 switch (pType) 364 switch (pType)
365 { 365 {
366 case scene::EPT_LINE_STRIP: 366 case scene::EPT_LINE_STRIP:
367 { 367 {
368 switch (vType) 368 switch (vType)
369 { 369 {
370 case EVT_STANDARD: 370 case EVT_STANDARD:
371 { 371 {
372 for (u32 i=0; i < primitiveCount-1; ++i) 372 for (u32 i=0; i < primitiveCount-1; ++i)
373 draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos, 373 draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos,
374 ((S3DVertex*)vertices)[indexList[i+1]].Pos, 374 ((S3DVertex*)vertices)[indexList[i+1]].Pos,
375 ((S3DVertex*)vertices)[indexList[i]].Color); 375 ((S3DVertex*)vertices)[indexList[i]].Color);
376 } 376 }
377 break; 377 break;
378 case EVT_2TCOORDS: 378 case EVT_2TCOORDS:
379 { 379 {
380 for (u32 i=0; i < primitiveCount-1; ++i) 380 for (u32 i=0; i < primitiveCount-1; ++i)
381 draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos, 381 draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos,
382 ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos, 382 ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos,
383 ((S3DVertex2TCoords*)vertices)[indexList[i]].Color); 383 ((S3DVertex2TCoords*)vertices)[indexList[i]].Color);
384 } 384 }
385 break; 385 break;
386 case EVT_TANGENTS: 386 case EVT_TANGENTS:
387 { 387 {
388 for (u32 i=0; i < primitiveCount-1; ++i) 388 for (u32 i=0; i < primitiveCount-1; ++i)
389 draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos, 389 draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos,
390 ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos, 390 ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos,
391 ((S3DVertexTangents*)vertices)[indexList[i]].Color); 391 ((S3DVertexTangents*)vertices)[indexList[i]].Color);
392 } 392 }
393 break; 393 break;
394 } 394 }
395 } 395 }
396 return; 396 return;
397 case scene::EPT_LINE_LOOP: 397 case scene::EPT_LINE_LOOP:
398 drawVertexPrimitiveList16(vertices, vertexCount, indexList, primitiveCount-1, vType, scene::EPT_LINE_STRIP); 398 drawVertexPrimitiveList16(vertices, vertexCount, indexList, primitiveCount-1, vType, scene::EPT_LINE_STRIP);
399 switch (vType) 399 switch (vType)
400 { 400 {
401 case EVT_STANDARD: 401 case EVT_STANDARD:
402 draw3DLine(((S3DVertex*)vertices)[indexList[primitiveCount-1]].Pos, 402 draw3DLine(((S3DVertex*)vertices)[indexList[primitiveCount-1]].Pos,
403 ((S3DVertex*)vertices)[indexList[0]].Pos, 403 ((S3DVertex*)vertices)[indexList[0]].Pos,
404 ((S3DVertex*)vertices)[indexList[primitiveCount-1]].Color); 404 ((S3DVertex*)vertices)[indexList[primitiveCount-1]].Color);
405 break; 405 break;
406 case EVT_2TCOORDS: 406 case EVT_2TCOORDS:
407 draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Pos, 407 draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Pos,
408 ((S3DVertex2TCoords*)vertices)[indexList[0]].Pos, 408 ((S3DVertex2TCoords*)vertices)[indexList[0]].Pos,
409 ((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Color); 409 ((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Color);
410 break; 410 break;
411 case EVT_TANGENTS: 411 case EVT_TANGENTS:
412 draw3DLine(((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Pos, 412 draw3DLine(((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Pos,
413 ((S3DVertexTangents*)vertices)[indexList[0]].Pos, 413 ((S3DVertexTangents*)vertices)[indexList[0]].Pos,
414 ((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Color); 414 ((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Color);
415 break; 415 break;
416 } 416 }
417 return; 417 return;
418 case scene::EPT_LINES: 418 case scene::EPT_LINES:
419 { 419 {
420 switch (vType) 420 switch (vType)
421 { 421 {
422 case EVT_STANDARD: 422 case EVT_STANDARD:
423 { 423 {
424 for (u32 i=0; i < 2*primitiveCount; i+=2) 424 for (u32 i=0; i < 2*primitiveCount; i+=2)
425 draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos, 425 draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos,
426 ((S3DVertex*)vertices)[indexList[i+1]].Pos, 426 ((S3DVertex*)vertices)[indexList[i+1]].Pos,
427 ((S3DVertex*)vertices)[indexList[i]].Color); 427 ((S3DVertex*)vertices)[indexList[i]].Color);
428 } 428 }
429 break; 429 break;
430 case EVT_2TCOORDS: 430 case EVT_2TCOORDS:
431 { 431 {
432 for (u32 i=0; i < 2*primitiveCount; i+=2) 432 for (u32 i=0; i < 2*primitiveCount; i+=2)
433 draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos, 433 draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos,
434 ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos, 434 ((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos,
435 ((S3DVertex2TCoords*)vertices)[indexList[i]].Color); 435 ((S3DVertex2TCoords*)vertices)[indexList[i]].Color);
436 } 436 }
437 break; 437 break;
438 case EVT_TANGENTS: 438 case EVT_TANGENTS:
439 { 439 {
440 for (u32 i=0; i < 2*primitiveCount; i+=2) 440 for (u32 i=0; i < 2*primitiveCount; i+=2)
441 draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos, 441 draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos,
442 ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos, 442 ((S3DVertexTangents*)vertices)[indexList[i+1]].Pos,
443 ((S3DVertexTangents*)vertices)[indexList[i]].Color); 443 ((S3DVertexTangents*)vertices)[indexList[i]].Color);
444 } 444 }
445 break; 445 break;
446 } 446 }
447 } 447 }
448 return; 448 return;
449 case scene::EPT_TRIANGLE_FAN: 449 case scene::EPT_TRIANGLE_FAN:
450 { 450 {
451 // TODO: don't convert fan to list 451 // TODO: don't convert fan to list
452 newBuffer.reallocate(primitiveCount*3); 452 newBuffer.reallocate(primitiveCount*3);
453 for( u32 t=0; t<primitiveCount; ++t ) 453 for( u32 t=0; t<primitiveCount; ++t )
454 { 454 {
455 newBuffer.push_back(indexList[0]); 455 newBuffer.push_back(indexList[0]);
456 newBuffer.push_back(indexList[t+1]); 456 newBuffer.push_back(indexList[t+1]);
457 newBuffer.push_back(indexList[t+2]); 457 newBuffer.push_back(indexList[t+2]);
458 } 458 }
459 459
460 indexPointer = newBuffer.pointer(); 460 indexPointer = newBuffer.pointer();
461 } 461 }
462 break; 462 break;
463 case scene::EPT_TRIANGLES: 463 case scene::EPT_TRIANGLES:
464 indexPointer=indexList; 464 indexPointer=indexList;
465 break; 465 break;
466 default: 466 default:
467 return; 467 return;
468 } 468 }
469 switch (vType) 469 switch (vType)
470 { 470 {
471 case EVT_STANDARD: 471 case EVT_STANDARD:
472 drawClippedIndexedTriangleListT((S3DVertex*)vertices, vertexCount, indexPointer, primitiveCount); 472 drawClippedIndexedTriangleListT((S3DVertex*)vertices, vertexCount, indexPointer, primitiveCount);
473 break; 473 break;
474 case EVT_2TCOORDS: 474 case EVT_2TCOORDS:
475 drawClippedIndexedTriangleListT((S3DVertex2TCoords*)vertices, vertexCount, indexPointer, primitiveCount); 475 drawClippedIndexedTriangleListT((S3DVertex2TCoords*)vertices, vertexCount, indexPointer, primitiveCount);
476 break; 476 break;
477 case EVT_TANGENTS: 477 case EVT_TANGENTS:
478 drawClippedIndexedTriangleListT((S3DVertexTangents*)vertices, vertexCount, indexPointer, primitiveCount); 478 drawClippedIndexedTriangleListT((S3DVertexTangents*)vertices, vertexCount, indexPointer, primitiveCount);
479 break; 479 break;
480 } 480 }
481} 481}
482 482
483 483
484template<class VERTEXTYPE> 484template<class VERTEXTYPE>
485void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices, 485void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices,
486 s32 vertexCount, const u16* indexList, s32 triangleCount) 486 s32 vertexCount, const u16* indexList, s32 triangleCount)
487{ 487{
488 if (!RenderTargetSurface || !ZBuffer || !triangleCount) 488 if (!RenderTargetSurface || !ZBuffer || !triangleCount)
489 return; 489 return;
490 490
491 if (!checkPrimitiveCount(triangleCount)) 491 if (!checkPrimitiveCount(triangleCount))
492 return; 492 return;
493 493
494 // arrays for storing clipped vertices 494 // arrays for storing clipped vertices
495 core::array<VERTEXTYPE> clippedVertices; 495 core::array<VERTEXTYPE> clippedVertices;
496 core::array<u16> clippedIndices; 496 core::array<u16> clippedIndices;
497 497
498 // calculate inverse world transformation 498 // calculate inverse world transformation
499 core::matrix4 worldinv(TransformationMatrix[ETS_WORLD]); 499 core::matrix4 worldinv(TransformationMatrix[ETS_WORLD]);
500 worldinv.makeInverse(); 500 worldinv.makeInverse();
501 501
502 // calculate view frustum planes 502 // calculate view frustum planes
503 scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW]); 503 scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW]);
504 504
505 // copy and transform clipping planes ignoring far plane 505 // copy and transform clipping planes ignoring far plane
506 core::plane3df planes[5]; // ordered by near, left, right, bottom, top 506 core::plane3df planes[5]; // ordered by near, left, right, bottom, top
507 for (int p=0; p<5; ++p) 507 for (int p=0; p<5; ++p)
508 worldinv.transformPlane(frustum.planes[p+1], planes[p]); 508 worldinv.transformPlane(frustum.planes[p+1], planes[p]);
509 509
510 core::EIntersectionRelation3D inout[3]; // is point in front or back of plane? 510 core::EIntersectionRelation3D inout[3]; // is point in front or back of plane?
511 511
512 // temporary buffer for vertices to be clipped by all planes 512 // temporary buffer for vertices to be clipped by all planes
513 core::array<VERTEXTYPE> tClpBuf; 513 core::array<VERTEXTYPE> tClpBuf;
514 int t; 514 int t;
515 515
516 int i; 516 int i;
517 for (i=0; i<triangleCount; ++i) // for all input triangles 517 for (i=0; i<triangleCount; ++i) // for all input triangles
518 { 518 {
519 // add next triangle to tempClipBuffer 519 // add next triangle to tempClipBuffer
520 for (t=0; t<3; ++t) 520 for (t=0; t<3; ++t)
521 tClpBuf.push_back(vertices[indexList[(i*3)+t]]); 521 tClpBuf.push_back(vertices[indexList[(i*3)+t]]);
522 522
523 for (int p=0; p<5; ++p) // for all clip planes 523 for (int p=0; p<5; ++p) // for all clip planes
524 for (int v=0; v<(int)tClpBuf.size(); v+=3) // for all vertices in temp clip buffer 524 for (int v=0; v<(int)tClpBuf.size(); v+=3) // for all vertices in temp clip buffer
525 { 525 {
526 int inside = 0; 526 int inside = 0;
527 int outside = 0; 527 int outside = 0;
528 528
529 // test intersection relation of the current vertices 529 // test intersection relation of the current vertices
530 for (t=0; t<3; ++t) 530 for (t=0; t<3; ++t)
531 { 531 {
532 inout[t] = planes[p].classifyPointRelation(tClpBuf[v+t].Pos); 532 inout[t] = planes[p].classifyPointRelation(tClpBuf[v+t].Pos);
533 if (inout[t] != core::ISREL3D_FRONT) 533 if (inout[t] != core::ISREL3D_FRONT)
534 ++inside; 534 ++inside;
535 else 535 else
536 if (inout[t] == core::ISREL3D_FRONT) 536 if (inout[t] == core::ISREL3D_FRONT)
537 ++outside; 537 ++outside;
538 } 538 }
539 539
540 if (!outside) 540 if (!outside)
541 { 541 {
542 // add all vertices to new buffer, this triangle needs no clipping. 542 // add all vertices to new buffer, this triangle needs no clipping.
543 // so simply don't change this part of the temporary triangle buffer 543 // so simply don't change this part of the temporary triangle buffer
544 continue; 544 continue;
545 } 545 }
546 546
547 if (!inside) 547 if (!inside)
548 { 548 {
549 // all vertices are outside, don't add this triangle, so erase this 549 // all vertices are outside, don't add this triangle, so erase this
550 // triangle from the tClpBuf 550 // triangle from the tClpBuf
551 tClpBuf.erase(v,3); 551 tClpBuf.erase(v,3);
552 v -= 3; 552 v -= 3;
553 continue; 553 continue;
554 } 554 }
555 555
556 // this vertex has to be clipped by this clipping plane. 556 // this vertex has to be clipped by this clipping plane.
557 557
558 // The following lines represent my try to implement some real clipping. 558 // The following lines represent my try to implement some real clipping.
559 // There is a bug somewhere, and after some time I've given up. 559 // There is a bug somewhere, and after some time I've given up.
560 // So now it is commented out, resulting that triangles which would need clipping 560 // So now it is commented out, resulting that triangles which would need clipping
561 // are simply taken out (in the next two lines). 561 // are simply taken out (in the next two lines).
562#ifndef __SOFTWARE_CLIPPING_PROBLEM__ 562#ifndef __SOFTWARE_CLIPPING_PROBLEM__
563 tClpBuf.erase(v,3); 563 tClpBuf.erase(v,3);
564 v -= 3; 564 v -= 3;
565#endif 565#endif
566 566
567 /* 567 /*
568 // my idea is the following: 568 // my idea is the following:
569 // current vertex to next vertex relation: 569 // current vertex to next vertex relation:
570 // out - out : add nothing 570 // out - out : add nothing
571 // out - in : add middle point 571 // out - in : add middle point
572 // in - out : add first and middle point 572 // in - out : add first and middle point
573 // in - in : add both 573 // in - in : add both
574 574
575 575
576 // now based on the number of intersections, create new vertices 576 // now based on the number of intersections, create new vertices
577 // into tClpBuf (at the front for not letting them be clipped again) 577 // into tClpBuf (at the front for not letting them be clipped again)
578 578
579 int added = 0; 579 int added = 0;
580 int prev = v+2; 580 int prev = v+2;
581 for (int index=v; index<v+3; ++index) 581 for (int index=v; index<v+3; ++index)
582 { 582 {
583 if (inout[prev] == core::ISREL3D_BACK) 583 if (inout[prev] == core::ISREL3D_BACK)
584 { 584 {
585 if (inout[index] != core::ISREL3D_BACK) 585 if (inout[index] != core::ISREL3D_BACK)
586 { 586 {
587 VERTEXTYPE& vt1 = tClpBuf[prev]; 587 VERTEXTYPE& vt1 = tClpBuf[prev];
588 VERTEXTYPE& vt2 = tClpBuf[index]; 588 VERTEXTYPE& vt2 = tClpBuf[index];
589 589
590 f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos); 590 f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos);
591 VERTEXTYPE nvt; 591 VERTEXTYPE nvt;
592 nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact); 592 nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact);
593 nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact); 593 nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact);
594 nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact); 594 nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact);
595 595
596 tClpBuf.push_front(nvt); ++index; ++prev; ++v; 596 tClpBuf.push_front(nvt); ++index; ++prev; ++v;
597 ++added; 597 ++added;
598 } 598 }
599 } 599 }
600 else 600 else
601 { 601 {
602 if (inout[index] != core::ISREL3D_BACK) 602 if (inout[index] != core::ISREL3D_BACK)
603 { 603 {
604 VERTEXTYPE vt1 = tClpBuf[index]; 604 VERTEXTYPE vt1 = tClpBuf[index];
605 VERTEXTYPE vt2 = tClpBuf[prev]; 605 VERTEXTYPE vt2 = tClpBuf[prev];
606 tClpBuf.push_front(vt1); ++index; ++prev; ++v; 606 tClpBuf.push_front(vt1); ++index; ++prev; ++v;
607 tClpBuf.push_front(vt2); ++index; ++prev; ++v; 607 tClpBuf.push_front(vt2); ++index; ++prev; ++v;
608 added+= 2; 608 added+= 2;
609 } 609 }
610 else 610 else
611 { 611 {
612 // same as above, but other way round. 612 // same as above, but other way round.
613 VERTEXTYPE vt1 = tClpBuf[index]; 613 VERTEXTYPE vt1 = tClpBuf[index];
614 VERTEXTYPE vt2 = tClpBuf[prev]; 614 VERTEXTYPE vt2 = tClpBuf[prev];
615 615
616 f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos); 616 f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos);
617 VERTEXTYPE nvt; 617 VERTEXTYPE nvt;
618 nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact); 618 nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact);
619 nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact); 619 nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact);
620 nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact); 620 nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact);
621 621
622 tClpBuf.push_front(vt2); ++index; ++prev; ++v; 622 tClpBuf.push_front(vt2); ++index; ++prev; ++v;
623 tClpBuf.push_front(nvt); ++index; ++prev; ++v; 623 tClpBuf.push_front(nvt); ++index; ++prev; ++v;
624 added += 2; 624 added += 2;
625 } 625 }
626 } 626 }
627 627
628 prev = index; 628 prev = index;
629 } 629 }
630 630
631 // erase original vertices 631 // erase original vertices
632 tClpBuf.erase(v,3); 632 tClpBuf.erase(v,3);
633 v -= 3; 633 v -= 3;
634 */ 634 */
635 635
636 636
637 } // end for all clip planes 637 } // end for all clip planes
638 638
639 // now add all remaining triangles in tempClipBuffer to clippedIndices 639 // now add all remaining triangles in tempClipBuffer to clippedIndices
640 // and clippedVertices array. 640 // and clippedVertices array.
641 if (clippedIndices.size() + tClpBuf.size() < 65535) 641 if (clippedIndices.size() + tClpBuf.size() < 65535)
642 for (t=0; t<(int)tClpBuf.size(); ++t) 642 for (t=0; t<(int)tClpBuf.size(); ++t)
643 { 643 {
644 clippedIndices.push_back(clippedVertices.size()); 644 clippedIndices.push_back(clippedVertices.size());
645 clippedVertices.push_back(tClpBuf[t]); 645 clippedVertices.push_back(tClpBuf[t]);
646 } 646 }
647 tClpBuf.clear(); 647 tClpBuf.clear();
648 648
649 } // end for all input triangles 649 } // end for all input triangles
650 650
651 651
652 // draw newly created triangles. 652 // draw newly created triangles.
653 653
654 // ----------------------------------------------------------- 654 // -----------------------------------------------------------
655 // here all triangles are being drawn. I put this in a separate 655 // here all triangles are being drawn. I put this in a separate
656 // method, but the visual studio 6 compiler has great problems 656 // method, but the visual studio 6 compiler has great problems
657 // with templates and didn't accept two template methods in this 657 // with templates and didn't accept two template methods in this
658 // class. 658 // class.
659 659
660 // draw triangles 660 // draw triangles
661 661
662 CNullDriver::drawVertexPrimitiveList(clippedVertices.pointer(), clippedVertices.size(), 662 CNullDriver::drawVertexPrimitiveList(clippedVertices.pointer(), clippedVertices.size(),
663 clippedIndices.pointer(), clippedIndices.size()/3, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT); 663 clippedIndices.pointer(), clippedIndices.size()/3, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
664 664
665 if (TransformedPoints.size() < clippedVertices.size()) 665 if (TransformedPoints.size() < clippedVertices.size())
666 TransformedPoints.set_used(clippedVertices.size()); 666 TransformedPoints.set_used(clippedVertices.size());
667 667
668 if (TransformedPoints.empty()) 668 if (TransformedPoints.empty())
669 return; 669 return;
670 670
671 const VERTEXTYPE* currentVertex = clippedVertices.pointer(); 671 const VERTEXTYPE* currentVertex = clippedVertices.pointer();
672 S2DVertex* tp = &TransformedPoints[0]; 672 S2DVertex* tp = &TransformedPoints[0];
673 673
674 core::dimension2d<u32> textureSize(0,0); 674 core::dimension2d<u32> textureSize(0,0);
675 f32 zDiv; 675 f32 zDiv;
676 676
677 if (Texture) 677 if (Texture)
678 textureSize = ((CSoftwareTexture*)Texture)->getTexture()->getDimension(); 678 textureSize = ((CSoftwareTexture*)Texture)->getTexture()->getDimension();
679 679
680 f32 transformedPos[4]; // transform all points in the list 680 f32 transformedPos[4]; // transform all points in the list
681 681
682 core::matrix4 matrix(TransformationMatrix[ETS_PROJECTION]); 682 core::matrix4 matrix(TransformationMatrix[ETS_PROJECTION]);
683 matrix *= TransformationMatrix[ETS_VIEW]; 683 matrix *= TransformationMatrix[ETS_VIEW];
684 matrix *= TransformationMatrix[ETS_WORLD]; 684 matrix *= TransformationMatrix[ETS_WORLD];
685 685
686 s32 ViewTransformWidth = (ViewPortSize.Width>>1); 686 s32 ViewTransformWidth = (ViewPortSize.Width>>1);
687 s32 ViewTransformHeight = (ViewPortSize.Height>>1); 687 s32 ViewTransformHeight = (ViewPortSize.Height>>1);
688 688
689 for (i=0; i<(int)clippedVertices.size(); ++i) 689 for (i=0; i<(int)clippedVertices.size(); ++i)
690 { 690 {
691 transformedPos[0] = currentVertex->Pos.X; 691 transformedPos[0] = currentVertex->Pos.X;
692 transformedPos[1] = currentVertex->Pos.Y; 692 transformedPos[1] = currentVertex->Pos.Y;
693 transformedPos[2] = currentVertex->Pos.Z; 693 transformedPos[2] = currentVertex->Pos.Z;
694 transformedPos[3] = 1.0f; 694 transformedPos[3] = 1.0f;
695 695
696 matrix.multiplyWith1x4Matrix(transformedPos); 696 matrix.multiplyWith1x4Matrix(transformedPos);
697 zDiv = transformedPos[3] == 0.0f ? 1.0f : (1.0f / transformedPos[3]); 697 zDiv = transformedPos[3] == 0.0f ? 1.0f : (1.0f / transformedPos[3]);
698 698
699 tp->Pos.X = (s32)(ViewTransformWidth * (transformedPos[0] * zDiv) + (Render2DTranslation.X)); 699 tp->Pos.X = (s32)(ViewTransformWidth * (transformedPos[0] * zDiv) + (Render2DTranslation.X));
700 tp->Pos.Y = (Render2DTranslation.Y - (s32)(ViewTransformHeight * (transformedPos[1] * zDiv))); 700 tp->Pos.Y = (Render2DTranslation.Y - (s32)(ViewTransformHeight * (transformedPos[1] * zDiv)));
701 tp->Color = currentVertex->Color.toA1R5G5B5(); 701 tp->Color = currentVertex->Color.toA1R5G5B5();
702 tp->ZValue = (TZBufferType)(32767.0f * zDiv); 702 tp->ZValue = (TZBufferType)(32767.0f * zDiv);
703 703
704 tp->TCoords.X = (s32)(currentVertex->TCoords.X * textureSize.Width); 704 tp->TCoords.X = (s32)(currentVertex->TCoords.X * textureSize.Width);
705 tp->TCoords.X <<= 8; 705 tp->TCoords.X <<= 8;
706 tp->TCoords.Y = (s32)(currentVertex->TCoords.Y * textureSize.Height); 706 tp->TCoords.Y = (s32)(currentVertex->TCoords.Y * textureSize.Height);
707 tp->TCoords.Y <<= 8; 707 tp->TCoords.Y <<= 8;
708 708
709 ++currentVertex; 709 ++currentVertex;
710 ++tp; 710 ++tp;
711 } 711 }
712 712
713 // draw all transformed points from the index list 713 // draw all transformed points from the index list
714 CurrentTriangleRenderer->drawIndexedTriangleList(&TransformedPoints[0], 714 CurrentTriangleRenderer->drawIndexedTriangleList(&TransformedPoints[0],
715 clippedVertices.size(), clippedIndices.pointer(), clippedIndices.size()/3); 715 clippedVertices.size(), clippedIndices.pointer(), clippedIndices.size()/3);
716} 716}
717 717
718 718
719//! Draws a 3d line. 719//! Draws a 3d line.
720void CSoftwareDriver::draw3DLine(const core::vector3df& start, 720void CSoftwareDriver::draw3DLine(const core::vector3df& start,
721 const core::vector3df& end, SColor color) 721 const core::vector3df& end, SColor color)
722{ 722{
723 core::vector3df vect = start.crossProduct(end); 723 core::vector3df vect = start.crossProduct(end);
724 vect.normalize(); 724 vect.normalize();
725 vect *= Material.Thickness*0.3f; 725 vect *= Material.Thickness*0.3f;
726 726
727 S3DVertex vtx[4]; 727 S3DVertex vtx[4];
728 728
729 vtx[0].Color = color; 729 vtx[0].Color = color;
730 vtx[1].Color = color; 730 vtx[1].Color = color;
731 vtx[2].Color = color; 731 vtx[2].Color = color;
732 vtx[3].Color = color; 732 vtx[3].Color = color;
733 733
734 vtx[0].Pos = start; 734 vtx[0].Pos = start;
735 vtx[1].Pos = end; 735 vtx[1].Pos = end;
736 736
737 vtx[2].Pos = start + vect; 737 vtx[2].Pos = start + vect;
738 vtx[3].Pos = end + vect; 738 vtx[3].Pos = end + vect;
739 739
740 u16 idx[12] = {0,1,2, 0,2,1, 0,1,3, 0,3,1}; 740 u16 idx[12] = {0,1,2, 0,2,1, 0,1,3, 0,3,1};
741 741
742 drawIndexedTriangleList(vtx, 4, idx, 4); 742 drawIndexedTriangleList(vtx, 4, idx, 4);
743} 743}
744 744
745 745
746//! clips a triangle against the viewing frustum 746//! clips a triangle against the viewing frustum
747void CSoftwareDriver::clipTriangle(f32* transformedPos) 747void CSoftwareDriver::clipTriangle(f32* transformedPos)
748{ 748{
749} 749}
750 750
751 751
752//! Only used by the internal engine. Used to notify the driver that 752//! Only used by the internal engine. Used to notify the driver that
753//! the window was resized. 753//! the window was resized.
754void CSoftwareDriver::OnResize(const core::dimension2d<u32>& size) 754void CSoftwareDriver::OnResize(const core::dimension2d<u32>& size)
755{ 755{
756 // make sure width and height are multiples of 2 756 // make sure width and height are multiples of 2
757 core::dimension2d<u32> realSize(size); 757 core::dimension2d<u32> realSize(size);
758 758
759 if (realSize.Width % 2) 759 if (realSize.Width % 2)
760 realSize.Width += 1; 760 realSize.Width += 1;
761 761
762 if (realSize.Height % 2) 762 if (realSize.Height % 2)
763 realSize.Height += 1; 763 realSize.Height += 1;
764 764
765 if (ScreenSize != realSize) 765 if (ScreenSize != realSize)
766 { 766 {
767 if (ViewPort.getWidth() == (s32)ScreenSize.Width && 767 if (ViewPort.getWidth() == (s32)ScreenSize.Width &&
768 ViewPort.getHeight() == (s32)ScreenSize.Height) 768 ViewPort.getHeight() == (s32)ScreenSize.Height)
769 { 769 {
770 ViewPort = core::rect<s32>(core::position2d<s32>(0,0), 770 ViewPort = core::rect<s32>(core::position2d<s32>(0,0),
771 core::dimension2di(realSize)); 771 core::dimension2di(realSize));
772 } 772 }
773 773
774 ScreenSize = realSize; 774 ScreenSize = realSize;
775 775
776 bool resetRT = (RenderTargetSurface == BackBuffer); 776 bool resetRT = (RenderTargetSurface == BackBuffer);
777 777
778 if (BackBuffer) 778 if (BackBuffer)
779 BackBuffer->drop(); 779 BackBuffer->drop();
780 BackBuffer = new CImage(ECF_A1R5G5B5, realSize); 780 BackBuffer = new CImage(ECF_A1R5G5B5, realSize);
781 781
782 if (resetRT) 782 if (resetRT)
783 setRenderTarget(BackBuffer); 783 setRenderTarget(BackBuffer);
784 } 784 }
785} 785}
786 786
787//! returns the current render target size 787//! returns the current render target size
788const core::dimension2d<u32>& CSoftwareDriver::getCurrentRenderTargetSize() const 788const core::dimension2d<u32>& CSoftwareDriver::getCurrentRenderTargetSize() const
789{ 789{
790 return RenderTargetSize; 790 return RenderTargetSize;
791} 791}
792 792
793 793
794//! 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. 794//! 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.
795void CSoftwareDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, 795void CSoftwareDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
796 const core::rect<s32>& sourceRect, 796 const core::rect<s32>& sourceRect,
797 const core::rect<s32>* clipRect, SColor color, 797 const core::rect<s32>* clipRect, SColor color,
798 bool useAlphaChannelOfTexture) 798 bool useAlphaChannelOfTexture)
799{ 799{
800 if (texture) 800 if (texture)
801 { 801 {
802 if (texture->getDriverType() != EDT_SOFTWARE) 802 if (texture->getDriverType() != EDT_SOFTWARE)
803 { 803 {
804 os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR); 804 os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);
805 return; 805 return;
806 } 806 }
807 807
808 if (useAlphaChannelOfTexture) 808 if (useAlphaChannelOfTexture)
809 ((CSoftwareTexture*)texture)->getImage()->copyToWithAlpha( 809 ((CSoftwareTexture*)texture)->getImage()->copyToWithAlpha(
810 RenderTargetSurface, destPos, sourceRect, color, clipRect); 810 RenderTargetSurface, destPos, sourceRect, color, clipRect);
811 else 811 else
812 ((CSoftwareTexture*)texture)->getImage()->copyTo( 812 ((CSoftwareTexture*)texture)->getImage()->copyTo(
813 RenderTargetSurface, destPos, sourceRect, clipRect); 813 RenderTargetSurface, destPos, sourceRect, clipRect);
814 } 814 }
815} 815}
816 816
817 817
818 818
819//! Draws a 2d line. 819//! Draws a 2d line.
820void CSoftwareDriver::draw2DLine(const core::position2d<s32>& start, 820void CSoftwareDriver::draw2DLine(const core::position2d<s32>& start,
821 const core::position2d<s32>& end, 821 const core::position2d<s32>& end,
822 SColor color) 822 SColor color)
823{ 823{
824 drawLine(RenderTargetSurface, start, end, color ); 824 drawLine(RenderTargetSurface, start, end, color );
825} 825}
826 826
827 827
828//! Draws a pixel 828//! Draws a pixel
829void CSoftwareDriver::drawPixel(u32 x, u32 y, const SColor & color) 829void CSoftwareDriver::drawPixel(u32 x, u32 y, const SColor & color)
830{ 830{
831 BackBuffer->setPixel(x, y, color, true); 831 BackBuffer->setPixel(x, y, color, true);
832} 832}
833 833
834 834
835//! draw a 2d rectangle 835//! draw a 2d rectangle
836void CSoftwareDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos, 836void CSoftwareDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos,
837 const core::rect<s32>* clip) 837 const core::rect<s32>* clip)
838{ 838{
839 if (clip) 839 if (clip)
840 { 840 {
841 core::rect<s32> p(pos); 841 core::rect<s32> p(pos);
842 842
843 p.clipAgainst(*clip); 843 p.clipAgainst(*clip);
844 844
845 if(!p.isValid()) 845 if(!p.isValid())
846 return; 846 return;
847 847
848 drawRectangle(RenderTargetSurface, p, color); 848 drawRectangle(RenderTargetSurface, p, color);
849 } 849 }
850 else 850 else
851 { 851 {
852 if(!pos.isValid()) 852 if(!pos.isValid())
853 return; 853 return;
854 854
855 drawRectangle(RenderTargetSurface, pos, color); 855 drawRectangle(RenderTargetSurface, pos, color);
856 } 856 }
857} 857}
858 858
859 859
860//!Draws an 2d rectangle with a gradient. 860//!Draws an 2d rectangle with a gradient.
861void CSoftwareDriver::draw2DRectangle(const core::rect<s32>& pos, 861void CSoftwareDriver::draw2DRectangle(const core::rect<s32>& pos,
862 SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown, 862 SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
863 const core::rect<s32>* clip) 863 const core::rect<s32>* clip)
864{ 864{
865 // TODO: implement 865 // TODO: implement
866 draw2DRectangle(colorLeftUp, pos, clip); 866 draw2DRectangle(colorLeftUp, pos, clip);
867} 867}
868 868
869 869
870//! \return Returns the name of the video driver. Example: In case of the Direct3D8 870//! \return Returns the name of the video driver. Example: In case of the Direct3D8
871//! driver, it would return "Direct3D8.1". 871//! driver, it would return "Direct3D8.1".
872const wchar_t* CSoftwareDriver::getName() const 872const wchar_t* CSoftwareDriver::getName() const
873{ 873{
874 return L"Irrlicht Software Driver 1.0"; 874 return L"Irrlicht Software Driver 1.0";
875} 875}
876 876
877 877
878//! Returns type of video driver 878//! Returns type of video driver
879E_DRIVER_TYPE CSoftwareDriver::getDriverType() const 879E_DRIVER_TYPE CSoftwareDriver::getDriverType() const
880{ 880{
881 return EDT_SOFTWARE; 881 return EDT_SOFTWARE;
882} 882}
883 883
884 884
885//! returns color format 885//! returns color format
886ECOLOR_FORMAT CSoftwareDriver::getColorFormat() const 886ECOLOR_FORMAT CSoftwareDriver::getColorFormat() const
887{ 887{
888 if (BackBuffer) 888 if (BackBuffer)
889 return BackBuffer->getColorFormat(); 889 return BackBuffer->getColorFormat();
890 else 890 else
891 return CNullDriver::getColorFormat(); 891 return CNullDriver::getColorFormat();
892} 892}
893 893
894 894
895//! Returns the transformation set by setTransform 895//! Returns the transformation set by setTransform
896const core::matrix4& CSoftwareDriver::getTransform(E_TRANSFORMATION_STATE state) const 896const core::matrix4& CSoftwareDriver::getTransform(E_TRANSFORMATION_STATE state) const
897{ 897{
898 return TransformationMatrix[state]; 898 return TransformationMatrix[state];
899} 899}
900 900
901 901
902//! Creates a render target texture. 902//! Creates a render target texture.
903ITexture* CSoftwareDriver::addRenderTargetTexture(const core::dimension2d<u32>& size, 903ITexture* CSoftwareDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
904 const io::path& name, 904 const io::path& name,
905 const ECOLOR_FORMAT format) 905 const ECOLOR_FORMAT format)
906{ 906{
907 IImage* img = createImage(video::ECF_A1R5G5B5, size); 907 IImage* img = createImage(video::ECF_A1R5G5B5, size);
908 ITexture* tex = new CSoftwareTexture(img, name, true); 908 ITexture* tex = new CSoftwareTexture(img, name, true);
909 img->drop(); 909 img->drop();
910 addTexture(tex); 910 addTexture(tex);
911 tex->drop(); 911 tex->drop();
912 return tex; 912 return tex;
913} 913}
914 914
915 915
916//! Clears the ZBuffer. 916//! Clears the ZBuffer.
917void CSoftwareDriver::clearZBuffer() 917void CSoftwareDriver::clearZBuffer()
918{ 918{
919 if (ZBuffer) 919 if (ZBuffer)
920 ZBuffer->clear(); 920 ZBuffer->clear();
921} 921}
922 922
923 923
924//! Returns an image created from the last rendered frame. 924//! Returns an image created from the last rendered frame.
925IImage* CSoftwareDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target) 925IImage* CSoftwareDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
926{ 926{
927 if (target != video::ERT_FRAME_BUFFER) 927 if (target != video::ERT_FRAME_BUFFER)
928 return 0; 928 return 0;
929 929
930 if (BackBuffer) 930 if (BackBuffer)
931 { 931 {
932 IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension()); 932 IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());
933 BackBuffer->copyTo(tmp); 933 BackBuffer->copyTo(tmp);
934 return tmp; 934 return tmp;
935 } 935 }
936 else 936 else
937 return 0; 937 return 0;
938} 938}
939 939
940 940
941//! Returns the maximum amount of primitives (mostly vertices) which 941//! Returns the maximum amount of primitives (mostly vertices) which
942//! the device is able to render with one drawIndexedTriangleList 942//! the device is able to render with one drawIndexedTriangleList
943//! call. 943//! call.
944u32 CSoftwareDriver::getMaximalPrimitiveCount() const 944u32 CSoftwareDriver::getMaximalPrimitiveCount() const
945{ 945{
946 return 0x00800000; 946 return 0x00800000;
947} 947}
948 948
949} // end namespace video 949} // end namespace video
950} // end namespace irr 950} // end namespace irr
951 951
952#endif // _IRR_COMPILE_WITH_SOFTWARE_ 952#endif // _IRR_COMPILE_WITH_SOFTWARE_
953 953
954namespace irr 954namespace irr
955{ 955{
956namespace video 956namespace video
957{ 957{
958 958
959 959
960//! creates a video driver 960//! creates a video driver
961IVideoDriver* createSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter) 961IVideoDriver* createSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter)
962{ 962{
963 #ifdef _IRR_COMPILE_WITH_SOFTWARE_ 963 #ifdef _IRR_COMPILE_WITH_SOFTWARE_
964 return new CSoftwareDriver(windowSize, fullscreen, io, presenter); 964 return new CSoftwareDriver(windowSize, fullscreen, io, presenter);
965 #else 965 #else
966 return 0; 966 return 0;
967 #endif 967 #endif
968} 968}
969 969
970 970
971} // end namespace video 971} // end namespace video
972} // end namespace irr 972} // end namespace irr
973 973