#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
enum BD3DRENDERSTATETYPE
{
BD3DRS_ZENABLE,
BD3DRS_FILLMODE,
BD3DRS_SHADEMODE,
BD3DRS_ZWRITEENABLE,
BD3DRS_ALPHATESTENABLE,
BD3DRS_SRCBLEND,
BD3DRS_DESTBLEND,
BD3DRS_CULLMODE,
BD3DRS_ZFUNC,
BD3DRS_ALPHAREF,
BD3DRS_ALPHAFUNC,
BD3DRS_DITHERENABLE,
BD3DRS_ALPHABLENDENABLE,
BD3DRS_FOGENABLE,
BD3DRS_SPECULARENABLE,
BD3DRS_FOGCOLOR,
BD3DRS_FOGTABLEMODE,
BD3DRS_FOGSTART,
BD3DRS_FOGEND,
BD3DRS_FOGDENSITY,
BD3DRS_RANGEFOGENABLE = 48,
BD3DRS_STENCILENABLE = 52,
BD3DRS_STENCILFAIL = 53,
BD3DRS_STENCILZFAIL = 54,
BD3DRS_STENCILPASS = 55,
BD3DRS_STENCILFUNC = 56,
BD3DRS_STENCILREF = 57,
BD3DRS_STENCILMASK = 58,
BD3DRS_STENCILWRITEMASK = 59,
BD3DRS_TEXTUREFACTOR = 60,
BD3DRS_WRAP0 = 128,
BD3DRS_WRAP1 = 129,
BD3DRS_WRAP2 = 130,
BD3DRS_WRAP3 = 131,
BD3DRS_WRAP4 = 132,
BD3DRS_WRAP5 = 133,
BD3DRS_WRAP6 = 134,
BD3DRS_WRAP7 = 135,
BD3DRS_CLIPPING = 136,
BD3DRS_LIGHTING = 137,
BD3DRS_AMBIENT = 139,
BD3DRS_FOGVERTEXMODE = 140,
BD3DRS_COLORVERTEX = 141,
BD3DRS_LOCALVIEWER = 142,
BD3DRS_NORMALIZENORMALS = 143,
BD3DRS_DIFFUSEMATERIALSOURCE = 145,
BD3DRS_SPECULARMATERIALSOURCE = 146,
BD3DRS_AMBIENTMATERIALSOURCE = 147,
BD3DRS_EMISSIVEMATERIALSOURCE = 148,
BD3DRS_VERTEXBLEND = 151,
BD3DRS_CLIPPLANEENABLE = 152,
BD3DRS_POINTSIZE = 154,
BD3DRS_POINTSIZE_MIN = 155,
BD3DRS_POINTSPRITEENABLE = 156,
BD3DRS_POINTSCALEENABLE = 157,
BD3DRS_POINTSCALE_A = 158,
BD3DRS_POINTSCALE_B = 159,
BD3DRS_POINTSCALE_C = 160,
BD3DRS_MULTISAMPLEANTIALIAS = 161,
BD3DRS_MULTISAMPLEMASK = 162,
BD3DRS_PATCHEDGESTYLE = 163,
BD3DRS_DEBUGMONITORTOKEN = 165,
BD3DRS_POINTSIZE_MAX = 166,
BD3DRS_INDEXEDVERTEXBLENDENABLE = 167,
BD3DRS_COLORWRITEENABLE = 168,
BD3DRS_TWEENFACTOR = 170,
BD3DRS_BLENDOP = 171,
BD3DRS_POSITIONDEGREE = 172,
BD3DRS_NORMALDEGREE = 173,
BD3DRS_SCISSORTESTENABLE = 174,
BD3DRS_SLOPESCALEDEPTHBIAS = 175,
BD3DRS_ANTIALIASEDLINEENABLE = 176,
BD3DRS_MINTESSELLATIONLEVEL = 178,
BD3DRS_MAXTESSELLATIONLEVEL = 179,
BD3DRS_ADAPTIVETESS_X = 180,
BD3DRS_ADAPTIVETESS_Y = 181,
BD3DRS_ADAPTIVETESS_Z = 182,
BD3DRS_ADAPTIVETESS_W = 183,
BD3DRS_ENABLEADAPTIVETESSELLATION = 184,
BD3DRS_TWOSIDEDSTENCILMODE = 185,
BD3DRS_CCW_STENCILFAIL = 186,
BD3DRS_CCW_STENCILZFAIL = 187,
BD3DRS_CCW_STENCILPASS = 188,
BD3DRS_CCW_STENCILFUNC = 189,
BD3DRS_COLORWRITEENABLE1 = 190,
BD3DRS_COLORWRITEENABLE2 = 191,
BD3DRS_COLORWRITEENABLE3 = 192,
BD3DRS_BLENDFACTOR = 193,
BD3DRS_SRGBWRITEENABLE = 194,
BD3DRS_DEPTHBIAS = 195,
BD3DRS_WRAP8 = 198,
BD3DRS_WRAP9 = 199,
BD3DRS_WRAP10 = 200,
BD3DRS_WRAP11 = 201,
BD3DRS_WRAP12 = 202,
BD3DRS_WRAP13 = 203,
BD3DRS_WRAP14 = 204,
BD3DRS_WRAP15 = 205,
BD3DRS_SEPARATEALPHABLENDENABLE = 206,
BD3DRS_SRCBLENDALPHA = 207,
BD3DRS_DESTBLENDALPHA = 208,
BD3DRS_BLENDOPALPHA = 209,
BD3DRS_MAX_TYPE
};
enum BD3DZBUFFERTYPE
{
BD3DZB_FALSE = 0,
BD3DZB_TRUE = 1,
BD3DZB_USEW = 2
};
enum BD3DCMPFUNC
{
BD3DCMP_NEVER = 1,
BD3DCMP_LESS,
BD3DCMP_EQUAL,
BD3DCMP_LESSEQUAL,
BD3DCMP_GREATER,
BD3DCMP_NOTEQUAL,
BD3DCMP_GREATEREQUAL,
BD3DCMP_ALWAYS
};
enum BD3DMATERIALCOLORSOURCE
{
BD3DMCS_MATERIAL = 0,
BD3DMCS_COLOR1 = 1,
BD3DMCS_COLOR2 = 2
};
enum BD3DSHADEMODE
{
BD3DSHADE_FLAT = 1,
BD3DSHADE_GOURAUD = 2,
BD3DSHADE_PHONG = 3
};
enum BD3DFILLMODE
{
BD3DFILL_POINT = 1,
BD3DFILL_WIREFRAME = 2,
BD3DFILL_SOLID = 3
};
enum BD3DCULL
{
BD3DCULL_NONE = 1,
BD3DCULL_CW = 2,
BD3DCULL_CCW = 3
};
struct SShaderParam
{
u32 ColorUnits;
u32 TextureUnits;
u32 RenderState [ BD3DRS_MAX_TYPE ];
void SetRenderState ( BD3DRENDERSTATETYPE state, u32 value );
};
void SShaderParam::SetRenderState ( BD3DRENDERSTATETYPE state, u32 value )
{
RenderState [ state ] = value;
}
class CBurningShader_Raster_Reference : public IBurningShader
{
public:
CBurningShader_Raster_Reference(CBurningVideoDriver* driver);
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void setMaterial ( const SBurningShaderMaterial &material );
private:
void scanline ();
void scanline2 ();
sScanLineData line;
sPixelShaderData pShader;
void pShader_1 ();
void pShader_EMT_LIGHTMAP_M4 ();
SShaderParam ShaderParam;
REALINLINE u32 depthFunc ();
REALINLINE void depthWrite ();
};
CBurningShader_Raster_Reference::CBurningShader_Raster_Reference(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CBurningShader_Raster_Reference");
#endif
}
void CBurningShader_Raster_Reference::pShader_EMT_LIGHTMAP_M4 ()
{
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
f32 inversew = fix_inverse32 ( line.w[0] );
getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
pShader.dst[pShader.i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
}
void CBurningShader_Raster_Reference::pShader_1 ()
{
tFixPoint r0, g0, b0;
tFixPoint tx0, ty0;
const f32 inversew = fix_inverse32 ( line.w[0] );
tx0 = tofix ( line.t[0][0].x, inversew );
ty0 = tofix ( line.t[0][0].y, inversew );
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
pShader.dst[pShader.i] = fix_to_color ( r0, g0, b0 );
}
void CBurningShader_Raster_Reference::setMaterial ( const SBurningShaderMaterial &material )
{
const video::SMaterial &m = material.org;
u32 i;
u32 enable;
ShaderParam.ColorUnits = 0;
ShaderParam.TextureUnits = 0;
for ( i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
if ( m.getTexture( i ) )
ShaderParam.TextureUnits = i;
}
ShaderParam.SetRenderState( BD3DRS_SHADEMODE,
m.GouraudShading ? BD3DSHADE_GOURAUD : BD3DSHADE_FLAT
);
ShaderParam.SetRenderState( BD3DRS_FILLMODE,
m.Wireframe ? BD3DFILL_WIREFRAME : m.PointCloud ? BD3DFILL_POINT : BD3DFILL_SOLID
);
ShaderParam.SetRenderState( BD3DRS_CULLMODE,
m.BackfaceCulling ? BD3DCULL_CCW : BD3DCULL_NONE
);
ShaderParam.SetRenderState( BD3DRS_LIGHTING, m.Lighting );
enable = F32_LOWER_EQUAL_0 ( m.Shininess );
ShaderParam.SetRenderState( BD3DRS_SPECULARENABLE, enable);
ShaderParam.SetRenderState( BD3DRS_NORMALIZENORMALS, enable);
ShaderParam.SetRenderState( BD3DRS_SPECULARMATERIALSOURCE, (m.ColorMaterial==ECM_SPECULAR)?BD3DMCS_COLOR1:BD3DMCS_MATERIAL);
ShaderParam.SetRenderState( BD3DRS_ZENABLE, (material.org.ZBuffer==video::ECFN_NEVER) ? BD3DZB_FALSE : BD3DZB_USEW);
switch (material.org.ZBuffer)
{
case ECFN_NEVER:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_NEVER);
break;
case ECFN_LESSEQUAL:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_LESSEQUAL);
break;
case ECFN_EQUAL:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_EQUAL);
break;
case ECFN_LESS:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_LESSEQUAL);
break;
case ECFN_NOTEQUAL:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_NOTEQUAL);
break;
case ECFN_GREATEREQUAL:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_GREATEREQUAL);
break;
case ECFN_GREATER:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_GREATER);
break;
case ECFN_ALWAYS:
ShaderParam.SetRenderState(BD3DRS_ZFUNC, BD3DCMP_ALWAYS);
break;
}
ShaderParam.SetRenderState( BD3DRS_ZWRITEENABLE, m.ZWriteEnable );
}
REALINLINE u32 CBurningShader_Raster_Reference::depthFunc ()
{
if ( ShaderParam.RenderState [ BD3DRS_ZENABLE ] )
{
switch ( ShaderParam.RenderState [ BD3DRS_ZFUNC ] )
{
case BD3DCMP_LESSEQUAL:
return line.w[0] >= pShader.z[ pShader.i];
case BD3DCMP_EQUAL:
return line.w[0] == pShader.z[ pShader.i];
}
}
return 1;
}
REALINLINE void CBurningShader_Raster_Reference::depthWrite ()
{
if ( ShaderParam.RenderState [ BD3DRS_ZWRITEENABLE ] )
{
pShader.z[pShader.i] = line.w[0];
}
}
REALINLINE void CBurningShader_Raster_Reference::scanline2()
{
pShader.xStart = core::ceil32( line.x[0] );
pShader.xEnd = core::ceil32( line.x[1] ) - 1;
pShader.dx = pShader.xEnd - pShader.xStart;
if ( pShader.dx < 0 )
return;
const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
line.w[0] += (line.w[1] = (line.w[1] - line.w[0]) * invDeltaX) * subPixel;
u32 i;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;
line.c[i][0] += line.c[i][1] * subPixel;
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
line.t[i][1] = (line.t[i][1] - line.t[i][0]) * invDeltaX;
line.t[i][0] += line.t[i][1] * subPixel;
}
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->lock() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
for ( pShader.i = 0; pShader.i <= pShader.dx; ++pShader.i )
{
if ( depthFunc() )
{
depthWrite ();
}
line.w[0] += line.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][0] += line.c[i][1];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
line.t[i][0] += line.t[i][1];
}
}
}
REALINLINE void CBurningShader_Raster_Reference::scanline ()
{
u32 i;
pShader.xStart = core::ceil32( line.x[0] );
pShader.xEnd = core::ceil32( line.x[1] ) - 1;
pShader.dx = pShader.xEnd - pShader.xStart;
if ( pShader.dx < 0 )
return;
const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
const f32 b = (line.w[1] - line.w[0]) * invDeltaX;
f32 a = line.w[0] + ( b * subPixel );
pShader.i = 0;
if ( ShaderParam.RenderState [ BD3DRS_ZENABLE ] )
{
u32 condition;
switch ( ShaderParam.RenderState [ BD3DRS_ZFUNC ] )
{
case BD3DCMP_LESSEQUAL:
condition = a < pShader.z[pShader.i];
break;
case BD3DCMP_EQUAL:
condition = a != pShader.z[pShader.i];
break;
}
while ( a < pShader.z[pShader.i] )
{
a += b;
pShader.i += 1;
if ( pShader.i > pShader.dx )
return;
}
}
line.w[0] = a;
line.w[1] = b;
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->lock() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
a = (f32) pShader.i + subPixel;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;
line.c[i][0] += line.c[i][1] * a;
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
line.t[i][1] = (line.t[i][1] - line.t[i][0]) * invDeltaX;
line.t[i][0] += line.t[i][1] * a;
}
for ( ; pShader.i <= pShader.dx; ++pShader.i )
{
if ( line.w[0] >= pShader.z[pShader.i] )
{
pShader.z[pShader.i] = line.w[0];
pShader_EMT_LIGHTMAP_M4 ();
}
line.w[0] += line.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][0] += line.c[i][1];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
line.t[i][0] += line.t[i][1];
}
}
}
void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
sScanConvertData scan;
u32 i;
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y );
scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y );
scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = a->Pos.y - c->Pos.y;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = b->Pos.y - a->Pos.y;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > (f32) 0.0 ? 0 : 1;
scan.right = 1 - scan.left;
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] = a->Color[i];
scan.slopeC[i][0] = (c->Color[i] - a->Color[i]) * scan.invDeltaY[0];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] = a->Tex[i];
scan.slopeT[i][0] = (c->Tex[i] - a->Tex[i]) * scan.invDeltaY[0];
}
s32 yStart;
s32 yEnd;
f32 subPixel;
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][1] = a->Color[i];
scan.slopeC[i][1] = (b->Color[i] - a->Color[i]) * scan.invDeltaY[1];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][1] = a->Tex[i];
scan.slopeT[i][1] = (b->Tex[i] - a->Tex[i]) * scan.invDeltaY[1];
}
yStart = core::ceil32( a->Pos.y );
yEnd = core::ceil32( b->Pos.y ) - 1;
subPixel = ( (f32) yStart ) - a->Pos.y;
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0] * subPixel;
scan.c[i][1] += scan.slopeC[i][1] * subPixel;
}
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0] * subPixel;
scan.t[i][1] += scan.slopeT[i][1] * subPixel;
}
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.w[scan.left] = scan.w[0];
line.x[scan.right] = scan.x[1];
line.w[scan.right] = scan.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][scan.left] = scan.c[i][0];
line.c[i][scan.right] = scan.c[i][1];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
line.t[i][scan.left] = scan.t[i][0];
line.t[i][scan.right] = scan.t[i][1];
}
scanline ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0];
scan.c[i][1] += scan.slopeC[i][1];
}
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0];
scan.t[i][1] += scan.slopeT[i][1];
}
}
}
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y;
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] = a->Color[i] + scan.slopeC[i][0] * temp[0];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] = a->Tex[i] + scan.slopeT[i][0] * temp[0];
}
}
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][1] = b->Color[i];
scan.slopeC[i][1] = (c->Color[i] - b->Color[i]) * scan.invDeltaY[2];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][1] = b->Tex[i];
scan.slopeT[i][1] = (c->Tex[i] - b->Tex[i]) * scan.invDeltaY[2];
}
yStart = core::ceil32( b->Pos.y );
yEnd = core::ceil32( c->Pos.y ) - 1;
subPixel = ( (f32) yStart ) - b->Pos.y;
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0] * subPixel;
scan.c[i][1] += scan.slopeC[i][1] * subPixel;
}
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0] * subPixel;
scan.t[i][1] += scan.slopeT[i][1] * subPixel;
}
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.w[scan.left] = scan.w[0];
line.x[scan.right] = scan.x[1];
line.w[scan.right] = scan.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][scan.left] = scan.c[i][0];
line.c[i][scan.right] = scan.c[i][1];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
line.t[i][scan.left] = scan.t[i][0];
line.t[i][scan.right] = scan.t[i][1];
}
scanline ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0];
scan.c[i][1] += scan.slopeC[i][1];
}
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0];
scan.t[i][1] += scan.slopeT[i][1];
}
}
}
}
}
}
namespace irr
{
namespace video
{
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver)
{
return new CBurningShader_Raster_Reference(driver);
}
}
}
#endif