1
// Copyright (C) 2002-2011 Nikolaus Gebhardt
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
5
#include "IrrCompileConfig.h"
6
#include "CSoftwareDriver.h"
8
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
10
#include "CSoftwareTexture.h"
13
#include "S3DVertex.h"
22
CSoftwareDriver::CSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter)
23
: CNullDriver(io, windowSize), BackBuffer(0), Presenter(presenter), WindowId(0),
24
SceneSourceRect(0), RenderTargetTexture(0), RenderTargetSurface(0),
25
CurrentTriangleRenderer(0), ZBuffer(0), Texture(0)
28
setDebugName("CSoftwareDriver");
33
BackBuffer = new CImage(ECF_A1R5G5B5, windowSize);
36
BackBuffer->fill(SColor(0));
39
ZBuffer = video::createZBuffer(BackBuffer->getDimension());
42
DriverAttributes->setAttribute("MaxTextures", 1);
43
DriverAttributes->setAttribute("MaxIndices", 1<<16);
44
DriverAttributes->setAttribute("MaxTextureSize", 1024);
45
DriverAttributes->setAttribute("Version", 1);
47
// create triangle renderers
49
TriangleRenderers[ETR_FLAT] = createTriangleRendererFlat(ZBuffer);
50
TriangleRenderers[ETR_FLAT_WIRE] = createTriangleRendererFlatWire(ZBuffer);
51
TriangleRenderers[ETR_GOURAUD] = createTriangleRendererGouraud(ZBuffer);
52
TriangleRenderers[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire(ZBuffer);
53
TriangleRenderers[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat(ZBuffer);
54
TriangleRenderers[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire(ZBuffer);
55
TriangleRenderers[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud(ZBuffer);
56
TriangleRenderers[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire(ZBuffer);
57
TriangleRenderers[ETR_TEXTURE_GOURAUD_NOZ] = createTriangleRendererTextureGouraudNoZ();
58
TriangleRenderers[ETR_TEXTURE_GOURAUD_ADD] = createTriangleRendererTextureGouraudAdd(ZBuffer);
60
// select render target
62
setRenderTarget(BackBuffer);
64
// select the right renderer
66
selectRightTriangleRenderer();
72
CSoftwareDriver::~CSoftwareDriver()
78
// delete triangle renderers
80
for (s32 i=0; i<ETR_COUNT; ++i)
81
if (TriangleRenderers[i])
82
TriangleRenderers[i]->drop();
89
// delete current texture
94
if (RenderTargetTexture)
95
RenderTargetTexture->drop();
97
if (RenderTargetSurface)
98
RenderTargetSurface->drop();
103
//! switches to a triangle renderer
104
void CSoftwareDriver::switchToTriangleRenderer(ETriangleRenderer renderer)
106
video::IImage* s = 0;
108
s = ((CSoftwareTexture*)Texture)->getTexture();
110
CurrentTriangleRenderer = TriangleRenderers[renderer];
111
CurrentTriangleRenderer->setBackfaceCulling(Material.BackfaceCulling == true);
112
CurrentTriangleRenderer->setTexture(s);
113
CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort);
117
//! void selects the right triangle renderer based on the render states.
118
void CSoftwareDriver::selectRightTriangleRenderer()
121
ETriangleRenderer renderer = ETR_FLAT;
125
if (!Material.GouraudShading)
126
renderer = (!Material.Wireframe) ? ETR_TEXTURE_FLAT : ETR_TEXTURE_FLAT_WIRE;
129
if (Material.Wireframe)
130
renderer = ETR_TEXTURE_GOURAUD_WIRE;
133
if (Material.MaterialType == EMT_TRANSPARENT_ADD_COLOR ||
134
Material.MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL ||
135
Material.MaterialType == EMT_TRANSPARENT_VERTEX_ALPHA)
137
// simply draw all transparent stuff with the same renderer. at
138
// least it is transparent then.
139
renderer = ETR_TEXTURE_GOURAUD_ADD;
142
if ((Material.ZBuffer==ECFN_NEVER) && !Material.ZWriteEnable)
143
renderer = ETR_TEXTURE_GOURAUD_NOZ;
146
renderer = ETR_TEXTURE_GOURAUD;
153
if (!Material.GouraudShading)
154
renderer = (!Material.Wireframe) ? ETR_FLAT : ETR_FLAT_WIRE;
156
renderer = (!Material.Wireframe) ? ETR_GOURAUD : ETR_GOURAUD_WIRE;
159
switchToTriangleRenderer(renderer);
163
//! queries the features of the driver, returns true if feature is available
164
bool CSoftwareDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
168
case EVDF_RENDER_TO_TARGET:
169
case EVDF_TEXTURE_NSQUARE:
170
return FeatureEnabled[feature];
177
//! sets transformation
178
void CSoftwareDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
180
TransformationMatrix[state] = mat;
184
//! sets the current Texture
185
bool CSoftwareDriver::setActiveTexture(u32 stage, video::ITexture* texture)
187
if (texture && texture->getDriverType() != EDT_SOFTWARE)
189
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
201
selectRightTriangleRenderer();
207
void CSoftwareDriver::setMaterial(const SMaterial& material)
210
OverrideMaterial.apply(Material);
212
for (u32 i = 0; i < 1; ++i)
214
setActiveTexture(i, Material.getTexture(i));
215
setTransform ((E_TRANSFORMATION_STATE) ( ETS_TEXTURE_0 + i ),
216
material.getTextureMatrix(i));
221
//! clears the zbuffer
222
bool CSoftwareDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
223
const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
225
CNullDriver::beginScene(backBuffer, zBuffer, color, videoData, sourceRect);
226
WindowId=videoData.D3D9.HWnd;
227
SceneSourceRect = sourceRect;
229
if (backBuffer && BackBuffer)
230
BackBuffer->fill(color);
232
if (ZBuffer && zBuffer)
239
//! presents the rendered scene on the screen, returns false if failed
240
bool CSoftwareDriver::endScene()
242
CNullDriver::endScene();
244
return Presenter->present(BackBuffer, WindowId, SceneSourceRect);
248
//! returns a device dependent texture from a software surface (IImage)
249
//! THIS METHOD HAS TO BE OVERRIDDEN BY DERIVED DRIVERS WITH OWN TEXTURES
250
ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData)
252
return new CSoftwareTexture(surface, name, false, mipmapData);
256
//! sets a render target
257
bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
258
bool clearZBuffer, SColor color)
260
if (texture && texture->getDriverType() != EDT_SOFTWARE)
262
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
266
if (RenderTargetTexture)
267
RenderTargetTexture->drop();
269
RenderTargetTexture = texture;
271
if (RenderTargetTexture)
273
RenderTargetTexture->grab();
274
setRenderTarget(((CSoftwareTexture*)RenderTargetTexture)->getTexture());
278
setRenderTarget(BackBuffer);
281
if (RenderTargetSurface && (clearBackBuffer || clearZBuffer))
287
RenderTargetSurface->fill(color);
294
//! sets a render target
295
void CSoftwareDriver::setRenderTarget(video::CImage* image)
297
if (RenderTargetSurface)
298
RenderTargetSurface->drop();
300
RenderTargetSurface = image;
301
RenderTargetSize.Width = 0;
302
RenderTargetSize.Height = 0;
303
Render2DTranslation.X = 0;
304
Render2DTranslation.Y = 0;
306
if (RenderTargetSurface)
308
RenderTargetSurface->grab();
309
RenderTargetSize = RenderTargetSurface->getDimension();
312
setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height));
315
ZBuffer->setSize(RenderTargetSize);
320
void CSoftwareDriver::setViewPort(const core::rect<s32>& area)
324
//TODO: the clipping is not correct, because the projection is affected.
325
// to correct this, ViewPortSize and Render2DTranslation will have to be corrected.
326
core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height);
327
ViewPort.clipAgainst(rendert);
329
ViewPortSize = core::dimension2du(ViewPort.getSize());
330
Render2DTranslation.X = (ViewPortSize.Width / 2) + ViewPort.UpperLeftCorner.X;
331
Render2DTranslation.Y = ViewPort.UpperLeftCorner.Y + ViewPortSize.Height - (ViewPortSize.Height / 2);// + ViewPort.UpperLeftCorner.Y;
333
if (CurrentTriangleRenderer)
334
CurrentTriangleRenderer->setRenderTarget(RenderTargetSurface, ViewPort);
338
void CSoftwareDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
339
const void* indexList, u32 primitiveCount,
340
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)
347
drawVertexPrimitiveList16(vertices, vertexCount, (const u16*)indexList, primitiveCount, vType, pType);
352
os::Printer::log("Software driver can not render 32bit buffers", ELL_ERROR);
359
//! draws a vertex primitive list
360
void CSoftwareDriver::drawVertexPrimitiveList16(const void* vertices, u32 vertexCount, const u16* indexList, u32 primitiveCount, E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType)
362
const u16* indexPointer=0;
363
core::array<u16> newBuffer;
366
case scene::EPT_LINE_STRIP:
372
for (u32 i=0; i < primitiveCount-1; ++i)
373
draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos,
374
((S3DVertex*)vertices)[indexList[i+1]].Pos,
375
((S3DVertex*)vertices)[indexList[i]].Color);
380
for (u32 i=0; i < primitiveCount-1; ++i)
381
draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos,
382
((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos,
383
((S3DVertex2TCoords*)vertices)[indexList[i]].Color);
388
for (u32 i=0; i < primitiveCount-1; ++i)
389
draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos,
390
((S3DVertexTangents*)vertices)[indexList[i+1]].Pos,
391
((S3DVertexTangents*)vertices)[indexList[i]].Color);
397
case scene::EPT_LINE_LOOP:
398
drawVertexPrimitiveList16(vertices, vertexCount, indexList, primitiveCount-1, vType, scene::EPT_LINE_STRIP);
402
draw3DLine(((S3DVertex*)vertices)[indexList[primitiveCount-1]].Pos,
403
((S3DVertex*)vertices)[indexList[0]].Pos,
404
((S3DVertex*)vertices)[indexList[primitiveCount-1]].Color);
407
draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Pos,
408
((S3DVertex2TCoords*)vertices)[indexList[0]].Pos,
409
((S3DVertex2TCoords*)vertices)[indexList[primitiveCount-1]].Color);
412
draw3DLine(((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Pos,
413
((S3DVertexTangents*)vertices)[indexList[0]].Pos,
414
((S3DVertexTangents*)vertices)[indexList[primitiveCount-1]].Color);
418
case scene::EPT_LINES:
424
for (u32 i=0; i < 2*primitiveCount; i+=2)
425
draw3DLine(((S3DVertex*)vertices)[indexList[i]].Pos,
426
((S3DVertex*)vertices)[indexList[i+1]].Pos,
427
((S3DVertex*)vertices)[indexList[i]].Color);
432
for (u32 i=0; i < 2*primitiveCount; i+=2)
433
draw3DLine(((S3DVertex2TCoords*)vertices)[indexList[i]].Pos,
434
((S3DVertex2TCoords*)vertices)[indexList[i+1]].Pos,
435
((S3DVertex2TCoords*)vertices)[indexList[i]].Color);
440
for (u32 i=0; i < 2*primitiveCount; i+=2)
441
draw3DLine(((S3DVertexTangents*)vertices)[indexList[i]].Pos,
442
((S3DVertexTangents*)vertices)[indexList[i+1]].Pos,
443
((S3DVertexTangents*)vertices)[indexList[i]].Color);
449
case scene::EPT_TRIANGLE_FAN:
451
// TODO: don't convert fan to list
452
newBuffer.reallocate(primitiveCount*3);
453
for( u32 t=0; t<primitiveCount; ++t )
455
newBuffer.push_back(indexList[0]);
456
newBuffer.push_back(indexList[t+1]);
457
newBuffer.push_back(indexList[t+2]);
460
indexPointer = newBuffer.pointer();
463
case scene::EPT_TRIANGLES:
464
indexPointer=indexList;
472
drawClippedIndexedTriangleListT((S3DVertex*)vertices, vertexCount, indexPointer, primitiveCount);
475
drawClippedIndexedTriangleListT((S3DVertex2TCoords*)vertices, vertexCount, indexPointer, primitiveCount);
478
drawClippedIndexedTriangleListT((S3DVertexTangents*)vertices, vertexCount, indexPointer, primitiveCount);
484
template<class VERTEXTYPE>
485
void CSoftwareDriver::drawClippedIndexedTriangleListT(const VERTEXTYPE* vertices,
486
s32 vertexCount, const u16* indexList, s32 triangleCount)
488
if (!RenderTargetSurface || !ZBuffer || !triangleCount)
491
if (!checkPrimitiveCount(triangleCount))
494
// arrays for storing clipped vertices
495
core::array<VERTEXTYPE> clippedVertices;
496
core::array<u16> clippedIndices;
498
// calculate inverse world transformation
499
core::matrix4 worldinv(TransformationMatrix[ETS_WORLD]);
500
worldinv.makeInverse();
502
// calculate view frustum planes
503
scene::SViewFrustum frustum(TransformationMatrix[ETS_PROJECTION] * TransformationMatrix[ETS_VIEW]);
505
// copy and transform clipping planes ignoring far plane
506
core::plane3df planes[5]; // ordered by near, left, right, bottom, top
507
for (int p=0; p<5; ++p)
508
worldinv.transformPlane(frustum.planes[p+1], planes[p]);
510
core::EIntersectionRelation3D inout[3]; // is point in front or back of plane?
512
// temporary buffer for vertices to be clipped by all planes
513
core::array<VERTEXTYPE> tClpBuf;
517
for (i=0; i<triangleCount; ++i) // for all input triangles
519
// add next triangle to tempClipBuffer
521
tClpBuf.push_back(vertices[indexList[(i*3)+t]]);
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
529
// test intersection relation of the current vertices
532
inout[t] = planes[p].classifyPointRelation(tClpBuf[v+t].Pos);
533
if (inout[t] != core::ISREL3D_FRONT)
536
if (inout[t] == core::ISREL3D_FRONT)
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
549
// all vertices are outside, don't add this triangle, so erase this
550
// triangle from the tClpBuf
556
// this vertex has to be clipped by this clipping plane.
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.
560
// So now it is commented out, resulting that triangles which would need clipping
561
// are simply taken out (in the next two lines).
562
#ifndef __SOFTWARE_CLIPPING_PROBLEM__
568
// my idea is the following:
569
// current vertex to next vertex relation:
570
// out - out : add nothing
571
// out - in : add middle point
572
// in - out : add first and middle point
573
// in - in : add both
576
// now based on the number of intersections, create new vertices
577
// into tClpBuf (at the front for not letting them be clipped again)
581
for (int index=v; index<v+3; ++index)
583
if (inout[prev] == core::ISREL3D_BACK)
585
if (inout[index] != core::ISREL3D_BACK)
587
VERTEXTYPE& vt1 = tClpBuf[prev];
588
VERTEXTYPE& vt2 = tClpBuf[index];
590
f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos);
592
nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact);
593
nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact);
594
nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact);
596
tClpBuf.push_front(nvt); ++index; ++prev; ++v;
602
if (inout[index] != core::ISREL3D_BACK)
604
VERTEXTYPE vt1 = tClpBuf[index];
605
VERTEXTYPE vt2 = tClpBuf[prev];
606
tClpBuf.push_front(vt1); ++index; ++prev; ++v;
607
tClpBuf.push_front(vt2); ++index; ++prev; ++v;
612
// same as above, but other way round.
613
VERTEXTYPE vt1 = tClpBuf[index];
614
VERTEXTYPE vt2 = tClpBuf[prev];
616
f32 fact = planes[p].getKnownIntersectionWithLine(vt1.Pos, vt2.Pos);
618
nvt.Pos = vt1.Pos.getInterpolated(vt2.Pos, fact);
619
nvt.Color = vt1.Color.getInterpolated(vt2.Color, fact);
620
nvt.TCoords = vt1.TCoords.getInterpolated(vt2.TCoords, fact);
622
tClpBuf.push_front(vt2); ++index; ++prev; ++v;
623
tClpBuf.push_front(nvt); ++index; ++prev; ++v;
631
// erase original vertices
637
} // end for all clip planes
639
// now add all remaining triangles in tempClipBuffer to clippedIndices
640
// and clippedVertices array.
641
if (clippedIndices.size() + tClpBuf.size() < 65535)
642
for (t=0; t<(int)tClpBuf.size(); ++t)
644
clippedIndices.push_back(clippedVertices.size());
645
clippedVertices.push_back(tClpBuf[t]);
649
} // end for all input triangles
652
// draw newly created triangles.
654
// -----------------------------------------------------------
655
// here all triangles are being drawn. I put this in a separate
656
// method, but the visual studio 6 compiler has great problems
657
// with templates and didn't accept two template methods in this
662
CNullDriver::drawVertexPrimitiveList(clippedVertices.pointer(), clippedVertices.size(),
663
clippedIndices.pointer(), clippedIndices.size()/3, EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);
665
if (TransformedPoints.size() < clippedVertices.size())
666
TransformedPoints.set_used(clippedVertices.size());
668
if (TransformedPoints.empty())
671
const VERTEXTYPE* currentVertex = clippedVertices.pointer();
672
S2DVertex* tp = &TransformedPoints[0];
674
core::dimension2d<u32> textureSize(0,0);
678
textureSize = ((CSoftwareTexture*)Texture)->getTexture()->getDimension();
680
f32 transformedPos[4]; // transform all points in the list
682
core::matrix4 matrix(TransformationMatrix[ETS_PROJECTION]);
683
matrix *= TransformationMatrix[ETS_VIEW];
684
matrix *= TransformationMatrix[ETS_WORLD];
686
s32 ViewTransformWidth = (ViewPortSize.Width>>1);
687
s32 ViewTransformHeight = (ViewPortSize.Height>>1);
689
for (i=0; i<(int)clippedVertices.size(); ++i)
691
transformedPos[0] = currentVertex->Pos.X;
692
transformedPos[1] = currentVertex->Pos.Y;
693
transformedPos[2] = currentVertex->Pos.Z;
694
transformedPos[3] = 1.0f;
696
matrix.multiplyWith1x4Matrix(transformedPos);
697
zDiv = transformedPos[3] == 0.0f ? 1.0f : (1.0f / transformedPos[3]);
699
tp->Pos.X = (s32)(ViewTransformWidth * (transformedPos[0] * zDiv) + (Render2DTranslation.X));
700
tp->Pos.Y = (Render2DTranslation.Y - (s32)(ViewTransformHeight * (transformedPos[1] * zDiv)));
701
tp->Color = currentVertex->Color.toA1R5G5B5();
702
tp->ZValue = (TZBufferType)(32767.0f * zDiv);
704
tp->TCoords.X = (s32)(currentVertex->TCoords.X * textureSize.Width);
706
tp->TCoords.Y = (s32)(currentVertex->TCoords.Y * textureSize.Height);
713
// draw all transformed points from the index list
714
CurrentTriangleRenderer->drawIndexedTriangleList(&TransformedPoints[0],
715
clippedVertices.size(), clippedIndices.pointer(), clippedIndices.size()/3);
720
void CSoftwareDriver::draw3DLine(const core::vector3df& start,
721
const core::vector3df& end, SColor color)
723
core::vector3df vect = start.crossProduct(end);
725
vect *= Material.Thickness*0.3f;
729
vtx[0].Color = color;
730
vtx[1].Color = color;
731
vtx[2].Color = color;
732
vtx[3].Color = color;
737
vtx[2].Pos = start + vect;
738
vtx[3].Pos = end + vect;
740
u16 idx[12] = {0,1,2, 0,2,1, 0,1,3, 0,3,1};
742
drawIndexedTriangleList(vtx, 4, idx, 4);
746
//! clips a triangle against the viewing frustum
747
void CSoftwareDriver::clipTriangle(f32* transformedPos)
752
//! Only used by the internal engine. Used to notify the driver that
753
//! the window was resized.
754
void CSoftwareDriver::OnResize(const core::dimension2d<u32>& size)
756
// make sure width and height are multiples of 2
757
core::dimension2d<u32> realSize(size);
759
if (realSize.Width % 2)
762
if (realSize.Height % 2)
763
realSize.Height += 1;
765
if (ScreenSize != realSize)
767
if (ViewPort.getWidth() == (s32)ScreenSize.Width &&
768
ViewPort.getHeight() == (s32)ScreenSize.Height)
770
ViewPort = core::rect<s32>(core::position2d<s32>(0,0),
771
core::dimension2di(realSize));
774
ScreenSize = realSize;
776
bool resetRT = (RenderTargetSurface == BackBuffer);
780
BackBuffer = new CImage(ECF_A1R5G5B5, realSize);
783
setRenderTarget(BackBuffer);
787
//! returns the current render target size
788
const core::dimension2d<u32>& CSoftwareDriver::getCurrentRenderTargetSize() const
790
return RenderTargetSize;
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.
795
void CSoftwareDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
796
const core::rect<s32>& sourceRect,
797
const core::rect<s32>* clipRect, SColor color,
798
bool useAlphaChannelOfTexture)
802
if (texture->getDriverType() != EDT_SOFTWARE)
804
os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);
808
if (useAlphaChannelOfTexture)
809
((CSoftwareTexture*)texture)->getImage()->copyToWithAlpha(
810
RenderTargetSurface, destPos, sourceRect, color, clipRect);
812
((CSoftwareTexture*)texture)->getImage()->copyTo(
813
RenderTargetSurface, destPos, sourceRect, clipRect);
820
void CSoftwareDriver::draw2DLine(const core::position2d<s32>& start,
821
const core::position2d<s32>& end,
824
drawLine(RenderTargetSurface, start, end, color );
829
void CSoftwareDriver::drawPixel(u32 x, u32 y, const SColor & color)
831
BackBuffer->setPixel(x, y, color, true);
835
//! draw a 2d rectangle
836
void CSoftwareDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos,
837
const core::rect<s32>* clip)
841
core::rect<s32> p(pos);
843
p.clipAgainst(*clip);
848
drawRectangle(RenderTargetSurface, p, color);
855
drawRectangle(RenderTargetSurface, pos, color);
860
//!Draws an 2d rectangle with a gradient.
861
void CSoftwareDriver::draw2DRectangle(const core::rect<s32>& pos,
862
SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,
863
const core::rect<s32>* clip)
866
draw2DRectangle(colorLeftUp, pos, clip);
870
//! \return Returns the name of the video driver. Example: In case of the Direct3D8
871
//! driver, it would return "Direct3D8.1".
872
const wchar_t* CSoftwareDriver::getName() const
874
return L"Irrlicht Software Driver 1.0";
878
//! Returns type of video driver
879
E_DRIVER_TYPE CSoftwareDriver::getDriverType() const
885
//! returns color format
886
ECOLOR_FORMAT CSoftwareDriver::getColorFormat() const
889
return BackBuffer->getColorFormat();
891
return CNullDriver::getColorFormat();
895
//! Returns the transformation set by setTransform
896
const core::matrix4& CSoftwareDriver::getTransform(E_TRANSFORMATION_STATE state) const
898
return TransformationMatrix[state];
902
//! Creates a render target texture.
903
ITexture* CSoftwareDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
904
const io::path& name,
905
const ECOLOR_FORMAT format)
907
IImage* img = createImage(video::ECF_A1R5G5B5, size);
908
ITexture* tex = new CSoftwareTexture(img, name, true);
916
//! Clears the ZBuffer.
917
void CSoftwareDriver::clearZBuffer()
924
//! Returns an image created from the last rendered frame.
925
IImage* CSoftwareDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)
927
if (target != video::ERT_FRAME_BUFFER)
932
IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());
933
BackBuffer->copyTo(tmp);
941
//! Returns the maximum amount of primitives (mostly vertices) which
942
//! the device is able to render with one drawIndexedTriangleList
944
u32 CSoftwareDriver::getMaximalPrimitiveCount() const
949
} // end namespace video
950
} // end namespace irr
952
#endif // _IRR_COMPILE_WITH_SOFTWARE_
960
//! creates a video driver
961
IVideoDriver* createSoftwareDriver(const core::dimension2d<u32>& windowSize, bool fullscreen, io::IFileSystem* io, video::IImagePresenter* presenter)
963
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
964
return new CSoftwareDriver(windowSize, fullscreen, io, presenter);
971
} // end namespace video
972
} // end namespace irr