Commit 976b62fc authored by engineer_apple's avatar engineer_apple

Burningvideo - add Stencil Shadow Rendering (one color only and 32 bit only),...

Burningvideo - add Stencil Shadow Rendering (one color only and 32 bit only), pushed Burningvideo to 0.47

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3337 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 2a8461a4
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
Changes in 1.7.1 (05.07.2010) TA Changes in 1.7.1 (05.07.2010) TA
- BurningVideo - BurningVideo
- add Normalmap Rendering ( one light only), pushed Burningvideo to 0.46 - add Normalmap Rendering ( one light only), pushed Burningvideo to 0.46
- add Stencil Shadow Rendering (one color only and 32 bit only), pushed Burningvideo to 0.47
- internal vertexformat changed - internal vertexformat changed
- changed fixpoint from 9 to 10 bit fract resolution - changed fixpoint from 9 to 10 bit fract resolution
- renamed createBurningVideoDriver to createBurningVideoDriver and uses SIrrlichtCreationParameters like opengl - renamed createBurningVideoDriver to createBurningVideoDriver and uses SIrrlichtCreationParameters like opengl
......
...@@ -25,7 +25,6 @@ using namespace irr; ...@@ -25,7 +25,6 @@ using namespace irr;
int main() int main()
{ {
// ask if user would like shadows // ask if user would like shadows
/*
char i; char i;
printf("Please press 'y' if you want to use realtime shadows.\n"); printf("Please press 'y' if you want to use realtime shadows.\n");
...@@ -37,9 +36,7 @@ int main() ...@@ -37,9 +36,7 @@ int main()
video::E_DRIVER_TYPE driverType=driverChoiceConsole(); video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT) if (driverType==video::EDT_COUNT)
return 1; return 1;
*/
video::E_DRIVER_TYPE driverType = video::EDT_BURNINGSVIDEO;// video::EDT_DIRECT3D9; // video::EDT_BURNINGSVIDEO; // video::EDT_OPENGL; //video::EDT_BURNINGSVIDEO;
bool shadows = true;
/* /*
Create device and exit if creation failed. We make the stencil flag Create device and exit if creation failed. We make the stencil flag
......
...@@ -63,7 +63,7 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows, ...@@ -63,7 +63,7 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
box->addItem(L"OpenGL 1.5"); box->addItem(L"OpenGL 1.5");
box->addItem(L"Direct3D 8.1"); box->addItem(L"Direct3D 8.1");
box->addItem(L"Direct3D 9.0c"); box->addItem(L"Direct3D 9.0c");
box->addItem(L"Burning's Video 0.46"); box->addItem(L"Burning's Video 0.47");
box->addItem(L"Irrlicht Software Renderer 1.0"); box->addItem(L"Irrlicht Software Renderer 1.0");
box->setSelected(selected); box->setSelected(selected);
......
...@@ -3443,7 +3443,9 @@ void COpenGLDriver::drawStencilShadowVolume(const core::vector3df* triangles, s3 ...@@ -3443,7 +3443,9 @@ void COpenGLDriver::drawStencilShadowVolume(const core::vector3df* triangles, s3
glPopAttrib(); glPopAttrib();
} }
//! Fills the stencil shadow with color. After the shadow volume has been drawn
//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
//! to draw the color of the shadow.
void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge, void COpenGLDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge) video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
{ {
......
...@@ -651,7 +651,7 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core: ...@@ -651,7 +651,7 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core:
} }
else else
{ {
Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] ); //Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] );
Transformation[ETS_CURRENT].setbyproduct_nocheck ( Transformation[ETS_CURRENT].setbyproduct_nocheck (
Transformation[ETS_VIEW_PROJECTION], Transformation[ETS_VIEW_PROJECTION],
Transformation[ETS_WORLD] Transformation[ETS_WORLD]
...@@ -1155,7 +1155,8 @@ const SVSize CBurningVideoDriver::vSize[] = ...@@ -1155,7 +1155,8 @@ const SVSize CBurningVideoDriver::vSize[] =
{ VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 }, { VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 },
{ VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 }, { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 },
{ VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 }, { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 },
{ VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 }, { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 }, // reflection map
{ 0, sizeof(f32) * 3, 0 }, // core::vector3df*
}; };
...@@ -1185,6 +1186,9 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest ...@@ -1185,6 +1186,9 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
const S3DVertex *base = ((S3DVertex*) source ); const S3DVertex *base = ((S3DVertex*) source );
Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos ); Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos );
//mhm ;-) maybe no goto
if ( VertexCache.vType == 4 ) goto clipandproject;
#if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) #if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )
...@@ -1443,6 +1447,7 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest ...@@ -1443,6 +1447,7 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
#endif #endif
clipandproject:
dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format; dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format;
// test vertex // test vertex
...@@ -1501,10 +1506,18 @@ REALINLINE void CBurningVideoDriver::VertexCache_get ( s4DVertex ** face ) ...@@ -1501,10 +1506,18 @@ REALINLINE void CBurningVideoDriver::VertexCache_get ( s4DVertex ** face )
fillIndex < VERTEXCACHE_ELEMENT fillIndex < VERTEXCACHE_ELEMENT
) )
{ {
sourceIndex = VertexCache.iType == 1 ? switch ( VertexCache.iType )
((u16*)VertexCache.indices) [ VertexCache.indicesIndex ] : {
((u32*)VertexCache.indices) [ VertexCache.indicesIndex ]; case 1:
sourceIndex = ((u16*)VertexCache.indices) [ VertexCache.indicesIndex ];
break;
case 2:
sourceIndex = ((u32*)VertexCache.indices) [ VertexCache.indicesIndex ];
break;
case 4:
sourceIndex = VertexCache.indicesIndex;
break;
}
VertexCache.indicesIndex += 1; VertexCache.indicesIndex += 1;
...@@ -1566,19 +1579,28 @@ REALINLINE void CBurningVideoDriver::VertexCache_get ( s4DVertex ** face ) ...@@ -1566,19 +1579,28 @@ REALINLINE void CBurningVideoDriver::VertexCache_get ( s4DVertex ** face )
const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );
if ( VertexCache.iType == 1 ) switch ( VertexCache.iType )
{ {
const u16 *p = (const u16 *) VertexCache.indices; case 1:
face[0] = VertexCache_getVertex ( p[ i0 ] ); {
face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); const u16 *p = (const u16 *) VertexCache.indices;
face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); face[0] = VertexCache_getVertex ( p[ i0 ] );
} face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] );
else face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] );
{ } break;
const u32 *p = (const u32 *) VertexCache.indices;
face[0] = VertexCache_getVertex ( p[ i0 ] ); case 2:
face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] ); {
face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] ); const u32 *p = (const u32 *) VertexCache.indices;
face[0] = VertexCache_getVertex ( p[ i0 ] );
face[1] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 1] );
face[2] = VertexCache_getVertex ( p[ VertexCache.indicesRun + 2] );
} break;
case 4:
face[0] = VertexCache_getVertex ( VertexCache.indicesRun + 0 );
face[1] = VertexCache_getVertex ( VertexCache.indicesRun + 1 );
face[2] = VertexCache_getVertex ( VertexCache.indicesRun + 2 );
break;
} }
VertexCache.indicesRun += VertexCache.primitivePitch; VertexCache.indicesRun += VertexCache.primitivePitch;
...@@ -1633,7 +1655,14 @@ void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCo ...@@ -1633,7 +1655,14 @@ void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCo
else else
VertexCache.vType = vType; VertexCache.vType = vType;
VertexCache.pType = pType; VertexCache.pType = pType;
VertexCache.iType = iType == EIT_16BIT ? 1 : 2;
switch ( iType )
{
case EIT_16BIT: VertexCache.iType = 1; break;
case EIT_32BIT: VertexCache.iType = 2; break;
default:
VertexCache.iType = iType; break;
}
switch ( VertexCache.pType ) switch ( VertexCache.pType )
{ {
...@@ -2451,13 +2480,13 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start, ...@@ -2451,13 +2480,13 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start,
const wchar_t* CBurningVideoDriver::getName() const const wchar_t* CBurningVideoDriver::getName() const
{ {
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
return L"Burning's Video 0.46 beautiful"; return L"Burning's Video 0.47 beautiful";
#elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) #elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST )
return L"Burning's Video 0.46 ultra fast"; return L"Burning's Video 0.47 ultra fast";
#elif defined ( BURNINGVIDEO_RENDERER_FAST ) #elif defined ( BURNINGVIDEO_RENDERER_FAST )
return L"Burning's Video 0.46 fast"; return L"Burning's Video 0.47 fast";
#else #else
return L"Burning's Video 0.46"; return L"Burning's Video 0.47";
#endif #endif
} }
...@@ -2555,20 +2584,36 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::vector3df* triangl ...@@ -2555,20 +2584,36 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::vector3df* triangl
return; return;
IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ]; IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ];
CurrentShader = shader;
shader->setRenderTarget(RenderTargetSurface, ViewPort); shader->setRenderTarget(RenderTargetSurface, ViewPort);
Material.org.MaterialType = video::EMT_SOLID;
Material.org.Lighting = false;
Material.org.ZWriteEnable = false;
Material.org.ZBuffer = ECFN_LESSEQUAL;
LightSpace.Flags &= ~VERTEXTRANSFORM;
//glStencilMask(~0); //glStencilMask(~0);
//glStencilFunc(GL_ALWAYS, 0, ~0); //glStencilFunc(GL_ALWAYS, 0, ~0);
if (zfail) if (zfail)
{ {
Material.org.BackfaceCulling = false; Material.org.BackfaceCulling = true;
Material.org.FrontfaceCulling = true; Material.org.FrontfaceCulling = false;
shader->setParam ( 0, 0 );
shader->setParam ( 1, 1 );
shader->setParam ( 2, 0 );
drawVertexPrimitiveList ( triangles, count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );
//glStencilOp(GL_KEEP, incr, GL_KEEP); //glStencilOp(GL_KEEP, incr, GL_KEEP);
//glDrawArrays(GL_TRIANGLES,0,count); //glDrawArrays(GL_TRIANGLES,0,count);
Material.org.BackfaceCulling = true; Material.org.BackfaceCulling = false;
Material.org.FrontfaceCulling = false; Material.org.FrontfaceCulling = true;
shader->setParam ( 0, 0 );
shader->setParam ( 1, 2 );
shader->setParam ( 2, 0 );
drawVertexPrimitiveList ( triangles, count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );
//glStencilOp(GL_KEEP, decr, GL_KEEP); //glStencilOp(GL_KEEP, decr, GL_KEEP);
//glDrawArrays(GL_TRIANGLES,0,count); //glDrawArrays(GL_TRIANGLES,0,count);
} }
...@@ -2576,87 +2621,54 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::vector3df* triangl ...@@ -2576,87 +2621,54 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::vector3df* triangl
{ {
Material.org.BackfaceCulling = true; Material.org.BackfaceCulling = true;
Material.org.FrontfaceCulling = false; Material.org.FrontfaceCulling = false;
shader->setParam ( 0, 0 );
shader->setParam ( 1, 0 );
shader->setParam ( 2, 1 );
//glStencilOp(GL_KEEP, GL_KEEP, incr); //glStencilOp(GL_KEEP, GL_KEEP, incr);
//glDrawArrays(GL_TRIANGLES,0,count); //glDrawArrays(GL_TRIANGLES,0,count);
Material.org.BackfaceCulling = false; Material.org.BackfaceCulling = false;
Material.org.FrontfaceCulling = true; Material.org.FrontfaceCulling = true;
shader->setParam ( 0, 0 );
shader->setParam ( 1, 0 );
shader->setParam ( 2, 2 );
//glStencilOp(GL_KEEP, GL_KEEP, decr); //glStencilOp(GL_KEEP, GL_KEEP, decr);
//glDrawArrays(GL_TRIANGLES,0,count); //glDrawArrays(GL_TRIANGLES,0,count);
} }
#if 0 }
if (!StencilBuffer || !count)
return;
// unset last 3d material
if (CurrentRenderMode == ERM_3D &&
static_cast<u32>(Material.MaterialType) < MaterialRenderers.size())
{
MaterialRenderers[Material.MaterialType].Renderer->OnUnsetMaterial();
ResetRenderStates = true;
}
// store current OpenGL state
glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT |
GL_POLYGON_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glDepthFunc(GL_LEQUAL);
glDepthMask(GL_FALSE); // no depth buffer writing
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no color buffer drawing
glEnable(GL_STENCIL_TEST);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(0.0f, 1.0f);
glEnableClientState(GL_VERTEX_ARRAY); //! Fills the stencil shadow with color. After the shadow volume has been drawn
glVertexPointer(3,GL_FLOAT,sizeof(core::vector3df),&triangles[0]); //! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this
glStencilMask(~0); //! to draw the color of the shadow.
glStencilFunc(GL_ALWAYS, 0, ~0); void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
{
if (!StencilBuffer)
return;
GLenum incr = GL_INCR; // draw a shadow rectangle covering the entire screen using stencil buffer
GLenum decr = GL_DECR; const u32 h = RenderTargetSurface->getDimension().Height;
if (FeatureAvailable[IRR_EXT_stencil_wrap]) const u32 w = RenderTargetSurface->getDimension().Width;
{ tVideoSample *dst;
incr = GL_INCR_WRAP_EXT; u32 *stencil;
decr = GL_DECR_WRAP_EXT;
}
for ( u32 y = 0; y < h; ++y )
{ {
glEnable(GL_CULL_FACE); dst = (tVideoSample*)RenderTargetSurface->lock() + ( y * w );
if (zfail) stencil = (u32*) StencilBuffer->lock() + ( y * w );
{
glCullFace(GL_FRONT);
glStencilOp(GL_KEEP, incr, GL_KEEP);
glDrawArrays(GL_TRIANGLES,0,count);
glCullFace(GL_BACK); for ( u32 x = 0; x < w; ++x )
glStencilOp(GL_KEEP, decr, GL_KEEP);
glDrawArrays(GL_TRIANGLES,0,count);
}
else // zpass
{ {
glCullFace(GL_BACK); if ( stencil[x] > 1 )
glStencilOp(GL_KEEP, GL_KEEP, incr); {
glDrawArrays(GL_TRIANGLES,0,count); dst[x] = PixelBlend32 ( dst[x], leftUpEdge.color );
}
glCullFace(GL_FRONT);
glStencilOp(GL_KEEP, GL_KEEP, decr);
glDrawArrays(GL_TRIANGLES,0,count);
} }
} }
glDisableClientState(GL_VERTEX_ARRAY); //not stored on stack StencilBuffer->clear();
glPopAttrib();
#endif
}
void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,
video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)
{
#if 0 #if 0
if (!StencilBuffer) if (!StencilBuffer)
return; return;
......
...@@ -159,6 +159,7 @@ namespace video ...@@ -159,6 +159,7 @@ namespace video
virtual core::dimension2du getMaxTextureSize() const; virtual core::dimension2du getMaxTextureSize() const;
virtual IDepthBuffer * getDepthBuffer () { return DepthBuffer; } virtual IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
virtual IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
protected: protected:
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
// define render case // define render case
#define SUBTEXEL #define SUBTEXEL
#define INVERSE_W //#define INVERSE_W
#define USE_ZBUFFER #define USE_ZBUFFER
#define USE_SBUFFER #define USE_SBUFFER
...@@ -85,10 +85,15 @@ public: ...@@ -85,10 +85,15 @@ public:
//! draws an indexed triangle list //! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ); virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void setParam ( u32 index, f32 value);
private: private:
void scanline (); // fragment shader
typedef void (CTRStencilShadow::*tFragmentShader) ();
void fragment_zfail_decr ();
void fragment_zfail_incr ();
tFragmentShader fragmentShader;
sScanConvertData scan; sScanConvertData scan;
sScanLineData line; sScanLineData line;
...@@ -108,9 +113,30 @@ CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver) ...@@ -108,9 +113,30 @@ CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRStencilShadow::scanline () void CTRStencilShadow::setParam ( u32 index, f32 value)
{
u32 val = (u32) value;
// glStencilOp (fail,zfail,zpass
if ( index == 1 && val == 1 )
{
fragmentShader = &CTRStencilShadow::fragment_zfail_incr;
}
else
if ( index == 1 && val == 2 )
{
fragmentShader = &CTRStencilShadow::fragment_zfail_decr;
}
}
/*!
*/
void CTRStencilShadow::fragment_zfail_decr ()
{ {
tVideoSample *dst; //tVideoSample *dst;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
fp24 *z; fp24 *z;
...@@ -204,7 +230,7 @@ void CTRStencilShadow::scanline () ...@@ -204,7 +230,7 @@ void CTRStencilShadow::scanline ()
#endif #endif
#endif #endif
dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; //dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
...@@ -230,24 +256,167 @@ void CTRStencilShadow::scanline () ...@@ -230,24 +256,167 @@ void CTRStencilShadow::scanline ()
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
#endif #endif
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] < z[i] )
#endif #endif
{ {
#ifdef INVERSE_W // zfail
inversew = fix_inverse32 ( line.w[0] ); stencil[i] -= 1;
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2];
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0];
#endif
}
}
/*!
*/
void CTRStencilShadow::fragment_zfail_incr ()
{
//tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
#ifdef USE_SBUFFER
u32 *stencil;
#endif
s32 xStart;
s32 xEnd;
s32 dx;
#ifdef SUBTEXEL
f32 subPixel;
#endif
#ifdef IPOL_Z
f32 slopeZ;
#endif
#ifdef IPOL_W
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32( line.x[0] );
xEnd = core::ceil32( line.x[1] ) - 1;
dx = xEnd - xStart;
#else if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
#endif
#ifdef IPOL_W
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T2
slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;
#endif
#ifdef IPOL_L0
slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
#endif #endif
dst[i] = 0xFFFFFFFF; #ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
#ifdef IPOL_W
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#ifdef IPOL_T2
line.t[2][0] += slopeT[2] * subPixel;
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0] * subPixel;
#endif
#endif
//dst = (tVideoSample*)RenderTarget->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef WRITE_Z #ifdef USE_ZBUFFER
z[i] = line.z[0]; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif #endif
#ifdef WRITE_W
z[i] = line.w[0]; #ifdef USE_SBUFFER
stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif #endif
#ifdef INVERSE_W
f32 inversew;
#endif
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] < z[i] )
#endif
{
// zfail
stencil[i] += 1;
} }
#ifdef IPOL_Z #ifdef IPOL_Z
...@@ -485,7 +654,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons ...@@ -485,7 +654,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif #endif
// render a scanline // render a scanline
scanline (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
...@@ -693,7 +862,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons ...@@ -693,7 +862,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif #endif
// render a scanline // render a scanline
scanline (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
......
...@@ -39,6 +39,11 @@ namespace video ...@@ -39,6 +39,11 @@ namespace video
DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer (); DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();
if ( DepthBuffer ) if ( DepthBuffer )
DepthBuffer->grab(); DepthBuffer->grab();
Stencil = (CStencilBuffer*) driver->getStencilBuffer ();
if ( Stencil )
Stencil->grab();
} }
...@@ -51,6 +56,9 @@ namespace video ...@@ -51,6 +56,9 @@ namespace video
if (DepthBuffer) if (DepthBuffer)
DepthBuffer->drop(); DepthBuffer->drop();
if (Stencil)
Stencil->drop();
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i ) for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{ {
if ( IT[i].Texture ) if ( IT[i].Texture )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment