- BurningVideo: 0.50

- 10 year anniversary update
  - Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map] 
  - increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]
  - Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption
  - 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D
  - Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]
  - SuperTuxKart 8.0.1 playable


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6086 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
engineer_apple 2020-02-22 20:48:12 +00:00
parent 9c837aa41b
commit 86dd0cde26
57 changed files with 10240 additions and 3736 deletions

View File

@ -1,5 +1,13 @@
--------------------------
Changes in 1.9 (not yet released)
- BurningVideo: 0.50
- 10 year anniversary update
- Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map]
- increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]
- Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption
- 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D
- Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]
- SuperTuxKart 8.0.1 playable
- Fix CPLYMeshFileLoader checking for wrong vertex count when switching between 16/32 bit. Thanks @randomMesh for reporting.
- Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes.
- Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function.

View File

@ -10,6 +10,28 @@
namespace irr
{
//! f18 - fixpoint 14.18 limit to 16k Textures
#define CBLIT_USE_FIXPOINT18
#if defined(CBLIT_USE_FIXPOINT18)
typedef int f18;
#define f18_one 262144
#define f18_zero 0
#define f32_to_f18(x)((f18)floorf(((x) * 262144.f) + 0.f))
#define f32_to_f32(x)(x)
#define f18_floor(x) ((x)>>18)
#define f18_round(x) ((x+131.072)>>18)
#else
typedef float f18;
#define f18_one 1.f
#define f18_zero_dot_five 0.5f
#define f18_zero 0.f
#define f32_to_f18(x)(x)
#define f32_to_f32(x)(x)
#define f18_floor(x) ((int)(x))
#define f18_round(x) ((int)(x+0.5f))
#endif
struct SBlitJob
{
AbsRectangle Dest;
@ -17,23 +39,21 @@ namespace irr
u32 argb;
void * src;
void * dst;
const void* src;
void* dst;
s32 width;
s32 height;
u32 width; //draw size
u32 height;
u32 srcPitch;
u32 dstPitch;
u32 srcPixelMul;
u32 srcPixelMul; //pixel byte size
u32 dstPixelMul;
bool stretch;
float x_stretch;
float y_stretch;
u32 srcPitch; //scanline byte size
u32 dstPitch;
SBlitJob() : stretch(false) {}
bool stretch;
f32 x_stretch;
f32 y_stretch;
};
// Bitfields Cohen Sutherland
@ -237,7 +257,7 @@ static void RenderLine32_Decal(video::IImage *t,
}
u32 *dst;
dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );
dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );
if ( dy > dx )
{
@ -301,7 +321,7 @@ static void RenderLine32_Blend(video::IImage *t,
}
u32 *dst;
dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );
dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );
if ( dy > dx )
{
@ -365,7 +385,7 @@ static void RenderLine16_Decal(video::IImage *t,
}
u16 *dst;
dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );
dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );
if ( dy > dx )
{
@ -429,7 +449,7 @@ static void RenderLine16_Blend(video::IImage *t,
}
u16 *dst;
dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );
dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );
if ( dy > dx )
{
@ -467,37 +487,57 @@ static void RenderLine16_Blend(video::IImage *t,
*/
static void executeBlit_TextureCopy_x_to_x( const SBlitJob * job )
{
const u32 w = job->width;
const u32 h = job->height;
if (job->stretch)
{
const u32 *src = static_cast<const u32*>(job->src);
u32 *dst = static_cast<u32*>(job->dst);
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const f18 wscale = f32_to_f18(job->x_stretch);
const f18 hscale = f32_to_f18(job->y_stretch);
for ( u32 dy = 0; dy < h; ++dy )
f18 src_y = f18_zero;
if (job->srcPixelMul == 4)
{
const u32 src_y = (u32)(dy*hscale);
src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
const u32 *src = (u32*)(job->src);
u32 *dst = (u32*)(job->dst);
for ( u32 dx = 0; dx < w; ++dx )
for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
const u32 src_x = (u32)(dx*wscale);
dst[dx] = src[src_x];
src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
f18 src_x = f18_zero;
for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
dst[dx] = src[f18_floor(src_x)];
}
dst = (u32*)((u8*)(dst)+job->dstPitch);
}
}
else if (job->srcPixelMul == 2)
{
const u16 *src = (u16*)(job->src);
u16* dst = (u16*)(job->dst);
for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
f18 src_x = f18_zero;
for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
dst[dx] = src[f18_floor(src_x)];
}
dst = (u16*)((u8*)(dst)+job->dstPitch);
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
const u32 widthPitch = job->width * job->dstPixelMul;
const size_t widthPitch = job->width * job->dstPixelMul;
const void *src = (void*) job->src;
void *dst = (void*) job->dst;
for ( u32 dy = 0; dy != h; ++dy )
for ( u32 dy = 0; dy < job->height; ++dy )
{
memcpy( dst, src, widthPitch );
memcpy( dst, src, widthPitch);
src = (void*) ( (u8*) (src) + job->srcPitch );
dst = (void*) ( (u8*) (dst) + job->dstPitch );
@ -516,8 +556,8 @@ static void executeBlit_TextureCopy_32_to_16( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -562,8 +602,8 @@ static void executeBlit_TextureCopy_24_to_16( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 3.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch * 3.f;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -607,8 +647,8 @@ static void executeBlit_TextureCopy_16_to_32( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -647,8 +687,8 @@ static void executeBlit_TextureCopy_16_to_24( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -697,8 +737,8 @@ static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 3.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch * 3.f;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -715,11 +755,11 @@ static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job )
}
else
{
for ( s32 dy = 0; dy != job->height; ++dy )
for ( u32 dy = 0; dy < job->height; ++dy )
{
const u8* s = src;
for ( s32 dx = 0; dx != job->width; ++dx )
for ( u32 dx = 0; dx < job->width; ++dx )
{
dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];
s += 3;
@ -740,8 +780,8 @@ static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -781,54 +821,21 @@ static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job )
*/
static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )
{
const u32 w = job->width;
const u32 h = job->height;
const u32 rdx = w>>1;
const f18 wscale = f32_to_f18(job->x_stretch);
const f18 hscale = f32_to_f18(job->y_stretch);
const u32 *src = (u32*) job->src;
u32 *dst = (u32*) job->dst;
f18 src_y = f18_zero;
u16 *dst = (u16*)job->dst;
if (job->stretch)
for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const u32 off = core::if_c_a_else_b(w&1, (u32)((w-1)*wscale), 0);
for ( u32 dy = 0; dy < h; ++dy )
const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
f18 src_x = f18_zero;
for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
const u32 src_y = (u32)(dy*hscale);
src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
for ( u32 dx = 0; dx < rdx; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
dst[dx] = PixelBlend16_simd( dst[dx], src[src_x] );
}
if ( off )
{
((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
const u32 off = core::if_c_a_else_b(w&1, w-1, 0);
for (u32 dy = 0; dy != h; ++dy )
{
for (u32 dx = 0; dx != rdx; ++dx )
{
dst[dx] = PixelBlend16_simd( dst[dx], src[dx] );
}
if ( off )
{
((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );
}
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
dst[dx] = PixelBlend16(dst[dx], src[f18_floor(src_x)]);
}
dst = (u16*)((u8*)(dst)+job->dstPitch);
}
}
@ -836,40 +843,21 @@ static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )
*/
static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )
{
const u32 w = job->width;
const u32 h = job->height;
const u32 *src = (u32*) job->src;
u32 *dst = (u32*) job->dst;
const f18 wscale = f32_to_f18(job->x_stretch);
const f18 hscale = f32_to_f18(job->y_stretch);
if (job->stretch)
f18 src_y = f18_zero;
u32 *dst = (u32*)job->dst;
for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
const u32 src_y = (u32)(dy*hscale);
src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
for ( u32 dx = 0; dx < w; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
dst[dx] = PixelBlend32( dst[dx], src[src_x] );
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
for ( u32 dy = 0; dy != h; ++dy )
f18 src_x = f18_zero;
for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
for ( u32 dx = 0; dx != w; ++dx )
{
dst[dx] = PixelBlend32( dst[dx], src[dx] );
}
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
dst[dx] = PixelBlend32(dst[dx], src[f18_floor(src_x)]);
}
dst = (u32*)((u8*)(dst)+job->dstPitch);
}
}
@ -877,21 +865,26 @@ static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )
*/
static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job )
{
u16 *src = (u16*) job->src;
u16 *dst = (u16*) job->dst;
const u16 blend = video::A8R8G8B8toA1R5G5B5(job->argb);
u16 blend = video::A8R8G8B8toA1R5G5B5 ( job->argb );
for ( s32 dy = 0; dy != job->height; ++dy )
const f18 wscale = f32_to_f18(job->x_stretch);
const f18 hscale = f32_to_f18(job->y_stretch);
f18 src_y = f18_zero;
u16 *dst = (u16*)job->dst;
for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
for ( s32 dx = 0; dx != job->width; ++dx )
const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
f18 src_x = f18_zero;
for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
if ( 0 == (src[dx] & 0x8000) )
register u16 c0 = src[f18_floor(src_x)];
if (0 == (c0 & 0x8000))
continue;
dst[dx] = PixelMul16_2( src[dx], blend );
dst[dx] = PixelMul16_2(c0, blend);
}
src = (u16*) ( (u8*) (src) + job->srcPitch );
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
dst = (u16*)((u8*)(dst)+job->dstPitch);
}
}
@ -900,17 +893,21 @@ static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job )
*/
static void executeBlit_TextureBlendColor_32_to_32( const SBlitJob * job )
{
u32 *src = (u32*) job->src;
u32 *dst = (u32*) job->dst;
const f18 wscale = f32_to_f18(job->x_stretch);
const f18 hscale = f32_to_f18(job->y_stretch);
for ( s32 dy = 0; dy != job->height; ++dy )
u32* dst = (u32*)job->dst;
f18 src_y = f18_zero;
for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)
{
for ( s32 dx = 0; dx != job->width; ++dx )
const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));
f18 src_x = f18_zero;
for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)
{
dst[dx] = PixelBlend32( dst[dx], PixelMul32_2( src[dx], job->argb ) );
dst[dx] = PixelBlend32(dst[dx], PixelMul32_2(src[f18_floor(src_x)], job->argb));
}
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
dst = (u32*)((u8*)(dst)+job->dstPitch);
}
}
@ -921,7 +918,7 @@ static void executeBlit_Color_16_to_16( const SBlitJob * job )
const u16 c = video::A8R8G8B8toA1R5G5B5(job->argb);
u16 *dst = (u16*) job->dst;
for ( s32 dy = 0; dy != job->height; ++dy )
for ( u32 dy = 0; dy < job->height; ++dy )
{
memset16(dst, c, job->srcPitch);
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
@ -934,7 +931,7 @@ static void executeBlit_Color_32_to_32( const SBlitJob * job )
{
u32 *dst = (u32*) job->dst;
for ( s32 dy = 0; dy != job->height; ++dy )
for ( u32 dy = 0; dy < job->height; ++dy )
{
memset32( dst, job->argb, job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
@ -952,11 +949,11 @@ static void executeBlit_ColorAlpha_16_to_16( const SBlitJob * job )
return;
const u32 src = video::A8R8G8B8toA1R5G5B5( job->argb );
for ( s32 dy = 0; dy != job->height; ++dy )
for ( u32 dy = 0; dy != job->height; ++dy )
{
for ( s32 dx = 0; dx != job->width; ++dx )
for ( u32 dx = 0; dx != job->width; ++dx )
{
dst[dx] = 0x8000 | PixelBlend16( dst[dx], src, alpha );
dst[dx] = PixelBlend16( dst[dx], src, alpha );
}
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
}
@ -966,19 +963,33 @@ static void executeBlit_ColorAlpha_16_to_16( const SBlitJob * job )
*/
static void executeBlit_ColorAlpha_32_to_32( const SBlitJob * job )
{
u32 *dst = (u32*) job->dst;
const u32 alpha = extractAlpha( job->argb );
const u32 src = job->argb;
if (0 == alpha)
return;
for ( s32 dy = 0; dy != job->height; ++dy )
u32 *dst = (u32*)job->dst;
for ( u32 dy = 0; dy < job->height; ++dy )
{
for ( s32 dx = 0; dx != job->width; ++dx )
for ( u32 dx = 0; dx < job->width; ++dx )
{
dst[dx] = (job->argb & 0xFF000000 ) | PixelBlend32( dst[dx], src, alpha );
dst[dx] = PixelBlend32( dst[dx], job->argb, alpha );
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
/*!
Pixel =>
color = sourceAlpha > 0 ? source, else dest
alpha = max(destAlpha, sourceAlpha)
*/
inline u16 PixelCombine16(const u16 c2, const u16 c1)
{
if (video::getAlpha(c1) > 0)
return c1;
else
return c2;
}
/*!
@ -1023,8 +1034,8 @@ static void executeBlit_TextureCombineColor_16_to_24( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -1068,6 +1079,58 @@ static void executeBlit_TextureCombineColor_16_to_24( const SBlitJob * job )
}
}
/*!
Pixel =>
color = dest * ( 1 - SourceAlpha ) + source * SourceAlpha,
alpha = destAlpha * ( 1 - SourceAlpha ) + sourceAlpha
where "1" means "full scale" (255)
*/
inline u32 PixelCombine32(const u32 c2, const u32 c1)
{
// alpha test
u32 alpha = c1 & 0xFF000000;
if (0 == alpha)
return c2;
if (0xFF000000 == alpha)
{
return c1;
}
alpha >>= 24;
// add highbit alpha, if ( alpha > 127 ) alpha += 1;
// stretches [0;255] to [0;256] to avoid division by 255. use division 256 == shr 8
alpha += (alpha >> 7);
u32 srcRB = c1 & 0x00FF00FF;
u32 srcXG = c1 & 0x0000FF00;
u32 dstRB = c2 & 0x00FF00FF;
u32 dstXG = c2 & 0x0000FF00;
u32 rb = srcRB - dstRB;
u32 xg = srcXG - dstXG;
rb *= alpha;
xg *= alpha;
rb >>= 8;
xg >>= 8;
rb += dstRB;
xg += dstXG;
rb &= 0x00FF00FF;
xg &= 0x0000FF00;
u32 sa = c1 >> 24;
u32 da = c2 >> 24;
u32 blendAlpha_fix8 = (sa * 256 + da * (256 - alpha)) >> 8;
return blendAlpha_fix8 << 24 | rb | xg;
}
/*!
Combine alpha channels (increases alpha / reduces transparency)
Destination alpha is treated as full 255
@ -1081,8 +1144,8 @@ static void executeBlit_TextureCombineColor_32_to_24( const SBlitJob * job )
if (job->stretch)
{
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const float wscale = job->x_stretch;
const float hscale = job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{
@ -1130,9 +1193,9 @@ static void executeBlit_TextureCombineColor_32_to_32( const SBlitJob * job )
u32 *src = (u32*) job->src;
u32 *dst = (u32*) job->dst;
for ( s32 dy = 0; dy != job->height; ++dy )
for ( u32 dy = 0; dy != job->height; ++dy )
{
for ( s32 dx = 0; dx != job->width; ++dx )
for (u32 dx = 0; dx != job->width; ++dx )
{
dst[dx] = PixelCombine32( dst[dx], PixelMul32_2( src[dx], job->argb ) );
}
@ -1220,26 +1283,46 @@ static inline tExecuteBlit getBlitter2( eBlitter operation,const video::IImage *
// bounce clipping to texture
inline void setClip ( AbsRectangle &out, const core::rect<s32> *clip,
const video::IImage * tex, s32 passnative )
inline void setClip(AbsRectangle &out, const core::rect<s32> *clip,
const video::IImage* tex, s32 passnative, const core::dimension2d<u32>* tex_org)
{
if ( clip && 0 == tex && passnative )
if (0 == tex)
{
out.x0 = clip->UpperLeftCorner.X;
out.x1 = clip->LowerRightCorner.X;
out.y0 = clip->UpperLeftCorner.Y;
out.y1 = clip->LowerRightCorner.Y;
if (clip && passnative)
{
out.x0 = clip->UpperLeftCorner.X;
out.x1 = clip->LowerRightCorner.X;
out.y0 = clip->UpperLeftCorner.Y;
out.y1 = clip->LowerRightCorner.Y;
}
else
{
out.x0 = 0;
out.x1 = 0;
out.y0 = 0;
out.y1 = 0;
}
return;
}
const s32 w = tex ? tex->getDimension().Width : 0;
const s32 h = tex ? tex->getDimension().Height : 0;
if ( clip )
const s32 w = tex->getDimension().Width;
const s32 h = tex->getDimension().Height;
//driver could have changed texture size.
if (clip && tex_org && ((u32)w != tex_org->Width || (u32)h != tex_org->Height))
{
out.x0 = core::s32_clamp ( clip->UpperLeftCorner.X, 0, w );
out.x1 = core::s32_clamp ( clip->LowerRightCorner.X, out.x0, w );
out.y0 = core::s32_clamp ( clip->UpperLeftCorner.Y, 0, h );
out.y1 = core::s32_clamp ( clip->LowerRightCorner.Y, out.y0, h );
out.x0 = core::s32_clamp((clip->UpperLeftCorner.X*w) / tex_org->Width, 0, w - 1);
out.x1 = core::s32_clamp((clip->LowerRightCorner.X*w) / tex_org->Width, out.x0, w);
out.y0 = core::s32_clamp((clip->UpperLeftCorner.Y*h) / tex_org->Height, 0, h - 1);
out.y1 = core::s32_clamp((clip->LowerRightCorner.Y*h) / tex_org->Height, out.y0, h);
}
else if (clip)
{
//y-1 to prevent starting on illegal memory (not ideal!).
out.x0 = core::s32_clamp(clip->UpperLeftCorner.X, 0, w - 1);
out.x1 = core::s32_clamp(clip->LowerRightCorner.X, passnative ? 0 : out.x0, w);
out.y0 = core::s32_clamp(clip->UpperLeftCorner.Y, 0, h - 1);
out.y1 = core::s32_clamp(clip->LowerRightCorner.Y, passnative ? 0 : out.y0, h);
}
else
{
@ -1275,8 +1358,8 @@ static s32 Blit(eBlitter operation,
SBlitJob job;
setClip ( sourceClip, sourceClipping, source, 1 );
setClip ( destClip, destClipping, dest, 0 );
setClip ( sourceClip, sourceClipping, source, 1,0 );
setClip ( destClip, destClipping, dest, 0,0 );
v.x0 = destPos ? destPos->X : 0;
v.y0 = destPos ? destPos->Y : 0;
@ -1296,6 +1379,10 @@ static s32 Blit(eBlitter operation,
job.argb = argb;
job.stretch = false;
job.x_stretch = 1.f;
job.y_stretch = 1.f;
if ( source )
{
job.srcPitch = source->getPitch();
@ -1317,9 +1404,10 @@ static s32 Blit(eBlitter operation,
return 1;
}
#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)
static s32 StretchBlit(eBlitter operation,
video::IImage* dest, const core::rect<s32> *destRect,
const core::rect<s32> *srcRect, video::IImage* const source,
video::IImage* dest, const core::rect<s32>* destClipping,const core::rect<s32> *destRect,
video::IImage* const source,const core::rect<s32> *srcRect, const core::dimension2d<u32>* source_org,
u32 argb)
{
tExecuteBlit blitter = getBlitter2( operation, dest, source );
@ -1330,9 +1418,15 @@ static s32 StretchBlit(eBlitter operation,
SBlitJob job;
AbsRectangle destClip;
AbsRectangle v;
setClip(destClip, destClipping, dest, 0, 0);
setClip(v, destRect, 0, 1, 0);
if (!intersect(job.Dest, destClip, v))
return 0;
// Clipping
setClip ( job.Source, srcRect, source, 1 );
setClip ( job.Dest, destRect, dest, 0 );
setClip ( job.Source, srcRect, source, 1, source_org);
job.width = job.Dest.x1-job.Dest.x0;
job.height = job.Dest.y1-job.Dest.y0;
@ -1340,14 +1434,25 @@ static s32 StretchBlit(eBlitter operation,
job.argb = argb;
// use original dest size, despite any clipping
job.x_stretch = (float)destRect->getWidth() / (float)(job.Source.x1-job.Source.x0);
job.y_stretch = (float)destRect->getHeight() / (float)(job.Source.y1-job.Source.y0);
job.stretch = (job.x_stretch != 1.f) || (job.y_stretch != 1.f);
const int dst_w = v.x1 - v.x0; // destRect->getWidth();
const int dst_h = v.y1 - v.y0; // destRect->getHeight();
const int src_w = job.Source.x1 - job.Source.x0;
const int src_h = job.Source.y1 - job.Source.y0;
job.stretch = dst_w != src_w || dst_h != src_h;
job.x_stretch = dst_w ? (float)src_w / (float)dst_w : 1.f;
job.y_stretch = dst_h ? (float)src_h / (float)dst_h : 1.f;
if ( source )
{
job.srcPitch = source->getPitch();
job.srcPixelMul = source->getBytesPerPixel();
//dest-clippling. advance source. loosing subpixel precision
job.Source.x0 += (s32)floorf(job.x_stretch * (job.Dest.x0 - v.x0));
job.Source.y0 += (s32)floorf(job.y_stretch * (job.Dest.y0 - v.y0));
job.src = (void*) ( (u8*) source->getData() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) );
}
else
@ -1364,7 +1469,7 @@ static s32 StretchBlit(eBlitter operation,
return 1;
}
#endif
// Methods for Software drivers
//! draws a rectangle

View File

@ -5,7 +5,7 @@
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
#if defined(_IRR_COMPILE_WITH_BURNINGSVIDEO_) && 0
namespace irr
@ -558,7 +558,7 @@ void CBurningShader_Raster_Reference::pShader_EMT_LIGHTMAP_M4 ()
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 ) ),
pShader.dst[pShader.i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
@ -578,7 +578,7 @@ void CBurningShader_Raster_Reference::pShader_1 ()
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 );
pShader.dst[pShader.i] = fix_to_sample( r0, g0, b0 );
}
@ -690,15 +690,15 @@ REALINLINE void CBurningShader_Raster_Reference::depthWrite ()
REALINLINE void CBurningShader_Raster_Reference::scanline2()
{
// apply top-left fill-convention, left
pShader.xStart = core::ceil32_fast( line.x[0] );
pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;
pShader.xStart = fill_convention_left( line.x[0] );
pShader.xEnd = fill_convention_right( line.x[1] );
pShader.dx = pShader.xEnd - pShader.xStart;
if ( pShader.dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
// store slopes in endpoint, and correct first pixel
@ -707,7 +707,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
u32 i;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;
@ -721,6 +721,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
line.t[i][0] += line.t[i][1] * subPixel;
}
SOFTWARE_DRIVER_2_CLIPCHECK_REF;
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
@ -734,7 +735,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
// advance next pixel
line.w[0] += line.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][0] += line.c[i][1];
@ -755,15 +756,15 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
u32 i;
// apply top-left fill-convention, left
pShader.xStart = core::ceil32_fast( line.x[0] );
pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;
pShader.xStart = fill_convention_left( line.x[0] );
pShader.xEnd = fill_convention_right( line.x[1] );
pShader.dx = pShader.xEnd - pShader.xStart;
if ( pShader.dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );
@ -787,6 +788,9 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
case BD3DCMP_EQUAL:
condition = a != pShader.z[pShader.i];
break;
default:
condition = 0;
break;
}
while ( a < pShader.z[pShader.i] )
{
@ -807,7 +811,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
a = (f32) pShader.i + subPixel;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;
@ -832,7 +836,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
line.w[0] += line.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][0] += line.c[i][1];
@ -847,7 +851,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
}
void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
sScanConvertData scan;
u32 i;
@ -859,9 +863,9 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
// calculate delta y of the edges
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 );
scan.invDeltaY[0] = reciprocal_zero2( c->Pos.y - a->Pos.y );
scan.invDeltaY[1] = reciprocal_zero2( b->Pos.y - a->Pos.y );
scan.invDeltaY[2] = reciprocal_zero2( c->Pos.y - b->Pos.y );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -885,7 +889,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
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
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] = a->Color[i];
@ -915,7 +919,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
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
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][1] = a->Color[i];
@ -929,8 +933,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
}
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -941,12 +945,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#if BURNING_MATERIAL_MAX_COLORS > 0
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;
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0] * subPixel;
@ -962,7 +967,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
line.x[scan.right] = scan.x[1];
line.w[scan.right] = scan.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][scan.left] = scan.c[i][0];
@ -984,12 +989,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0];
scan.c[i][1] += scan.slopeC[i][1];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0];
@ -1010,7 +1016,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
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
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] = a->Color[i] + scan.slopeC[i][0] * temp[0];
@ -1029,7 +1035,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
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
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][1] = b->Color[i];
@ -1043,8 +1049,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
}
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
subPixel = ( (f32) yStart ) - b->Pos.y;
@ -1056,12 +1062,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#if BURNING_MATERIAL_MAX_COLORS > 0
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;
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0] * subPixel;
@ -1077,7 +1084,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
line.x[scan.right] = scan.x[1];
line.w[scan.right] = scan.w[1];
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
line.c[i][scan.left] = scan.c[i][0];
@ -1099,12 +1106,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
#if BURNING_MATERIAL_MAX_COLORS > 0
for ( i = 0; i != ShaderParam.ColorUnits; ++i )
{
scan.c[i][0] += scan.slopeC[i][0];
scan.c[i][1] += scan.slopeC[i][1];
}
#endif
for ( i = 0; i != ShaderParam.TextureUnits; ++i )
{
scan.t[i][0] += scan.slopeT[i][0];

View File

@ -30,30 +30,32 @@ CDepthBuffer::CDepthBuffer(const core::dimension2d<u32>& size)
//! destructor
CDepthBuffer::~CDepthBuffer()
{
delete [] Buffer;
if (Buffer)
{
delete[] Buffer;
Buffer = 0;
}
}
//! clears the zbuffer
void CDepthBuffer::clear()
void CDepthBuffer::clear(f32 value)
{
ieee754 zMaxValue;
#ifdef SOFTWARE_DRIVER_2_USE_WBUFFER
f32 zMax = 0.f;
zMaxValue.f = 1.f-value;
#else
f32 zMax = 1.f;
zMaxValue.f = value;
#endif
u32 zMaxValue;
zMaxValue = IR(zMax);
memset32 ( Buffer, zMaxValue, TotalSize );
memset32 ( Buffer, zMaxValue.u, TotalSize );
}
//! sets the new size of the zbuffer
//! sets the new size of the buffer
void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
{
if (size == Size)
@ -65,13 +67,13 @@ void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
Pitch = size.Width * sizeof ( fp24 );
TotalSize = Pitch * size.Height;
Buffer = new u8[TotalSize];
Buffer = new u8[align_next(TotalSize,16)];
clear ();
}
//! returns the size of the zbuffer
//! returns the size of the buffer
const core::dimension2d<u32>& CDepthBuffer::getSize() const
{
return Size;
@ -80,11 +82,11 @@ const core::dimension2d<u32>& CDepthBuffer::getSize() const
// -----------------------------------------------------------------
//! constructor
CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size)
: Buffer(0), Size(0,0)
CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit)
: Buffer(0), Size(0,0),Bit(bit)
{
#ifdef _DEBUG
setDebugName("CDepthBuffer");
setDebugName("CStencilBuffer");
#endif
setSize(size);
@ -95,20 +97,30 @@ CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size)
//! destructor
CStencilBuffer::~CStencilBuffer()
{
delete [] Buffer;
if (Buffer)
{
delete[] Buffer;
Buffer = 0;
}
}
//! clears the zbuffer
void CStencilBuffer::clear()
//! clears the buffer
void CStencilBuffer::clear(u8 value)
{
memset32 ( Buffer, 0, TotalSize );
u32 set = value;
if (Bit == 8)
{
set |= set << 8;
set |= set << 16;
}
memset32 ( Buffer, set, TotalSize );
}
//! sets the new size of the zbuffer
//! sets the new size of the buffer
void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
{
if (size == Size)
@ -118,15 +130,15 @@ void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
delete [] Buffer;
Pitch = size.Width * sizeof ( u32 );
Pitch = size.Width * sizeof (tStencilSample);
TotalSize = Pitch * size.Height;
Buffer = new u8[TotalSize];
Buffer = new u8[align_next(TotalSize,16)];
clear ();
}
//! returns the size of the zbuffer
//! returns the size of the buffer
const core::dimension2d<u32>& CStencilBuffer::getSize() const
{
return Size;
@ -155,11 +167,11 @@ IDepthBuffer* createDepthBuffer(const core::dimension2d<u32>& size)
}
//! creates a ZBuffer
IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size)
//! creates a Stencil Buffer
IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit)
{
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CStencilBuffer(size);
return new CStencilBuffer(size,bit);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

View File

@ -23,7 +23,7 @@ namespace video
virtual ~CDepthBuffer();
//! clears the zbuffer
virtual void clear() _IRR_OVERRIDE_;
virtual void clear(f32 value=1.f) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@ -55,13 +55,13 @@ namespace video
public:
//! constructor
CStencilBuffer(const core::dimension2d<u32>& size);
CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit);
//! destructor
virtual ~CStencilBuffer();
//! clears the zbuffer
virtual void clear() _IRR_OVERRIDE_;
virtual void clear(u8 value=0) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@ -80,11 +80,11 @@ namespace video
private:
u8* Buffer;
core::dimension2d<u32> Size;
u32 TotalSize;
u32 Pitch;
u32 Bit;
};
} // end namespace video

View File

@ -7,6 +7,7 @@
#include "CColorConverter.h"
#include "CBlit.h"
#include "os.h"
#include "SoftwareDriver2_helper.h"
namespace irr
{
@ -25,7 +26,7 @@ CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* d
{
const u32 dataSize = getDataSizeFromFormat(Format, Size.Width, Size.Height);
Data = new u8[dataSize];
Data = new u8[align_next(dataSize,16)];
memcpy(Data, data, dataSize);
DeleteMemory = true;
}
@ -35,7 +36,7 @@ CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* d
//! Constructor of empty image
CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) : IImage(format, size, true)
{
Data = new u8[getDataSizeFromFormat(Format, Size.Width, Size.Height)];
Data = new u8[align_next(getDataSizeFromFormat(Format, Size.Width, Size.Height),16)];
DeleteMemory = true;
}
@ -82,10 +83,8 @@ void CImage::setPixel(u32 x, u32 y, const SColor &color, bool blend)
os::Printer::log("IImage::setPixel unknown format.", ELL_WARNING);
return;
#ifndef _DEBUG
default:
break;
#endif
}
}
@ -118,10 +117,8 @@ SColor CImage::getPixel(u32 x, u32 y) const
os::Printer::log("IImage::getPixel unknown format.", ELL_WARNING);
break;
#ifndef _DEBUG
default:
break;
#endif
}
return SColor(0);
@ -137,9 +134,9 @@ void CImage::copyTo(IImage* target, const core::position2d<s32>& pos)
return;
}
if ( !Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)
if (!Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)
&& target && pos.X == 0 && pos.Y == 0 &&
CColorConverter::canConvertFormat(Format, target->getColorFormat()) )
CColorConverter::canConvertFormat(Format, target->getColorFormat()))
{
// No fast blitting, but copyToScaling uses other color conversions and might work
irr::core::dimension2du dim(target->getDimension());
@ -170,16 +167,9 @@ void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, c
return;
}
if ( combineAlpha )
{
Blit(BLITTER_TEXTURE_COMBINE_ALPHA, target, clipRect, &pos, this, &sourceRect, color.color);
}
else
{
// color blend only necessary on not full spectrum aka. color.color != 0xFFFFFFFF
Blit(color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND: BLITTER_TEXTURE_ALPHA_COLOR_BLEND,
target, clipRect, &pos, this, &sourceRect, color.color);
}
eBlitter op = combineAlpha ? BLITTER_TEXTURE_COMBINE_ALPHA :
color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND;
Blit(op,target, clipRect, &pos, this, &sourceRect, color.color);
}
@ -390,5 +380,6 @@ inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) cons
}
} // end namespace video
} // end namespace irr

View File

@ -26,6 +26,13 @@ public:
{
}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
{
if (Driver)
Driver->setFallback_Material(material.MaterialType);
}
protected:
video::CBurningVideoDriver* Driver;
@ -47,7 +54,6 @@ public:
};
//! Transparent material renderer
class CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR : public CSoftware2MaterialRenderer
{
@ -75,40 +81,6 @@ public:
};
//! unsupported material renderer
class CBurningShader_REFERENCE : public CSoftware2MaterialRenderer
{
public:
CBurningShader_REFERENCE ( video::CBurningVideoDriver* driver )
: CSoftware2MaterialRenderer ( driver ) {}
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_
{
}
virtual void OnUnsetMaterial() _IRR_OVERRIDE_
{
}
virtual bool isTransparent() const _IRR_OVERRIDE_
{
return false;
}
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_
{
return true;
};
virtual s32 getRenderCapability() const _IRR_OVERRIDE_
{
return 1;
}
};
} // end namespace video

File diff suppressed because it is too large Load Diff

View File

@ -13,11 +13,12 @@
#include "irrString.h"
#include "SIrrCreationParameters.h"
namespace irr
{
namespace video
{
class CBurningVideoDriver : public CNullDriver
class CBurningVideoDriver : public CNullDriver, public IMaterialRendererServices
{
public:
@ -39,14 +40,15 @@ namespace video
//! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor,
f32 clearDepth, u8 clearStencil) _IRR_OVERRIDE_;
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
virtual void setScissor(int x, int y, int width, int height);
virtual bool beginScene(u16 clearFlag, SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0,
const SExposedVideoData& videoData = SExposedVideoData(), core::rect<s32>* sourceRect = 0) _IRR_OVERRIDE_;
virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil,
const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_;
virtual bool endScene() _IRR_OVERRIDE_;
@ -83,23 +85,44 @@ namespace video
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;
//! draws a vertex primitive list in 2d
virtual void draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;
//! draws an 2d image
//virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, bool useAlphaChannelOfTexture) _IRR_OVERRIDE_;
/* NullDriver calls
draw2DImage(texture, destPos,
core::rect<s32>(core::position2d<s32>(0, 0), core::dimension2di(texture->getOriginalSize())),
0,
SColor(255, 255, 255, 255),
useAlphaChannelOfTexture
*/
//! 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.
virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
//! Draws a part of the texture into the rectangle.
//! Draws a part of the texture into the rectangle.
virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,
const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;
//! Draws a 3d line.
virtual void draw3DLine(const core::vector3df& start,
const core::vector3df& end, SColor color = SColor(255,255,255,255)) _IRR_OVERRIDE_;
const core::vector3df& end, SColor color_start) _IRR_OVERRIDE_;
//! draw an 2d rectangle
virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
//virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,
// const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;
/* NullDriver calls
draw2DRectangle(pos, color, color, color, color, clip);
*/
//!Draws an 2d rectangle with a gradient.
virtual void draw2DRectangle(const core::rect<s32>& pos,
@ -131,7 +154,7 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
virtual void clearBuffers(u16 flag, SColor color = SColor(255,0,0,0), f32 depth = 1.f, u8 stencil = 0) _IRR_OVERRIDE_;
virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_;
//! Returns an image created from the last rendered frame.
virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) _IRR_OVERRIDE_;
@ -155,6 +178,9 @@ namespace video
video::SColor leftDownEdge = video::SColor(0,0,0,0),
video::SColor rightDownEdge = video::SColor(0,0,0,0)) _IRR_OVERRIDE_;
//! Enable the 2d override material
virtual void enableMaterial2D(bool enable = true) _IRR_OVERRIDE_;
//! Returns the graphics card vendor name.
virtual core::stringc getVendorInfo() _IRR_OVERRIDE_;
@ -170,8 +196,70 @@ namespace video
IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
//#define Tweak_Burning
#if defined(Tweak_Burning)
virtual void postEventFromUser(const void* sevent) _IRR_OVERRIDE_;
#endif
//! Adds a new material renderer to the VideoDriver, using pixel and/or
//! vertex shaders to render geometry.
virtual s32 addShaderMaterial(const c8* vertexShaderProgram,
const c8* pixelShaderProgram,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData) _IRR_OVERRIDE_;
//! Adds a new material renderer to the VideoDriver, based on a high level shading
//! language. Currently only HLSL in D3D9 is supported.
virtual s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,
s32 userData = 0) _IRR_OVERRIDE_;
//IMaterialRendererService
virtual void setBasicRenderStates(const SMaterial& material,
const SMaterial& lastMaterial,
bool resetAllRenderstates) _IRR_OVERRIDE_;
//pass BaseMaterialID
void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType);
//! Return an index constant for the vertex shader based on a name.
virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;
virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
//! Return an index constant for the pixel shader based on a name.
virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;
virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
//! Get pointer to the IVideoDriver interface
/** \return Pointer to the IVideoDriver interface */
virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
protected:
void saveBuffer();
//! sets a render target
void setRenderTargetImage(video::CImage* image);
@ -191,9 +279,6 @@ namespace video
video::IImage* RenderTargetSurface;
core::dimension2d<u32> RenderTargetSize;
//! selects the right triangle renderer based on the render states.
void setCurrentShader();
IBurningShader* CurrentShader;
IBurningShader* BurningShader[ETR2_COUNT];
@ -210,78 +295,90 @@ namespace video
enum E_TRANSFORMATION_STATE_BURNING_VIDEO
{
ETS_VIEW_PROJECTION = ETS_COUNT,
ETS_CURRENT,
ETS_CLIPSCALE,
ETS_VIEW_INVERSE,
ETS_WORLD_INVERSE,
ETS_PROJ_MODEL_VIEW,
ETS_MODEL_VIEW,
ETS_NORMAL, //3x3 ModelView Tansposed Inverse
ETS_COUNT_BURNING
//ETS_VIEW_INVERSE,
ETS_COUNT_BURNING = 16
};
enum E_TRANSFORMATION_FLAG
{
ETF_IDENTITY = 1,
ETF_TEXGEN_CAMERA_NORMAL = 2,
ETF_TEXGEN_CAMERA_REFLECTION = 4,
ETF_VALID = 1,
ETF_IDENTITY = 2,
ETF_TEXGEN_CAMERA_SPHERE = 4,
ETF_TEXGEN_CAMERA_REFLECTION = 8,
ETF_TEXGEN_WRAP = 16,
ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP
};
u32 TransformationFlag[ETS_COUNT_BURNING];
core::matrix4 Transformation[ETS_COUNT_BURNING];
core::matrix4 Transformation[2][ETS_COUNT_BURNING];
size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG
void getCameraPosWorldSpace ();
void getLightPosObjectSpace ();
size_t TransformationStack; // 0 .. 3D , 1 .. 2D
void setRenderStates2DMode(const video::SColor& color,video::ITexture* texture,bool useAlphaChannelOfTexture);
void setRenderStates3DMode();
//ETS_CLIPSCALE, // moved outside to stay at 16 matrices
f32 Transformation_ETS_CLIPSCALE[2][4];
void transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state);
//core::recti ViewPort;
AbsRectangle Scissor;
// Vertex Cache
static const SVSize vSize[];
SVertexCache VertexCache;
void VertexCache_reset (const void* vertices, u32 vertexCount,
int VertexCache_reset (const void* vertices, u32 vertexCount,
const void* indices, u32 indexCount,
E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType);
void VertexCache_get ( const s4DVertex ** face );
void VertexCache_getbypass ( s4DVertex ** face );
void VertexCache_get (s4DVertexPair* face[4] );
void VertexCache_map_source_format();
void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex );
s4DVertex * VertexCache_getVertex ( const u32 sourceIndex );
s4DVertexPair* VertexCache_getVertex ( const u32 sourceIndex ) const;
// culling & clipping
u32 clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane );
u32 clipToFrustumTest ( const s4DVertex * v ) const;
u32 clipToFrustum ( s4DVertex *source, s4DVertex * temp, const u32 vIn );
//size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane );
//size_t inline clipToFrustumTest ( const s4DVertex * v ) const;
public:
size_t clipToFrustum( const size_t vIn /*, const size_t clipmask_for_face*/ );
protected:
// holds transformed, clipped vertices for a triangle. triangle expands on clipping
// Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected)
SAligned4DVertex Clipper;
SAligned4DVertex Clipper_temp;
#ifdef SOFTWARE_DRIVER_2_LIGHTING
void lightVertex_eye ( s4DVertex *dest, u32 vertexargb );
#endif
void lightVertex ( s4DVertex *dest, u32 vertexargb );
//! Sets the fog mode.
virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start,
f32 end, f32 density, bool pixelFog, bool rangeFog) _IRR_OVERRIDE_;
#endif
// holds transformed, clipped vertices
SAlignedVertex CurrentOut;
SAlignedVertex Temp;
void ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair* source, const size_t vIn ) const;
void ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const;
f32 screenarea ( const s4DVertex *v0 ) const;
void select_polygon_mipmap ( s4DVertex *source, u32 vIn, u32 tex, const core::dimension2du& texSize ) const;
f32 texelarea ( const s4DVertex *v0, int tex ) const;
//const is misleading. **v is const that true, but not *v..
f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const;
s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, f32 dc_area, f32 lod_bias ) const;
void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;
void ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const;
f32 screenarea2 ( const s4DVertex **v ) const;
f32 texelarea2 ( const s4DVertex **v, int tex ) const;
void select_polygon_mipmap2 ( s4DVertex **source, u32 tex, const core::dimension2du& texSize ) const;
SBurningShaderLightSpace LightSpace;
void getCameraPosWorldSpace();
SBurningShaderEyeSpace EyeSpace;
SBurningShaderMaterial Material;
static const sVec4 NDCPlane[6];
static const sVec4 NDCPlane[6+2];
//! Built-in 2D quad for 2D rendering.
S3DVertex Quad2DVertices[4];
};
} // end namespace video

View File

@ -9,6 +9,7 @@
#include "SoftwareDriver2_helper.h"
#include "CSoftwareTexture2.h"
#include "CSoftwareDriver2.h"
#include "CBlit.h"
#include "os.h"
namespace irr
@ -16,9 +17,12 @@ namespace irr
namespace video
{
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect);
//! constructor
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags)
: ITexture(name, ETT_2D), MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN)
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver)
: ITexture(name, ETT_2D),MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN),Driver(driver)
{
#ifdef _DEBUG
setDebugName("CSoftwareTexture2");
@ -31,110 +35,148 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
DriverType = EDT_BURNINGSVIDEO;
ColorFormat = BURNINGSHADER_COLOR_FORMAT;
IsRenderTarget = (Flags & IS_RENDERTARGET) != 0;
memset32 ( MipMap, 0, sizeof ( MipMap ) );
HasMipMaps = (Flags & GEN_MIPMAP) != 0;
MipMap0_Area[0] = 1;
MipMap0_Area[1] = 1;
for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) MipMap[i] = 0;
if (!image) return;
if (image)
OriginalSize = image->getDimension();
OriginalFormat = image->getColorFormat();
#if defined(IRRLICHT_sRGB)
if ( Flags & IMAGE_IS_LINEAR ) image->set_sRGB(0);
#endif
bool isCompressed = IImage::isCompressedFormat(OriginalFormat);
if (isCompressed)
{
bool IsCompressed = false;
if (IImage::isCompressedFormat(image->getColorFormat()))
{
os::Printer::log("Texture compression not available.", ELL_ERROR);
IsCompressed = true;
}
OriginalSize = image->getDimension();
OriginalFormat = image->getColorFormat();
core::dimension2d<u32> optSize(
OriginalSize.getOptimalSize(0 != (Flags & NP2_SIZE),
false, true,
SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE)
);
if (OriginalSize == optSize)
{
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());
if (!IsCompressed)
image->copyTo(MipMap[0]);
}
else
{
char buf[256];
core::stringw showName ( name );
snprintf_irr ( buf, 256, "Burningvideo: Warning Texture %ls reformat %dx%d -> %dx%d,%d",
showName.c_str(),
OriginalSize.Width, OriginalSize.Height, optSize.Width, optSize.Height,
BURNINGSHADER_COLOR_FORMAT
);
OriginalSize = optSize;
os::Printer::log ( buf, ELL_WARNING );
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
if (!IsCompressed)
image->copyToScalingBoxFilter ( MipMap[0],0, false );
}
Size = MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch();
OrigImageDataSizeInPixels = (f32) 0.3f * MipMap[0]->getImageDataSizeInPixels();
HasMipMaps = (Flags & GEN_MIPMAP) != 0;
regenerateMipMapLevels(image->getMipMapsData());
os::Printer::log("Texture compression not available.", ELL_ERROR);
}
//visual studio code warning
u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE;
core::dimension2d<u32> optSize( OriginalSize.getOptimalSize(
(Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo
false, // requireSquare
(Flags & ALLOW_NPOT) ? 1 : maxTexSize == 0, // larger
(Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue
)
);
if (OriginalSize == optSize)
{
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());
#if defined(IRRLICHT_sRGB)
MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() );
#endif
if (!isCompressed)
image->copyTo(MipMap[0]);
}
else
{
char buf[256];
core::stringw showName ( name );
snprintf_irr ( buf, sizeof(buf), "Burningvideo: Warning Texture %ls reformat %ux%u,%d -> %ux%u,%d",
showName.c_str(),
OriginalSize.Width, OriginalSize.Height,OriginalFormat,
optSize.Width, optSize.Height,BURNINGSHADER_COLOR_FORMAT
);
os::Printer::log ( buf, ELL_WARNING );
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);
#if defined(IRRLICHT_sRGB)
MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() );
#endif
if (!isCompressed)
{
//image->copyToScalingBoxFilter ( MipMap[0],0, false );
Resample_subSampling(BLITTER_TEXTURE,MipMap[0],0,image,0);
}
// if Original Size is used for calculation ( 2D position, font) it will be wrong
//OriginalSize = optSize;
}
//select highest mipmap 0
regenerateMipMapLevels(image->getMipMapsData());
}
//! destructor
CSoftwareTexture2::~CSoftwareTexture2()
{
for ( s32 i = 0; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
{
if ( MipMap[i] )
{
MipMap[i]->drop();
MipMap[i] = 0;
}
}
}
//! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture
void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
{
if (!hasMipMaps())
return;
s32 i;
int i;
// release
for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
{
if ( MipMap[i] )
{
MipMap[i]->drop();
MipMap[i] = 0;
}
}
core::dimension2d<u32> newSize;
core::dimension2d<u32> origSize = Size;
for (i=1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
//deactivated outside mipdata until TA knows how to handle this.
if (HasMipMaps && (0 == data || 1))
{
newSize = MipMap[i-1]->getDimension();
newSize.Width = core::s32_max ( 1, newSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
newSize.Height = core::s32_max ( 1, newSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );
origSize.Width = core::s32_max(1, origSize.Width >> 1);
origSize.Height = core::s32_max(1, origSize.Height >> 1);
if (data)
for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
{
const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
//isotropic
newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);
newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);
if (upperDim == newSize)
break;
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
#if defined(IRRLICHT_sRGB)
MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB());
#endif
//MipMap[i]->fill ( 0xFFFF4040 );
//MipMap[i-1]->copyToScalingBoxFilter( MipMap[i], 0, false );
Resample_subSampling(BLITTER_TEXTURE, MipMap[i], 0, MipMap[0], 0);
}
}
else if (HasMipMaps && data)
{
core::dimension2d<u32> origSize = Size;
for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
{
const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
//isotropic
newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);
newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);
if (upperDim == newSize)
break;
origSize.Width = core::s32_max(1, origSize.Width >> 1);
origSize.Height = core::s32_max(1, origSize.Height >> 1);
if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT)
{
IImage* tmpImage = new CImage(OriginalFormat, origSize, data, true, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
if (origSize==newSize)
if (origSize == newSize)
tmpImage->copyTo(MipMap[i]);
else
tmpImage->copyToScalingBoxFilter(MipMap[i]);
@ -142,7 +184,7 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
}
else
{
if (origSize==newSize)
if (origSize == newSize)
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, data, false);
else
{
@ -152,17 +194,102 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
tmpImage->drop();
}
}
data = (u8*)data +origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;
data = (u8*)data + origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat) / 8;
}
}
//visualize mipmap
for (i=1; i < 0 && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
{
/*
static u32 color[] = {
0x30bf7f00,0x3040bf00,0x30bf00bf,0x3000bf00,
0x300080bf,0x30bf4000,0x300040bf,0x307f00bf,
0x30bf0000,0x3000bfbf,0x304000bf,0x307fbf00,
0x8000bf7f,0x80bf0040,0x80bfbf00,0x800000bf
};
*/
static u32 color[] = {
0xFFFFFFFF,0xFFFF0000,0xFF00FF00,0xFF0000FF,
0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFF0000FF,
0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFF0000FF,
0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFFFF00FF
};
if ( MipMap[i] )
{
core::rect<s32> p (core::position2di(0,0),MipMap[i]->getDimension());
SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);
Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], 0, 0, MipMap[i], &p, c.color);
}
}
//save mipmap chain
if ( 0 )
{
char buf[256];
const char* name = getName().getPath().c_str();
int filename = 0;
//int ext = -1;
i = 0;
while (name[i])
{
if (name[i] == '/' || name[i] == '\\') filename = i + 1;
//if (name[i] == '.') ext = i;
i += 1;
}
for (i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)
{
if (MipMap[i])
{
snprintf_irr(buf, sizeof(buf),"mip/%s_%02d.png", name + filename,i);
Driver->writeImageToFile(MipMap[i], buf);
}
}
}
calcDerivative();
}
void CSoftwareTexture2::calcDerivative()
{
//reset current MipMap
MipMapLOD = 0;
if (MipMap[0])
{
const core::dimension2du& dim = MipMap[0]->getDimension();
MipMap0_Area[0] = dim.Width;
MipMap0_Area[1] = dim.Height; // screensize of a triangle
Size = dim; // MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch();
}
//preCalc mipmap texel center boundaries
for ( s32 i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )
{
CSoftwareTexture2_Bound& b = TexBound[i];
if (MipMap[i])
{
const core::dimension2du& dim = MipMap[i]->getDimension();
//f32 u = 1.f / dim.Width;
//f32 v = 1.f / dim.Height;
b.w = dim.Width - 1.f;
b.h = dim.Height - 1.f;
b.cx = 0.f; //u*0.005f;
b.cy = 0.f; //v*0.005f;
}
else
{
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);
//static u32 color[] = { 0, 0xFFFF0000, 0xFF00FF00,0xFF0000FF,0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0xFF0F0F0F };
MipMap[i]->fill ( 0 );
MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false );
b.w = 0.f;
b.h = 0.f;
b.cx = 0.f;
b.cy = 0.f;
}
}
}
@ -216,6 +343,290 @@ ITexture* CSoftwareRenderTarget2::getTexture() const
}
static const float srgb_8bit_to_linear_float[1 << 8] = {
0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f,
0.001214108f, 0.001517635f, 0.001821162f, 0.0021246888f,
0.002428216f, 0.002731743f, 0.00303527f, 0.0033465358f,
0.0036765074f, 0.004024717f, 0.004391442f, 0.0047769537f,
0.005181517f, 0.005605392f, 0.0060488335f, 0.006512091f,
0.0069954107f, 0.007499032f, 0.008023193f, 0.008568126f,
0.009134059f, 0.009721218f, 0.010329823f, 0.010960095f,
0.011612245f, 0.012286489f, 0.0129830325f, 0.013702083f,
0.014443845f, 0.015208516f, 0.015996294f, 0.016807377f,
0.017641956f, 0.018500222f, 0.019382363f, 0.020288564f,
0.021219011f, 0.022173885f, 0.023153368f, 0.024157634f,
0.025186861f, 0.026241222f, 0.027320893f, 0.02842604f,
0.029556835f, 0.030713445f, 0.031896032f, 0.033104766f,
0.034339808f, 0.035601314f, 0.036889452f, 0.038204372f,
0.039546236f, 0.0409152f, 0.04231141f, 0.04373503f,
0.045186203f, 0.046665087f, 0.048171826f, 0.049706567f,
0.051269464f, 0.05286065f, 0.05448028f, 0.056128494f,
0.057805438f, 0.059511244f, 0.06124606f, 0.06301002f,
0.06480327f, 0.066625945f, 0.068478175f, 0.0703601f,
0.07227185f, 0.07421357f, 0.07618539f, 0.07818743f,
0.08021983f, 0.082282715f, 0.084376216f, 0.086500466f,
0.08865559f, 0.09084172f, 0.093058966f, 0.09530747f,
0.097587354f, 0.09989873f, 0.10224174f, 0.10461649f,
0.107023105f, 0.10946172f, 0.111932434f, 0.11443538f,
0.11697067f, 0.119538434f, 0.122138776f, 0.12477182f,
0.12743768f, 0.13013647f, 0.13286832f, 0.13563333f,
0.13843162f, 0.14126329f, 0.14412847f, 0.14702727f,
0.14995979f, 0.15292616f, 0.15592647f, 0.15896083f,
0.16202939f, 0.1651322f, 0.1682694f, 0.17144111f,
0.1746474f, 0.17788842f, 0.18116425f, 0.18447499f,
0.18782078f, 0.19120169f, 0.19461784f, 0.19806932f,
0.20155625f, 0.20507874f, 0.20863687f, 0.21223076f,
0.21586053f, 0.21952623f, 0.22322798f, 0.2269659f,
0.23074007f, 0.23455061f, 0.2383976f, 0.24228115f,
0.24620135f, 0.2501583f, 0.25415212f, 0.25818288f,
0.2622507f, 0.26635563f, 0.27049783f, 0.27467734f,
0.2788943f, 0.28314877f, 0.28744087f, 0.29177067f,
0.2961383f, 0.3005438f, 0.30498734f, 0.30946895f,
0.31398875f, 0.3185468f, 0.32314324f, 0.32777813f,
0.33245155f, 0.33716366f, 0.34191445f, 0.3467041f,
0.35153264f, 0.35640016f, 0.36130682f, 0.36625263f,
0.3712377f, 0.37626216f, 0.38132605f, 0.38642946f,
0.3915725f, 0.39675525f, 0.4019778f, 0.40724024f,
0.41254264f, 0.4178851f, 0.4232677f, 0.42869052f,
0.43415368f, 0.4396572f, 0.44520122f, 0.45078582f,
0.45641103f, 0.46207702f, 0.4677838f, 0.4735315f,
0.4793202f, 0.48514995f, 0.4910209f, 0.496933f,
0.5028865f, 0.50888133f, 0.5149177f, 0.5209956f,
0.52711517f, 0.53327644f, 0.5394795f, 0.5457245f,
0.55201143f, 0.55834043f, 0.5647115f, 0.57112485f,
0.57758045f, 0.58407843f, 0.59061885f, 0.5972018f,
0.60382736f, 0.61049557f, 0.6172066f, 0.62396044f,
0.63075715f, 0.6375969f, 0.6444797f, 0.65140563f,
0.65837485f, 0.66538733f, 0.67244315f, 0.6795425f,
0.6866853f, 0.6938718f, 0.7011019f, 0.7083758f,
0.71569353f, 0.7230551f, 0.73046076f, 0.73791045f,
0.74540424f, 0.7529422f, 0.7605245f, 0.76815116f,
0.7758222f, 0.7835378f, 0.791298f, 0.7991027f,
0.8069523f, 0.8148466f, 0.82278574f, 0.8307699f,
0.838799f, 0.8468732f, 0.8549926f, 0.8631572f,
0.8713671f, 0.8796224f, 0.8879231f, 0.8962694f,
0.9046612f, 0.91309863f, 0.92158186f, 0.9301109f,
0.9386857f, 0.9473065f, 0.9559733f, 0.9646863f,
0.9734453f, 0.9822506f, 0.9911021f, 1.0f,
};
/*
int linear_to_srgb_8bit(const float x) {
if (x <= 0.f) return 0;
if (x >= 1.f) return 255;
const float *table = SRGB_8BIT_TO_LINEAR_FLOAT;
int y = 0;
for (int i = 128; i != 0; i >>= 1) {
if (table[y + i] <= x)
y += i;
}
if (x - table[y] <= table[y + 1] - x)
return y;
else
return y + 1;
}
*/
u32 linear_to_srgb_8bit(const float v)
{
ieee754 c;
c.f = v;
const register size_t x = c.u;
const u32 *table = (u32*)srgb_8bit_to_linear_float;
register u32 y = 0;
y += table[y + 128] <= x ? 128 : 0;
y += table[y + 64] <= x ? 64 : 0;
y += table[y + 32] <= x ? 32 : 0;
y += table[y + 16] <= x ? 16 : 0;
y += table[y + 8] <= x ? 8 : 0;
y += table[y + 4] <= x ? 4 : 0;
y += table[y + 2] <= x ? 2 : 0;
y += table[y + 1] <= x ? 1 : 0;
return y;
}
// 2D Region half open [x0;x1[
struct absrect2
{
s32 x0;
s32 y0;
s32 x1;
s32 y1;
};
static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2& b)
{
if (a == 0)
{
o.x0 = b.x0;
o.y0 = b.y0;
o.x1 = b.x1;
o.y1 = b.y1;
}
else
{
o.x0 = core::s32_max(a->UpperLeftCorner.X, b.x0);
o.x1 = core::s32_min(a->LowerRightCorner.X, b.x1);
o.y0 = core::s32_max(a->UpperLeftCorner.Y, b.y0);
o.y1 = core::s32_min(a->LowerRightCorner.Y, b.y1);
}
int clipTest = 0;
clipTest |= o.x0 >= o.x1 ? 1 : 0;
clipTest |= o.y0 >= o.y1 ? 2 : 0;
return clipTest;
}
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)
// todo: texture jumps (mip selection problem)
void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect,
const video::IImage* src, const core::rect<s32>* srcRect)
{
const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height };
absrect2 dc;
if (clipTest(dc, dstRect, dst_clip)) return;
const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat();
u8* dstData = (u8*)dst->getData();
const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height };
absrect2 sc;
if (clipTest(sc, srcRect, src_clip)) return;
const video::ECOLOR_FORMAT srcFormat = src->getColorFormat();
const u8* srcData = (u8*)src->getData();
#if defined(IRRLICHT_sRGB)
const int dst_sRGB = dst->get_sRGB();
const int src_sRGB = src->get_sRGB();
#else
const int dst_sRGB = 1;
const int src_sRGB = 1;
#endif
float scale[2];
scale[0] = (float)(sc.x1 - sc.x0) / (float)(dc.x1 - dc.x0);
scale[1] = (float)(sc.y1 - sc.y0) / (float)(dc.y1 - dc.y0);
const float rs = 1.f / (scale[0] * scale[1]);
float sum[4];
u32 sbgra = 0;
float f[4];
int fi[4];
f[3] = (float)sc.y0;
for (int dy = dc.y0; dy < dc.y1; ++dy)
{
f[1] = f[3];
f[3] = sc.y0 + (dy + 1 - dc.y0)*scale[1];
if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough
f[2] = (float)sc.x0;
for (int dx = dc.x0; dx < dc.x1; ++dx)
{
f[0] = f[2];
f[2] = sc.x0 + (dx + 1 - dc.x0)*scale[0];
if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;
//accumulate linear color
sum[0] = 0.f;
sum[1] = 0.f;
sum[2] = 0.f;
sum[3] = 0.f;
//sample border
fi[0] = (int)(f[0]);
fi[1] = (int)(f[1]);
fi[2] = (int)(f[2]);
fi[3] = (int)(f[3]);
float w[2];
for (int fy = fi[1]; fy <= fi[3]; ++fy)
{
w[1] = 1.f;
if (fy == fi[1]) w[1] -= f[1] - fy;
if (fy == fi[3]) w[1] -= fy + 1 - f[3];
for (int fx = fi[0]; fx <= fi[2]; ++fx)
{
w[0] = 1.f;
if (fx == fi[0]) w[0] -= f[0] - fx;
if (fx == fi[2]) w[0] -= fx + 1 - f[2];
const float ws = w[1] * w[0] * rs;
switch (srcFormat)
{
case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;
case video::ECF_R5G6B5: sbgra = video::R5G6B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;
case video::ECF_A8R8G8B8: sbgra = *(u32*)(srcData + (fy*src_clip.x1) * 4 + (fx * 4)); break;
case video::ECF_R8G8B8:
{
const u8* p = srcData + (fy*src_clip.x1) * 3 + (fx * 3);
sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2];
} break;
default: break;
}
if (src_sRGB)
{
sum[0] += srgb_8bit_to_linear_float[(sbgra) & 0xFF] * ws;
sum[1] += srgb_8bit_to_linear_float[(sbgra >> 8) & 0xFF] * ws;
sum[2] += srgb_8bit_to_linear_float[(sbgra >> 16) & 0xFF] * ws;
sum[3] += ((sbgra >> 24) & 0xFF) * ws;
}
else
{
sum[0] += ((sbgra) & 0xFF) * ws;
sum[1] += ((sbgra >> 8) & 0xFF) * ws;
sum[2] += ((sbgra >> 16) & 0xFF) * ws;
sum[3] += ((sbgra >> 24) & 0xFF) * ws;
}
}
}
switch (op)
{
case BLITTER_TEXTURE_ALPHA_BLEND:
case BLITTER_TEXTURE_ALPHA_COLOR_BLEND:
break;
default:
break;
}
if (dst_sRGB)
{
sbgra = linear_to_srgb_8bit(sum[0]) |
linear_to_srgb_8bit(sum[1]) << 8 |
linear_to_srgb_8bit(sum[2]) << 16 |
(u32)(sum[3]) << 24;
}
else
{
sbgra = (u32)(sum[0]) |
(u32)(sum[1]) << 8 |
(u32)(sum[2]) << 16 |
(u32)(sum[3]) << 24;
}
switch (dstFormat)
{
case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy*dst_clip.x1) * 4 + (dx * 4)) = sbgra; break;
case video::ECF_R8G8B8:
{
u8* p = dstData + (dy*dst_clip.x1) * 3 + (dx * 3);
p[2] = (sbgra) & 0xFF;
p[1] = (sbgra >> 8) & 0xFF;
p[0] = (sbgra >> 16) & 0xFF;
} break;
case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); break;
case video::ECF_R5G6B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break;
default:
break;
}
}
}
}
} // end namespace video
} // end namespace irr

View File

@ -21,6 +21,14 @@ class CBurningVideoDriver;
/*!
interface for a Video Driver dependent Texture.
*/
struct CSoftwareTexture2_Bound
{
f32 w; // width - 0.5f;
f32 h; // height- 0.5f;
f32 cx; // texelcenter x 1.f/width*0.5f
f32 cy; // texelcenter y 1.f/height*0.5f
};
class CSoftwareTexture2 : public ITexture
{
public:
@ -28,21 +36,33 @@ public:
//! constructor
enum eTex2Flags
{
GEN_MIPMAP = 1,
IS_RENDERTARGET = 2,
NP2_SIZE = 4,
GEN_MIPMAP = 1,
IS_RENDERTARGET = 2,
ALLOW_NPOT = 4, //allow non power of two
IMAGE_IS_LINEAR = 8,
TEXTURE_IS_LINEAR = 16,
};
CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags);
CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags /*eTex2Flags*/, CBurningVideoDriver* driver);
//! destructor
virtual ~CSoftwareTexture2();
u32 getMipmapLevel(s32 newLevel) const
{
if ( newLevel < 0 ) newLevel = 0;
else if ( newLevel >= SOFTWARE_DRIVER_2_MIPMAPPING_MAX ) newLevel = SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1;
while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1;
return newLevel;
}
//! lock function
virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_
{
if (Flags & GEN_MIPMAP)
{
MipMapLOD = mipmapLevel;
//called from outside. must test
MipMapLOD = getMipmapLevel(mipmapLevel);
Size = MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch();
}
@ -55,14 +75,19 @@ public:
{
}
//! Returns the size of the largest mipmap.
//! compare the area drawn with the area of the texture
f32 getLODFactor( const f32 texArea ) const
{
return OrigImageDataSizeInPixels * texArea;
return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;
//return MipMap[0]->getImageDataSizeInPixels () * texArea;
}
//! returns unoptimized surface
const u32* getMipMap0_Area() const
{
return MipMap0_Area;
}
//! returns unoptimized surface (misleading name. burning can scale down originalimage)
virtual CImage* getImage() const
{
return MipMap[0];
@ -74,16 +99,26 @@ public:
return MipMap[MipMapLOD];
}
//precalculated dimx-1/dimx*0.5f
const CSoftwareTexture2_Bound& getTexBound() const
{
return TexBound[MipMapLOD];
}
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
private:
f32 OrigImageDataSizeInPixels;
void calcDerivative();
CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
u32 MipMapLOD;
u32 Flags;
//! controls MipmapSelection. relation between drawn area and image size
u32 MipMapLOD; // 0 .. original Texture pot -SOFTWARE_DRIVER_2_MIPMAPPING_MAX
u32 Flags; //eTex2Flags
ECOLOR_FORMAT OriginalFormat;
CBurningVideoDriver* Driver;
CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
u32 MipMap0_Area[2];
};
/*!
@ -103,9 +138,9 @@ protected:
CBurningVideoDriver* Driver;
};
} // end namespace video
} // end namespace irr
#endif
#endif // __C_SOFTWARE_2_TEXTURE_H_INCLUDED__

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -83,13 +83,11 @@ public:
CTRGouraud2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
//virtual bool canWireFrame () { return true; }
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
protected:
virtual void scanline_bilinear ();
};
@ -136,8 +134,8 @@ void CTRGouraud2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -145,7 +143,7 @@ void CTRGouraud2::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -182,6 +180,7 @@ void CTRGouraud2::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -193,34 +192,31 @@ void CTRGouraud2::scanline_bilinear ()
#ifdef IPOL_C0
tFixPoint r0, g0, b0;
#ifdef INVERSE_W
f32 inversew;
#endif
f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
//if test active only first pixel
if ( (0 == EdgeTestPass) & i ) break;
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if ( line.w[0] >= z[i] )
if (line.w[0] >= z[i] )
#endif
{
#ifdef IPOL_C0
#ifdef INVERSE_W
inversew = core::reciprocal ( line.w[0] );
getSample_color ( r0, g0, b0, line.c[0][0] * inversew );
#else
getSample_color ( r0, g0, b0, line.c[0][0] );
inversew = fix_inverse32_color(line.w[0]);
#endif
dst[i] = fix_to_color ( r0, g0, b0 );
vec4_to_fix( r0, g0, b0, line.c[0][0],inversew );
dst[i] = fix_to_sample( r0, g0, b0 );
#else
dst[i] = COLOR_BRIGHT_WHITE;
dst[i] = PrimitiveColor;
#endif
#ifdef WRITE_Z
@ -251,7 +247,7 @@ void CTRGouraud2::scanline_bilinear ()
}
void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
@ -262,10 +258,10 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_edge( ca );
scan.invDeltaY[1] = reciprocal_edge( ba );
scan.invDeltaY[2] = reciprocal_edge( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -351,8 +347,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -421,6 +417,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
// render a scanline
scanline_bilinear ();
if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -454,7 +451,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
@ -510,8 +507,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -581,6 +578,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
// render a scanline
scanline_bilinear ();
if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -630,6 +628,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver)
{
// ETR_GOURAUD . no texture
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraud2(driver);
#else

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -84,15 +84,12 @@ public:
CTRGouraudAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c ) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
@ -142,8 +139,8 @@ void CTRGouraudAlpha2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -151,7 +148,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -188,6 +185,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -198,9 +196,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
#ifdef IPOL_C0
#ifdef INVERSE_W
f32 inversew;
#endif
f32 inversew = FIX_POINT_F32_MUL;
tFixPoint a0;
tFixPoint r0, g0, b0;
@ -220,22 +216,20 @@ void CTRGouraudAlpha2::scanline_bilinear ()
{
#ifdef IPOL_C0
#ifdef INVERSE_W
inversew = core::reciprocal ( line.w[0] );
getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );
#else
getSample_color ( a0, r0, g0, b0, line.c[0][0] );
inversew = reciprocal_zero_no ( line.w[0] );
#endif
vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );
color_to_fix ( r1, g1, b1, dst[i] );
fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix_to_color ( r2, g2, b2 );
dst[i] = fix4_to_sample( a0,r2, g2, b2 );
#else
dst[i] = COLOR_BRIGHT_WHITE;
dst[i] = PrimitiveColor;
#endif
#ifdef WRITE_Z
z[i] = line.z[0];
@ -265,7 +259,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
}
void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -276,9 +270,9 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -365,8 +359,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -524,8 +518,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -642,6 +636,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver)
{
// ETR_GOURAUD_ALPHA unused
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlpha2(driver);
#else

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -84,14 +84,11 @@ public:
CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
@ -138,8 +135,8 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -147,7 +144,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -184,6 +181,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -192,11 +190,10 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;
#ifdef IPOL_C0
#ifdef INVERSE_W
f32 inversew;
#endif
tFixPoint a0;
tFixPoint r0, g0, b0;
@ -224,22 +221,21 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
#ifdef IPOL_C0
#ifdef IPOL_W
inversew = core::reciprocal ( line.w[0] );
getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );
#else
getSample_color ( a0, r0, g0, b0, line.c[0][0] );
inversew = fix_inverse32_color(line.w[0]);
#endif
vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );
color_to_fix ( r1, g1, b1, dst[i] );
fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix_to_color ( r2, g2, b2 );
dst[i] = fix_to_sample( r2, g2, b2 );
#else
dst[i] = COLOR_BRIGHT_WHITE;
dst[i] = PrimitiveColor;
#endif
@ -264,7 +260,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
}
void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -275,9 +271,9 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -363,8 +359,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -522,8 +518,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -640,6 +636,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
{
//ETR_GOURAUD_ALPHA_NOZ - draw2DRectangle Gradient
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlphaNoZ2(driver);
#else

View File

@ -0,0 +1,641 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
//#define CMP_W
//#define WRITE_W
#define IPOL_C0
//#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTRGouraudNoZ2 : public IBurningShader
{
public:
//! constructor
CTRGouraudNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual bool canWireFrame () { return true; }
protected:
virtual void scanline_bilinear ();
};
//! constructor
CTRGouraudNoZ2::CTRGouraudNoZ2(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTRGouraudNoZ2");
#endif
}
/*!
*/
void CTRGouraudNoZ2::scanline_bilinear ()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
//fp24 *z;
#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;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = reciprocal_zero2( 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 = (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 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 * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
//z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef IPOL_C0
tFixPoint r0, g0, b0;
f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
if ( (0 == EdgeTestPass) & i ) break;
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
#ifdef CMP_W
if (line.w[0] >= z[i] )
#endif
{
#ifdef IPOL_C0
#ifdef INVERSE_W
inversew = fix_inverse32_color(line.w[0]);
#endif
vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);
dst[i] = fix_to_sample(r0, g0, b0);
#else
dst[i] = PrimitiveColor;
#endif
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c);
if ( b->Pos.y > c->Pos.y ) swapVertexPointer(&b, &c);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_edge( ca );
scan.invDeltaY[1] = reciprocal_edge( ba );
scan.invDeltaY[2] = reciprocal_edge( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
scanline_bilinear ();
if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver)
{
//ETR_GOURAUD_NOZ - no texture no depth test no depth write
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudNoZ2(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@ -21,6 +21,7 @@
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_C1
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_T2
@ -36,6 +37,7 @@
#define WRITE_W
#define IPOL_C0
#define IPOL_C1
#define IPOL_T0
#define IPOL_T1
#define IPOL_L0
@ -49,10 +51,18 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1
#endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
#undef IPOL_L0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@ -87,14 +97,11 @@ public:
CTRNormalMap(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
void fragmentShader();
};
@ -108,10 +115,13 @@ CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver)
}
void CTRNormalMap::OnSetMaterial(const SBurningShaderMaterial& material)
{
}
/*!
*/
void CTRNormalMap::scanline_bilinear ()
void CTRNormalMap::fragmentShader()
{
tVideoSample *dst;
@ -135,18 +145,18 @@ void CTRNormalMap::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];
sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -154,7 +164,7 @@ void CTRNormalMap::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -165,6 +175,9 @@ void CTRNormalMap::scanline_bilinear ()
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
@ -189,6 +202,9 @@ void CTRNormalMap::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
@ -203,6 +219,7 @@ void CTRNormalMap::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -210,7 +227,7 @@ void CTRNormalMap::scanline_bilinear ()
#endif
f32 inversew;
f32 inversew = FIX_POINT_F32_MUL;
tFixPoint tx0, tx1;
tFixPoint ty0, ty1;
@ -219,16 +236,21 @@ void CTRNormalMap::scanline_bilinear ()
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#ifdef IPOL_L0
tFixPoint lx, ly, lz;
tFixPoint ndotl;
sVec3 light;
#endif
tFixPoint ndotl = FIX_POINT_ONE;
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
tFixPoint a3,r3, g3, b3;
#endif
#ifdef IPOL_C1
tFixPoint aFog = FIX_POINT_ONE;
#endif
for ( s32 i = 0; i <= dx; i++ )
{
#ifdef CMP_Z
@ -240,6 +262,34 @@ void CTRNormalMap::scanline_bilinear ()
{
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
#ifdef IPOL_C0
//vertex alpha blend ( and omit depthwrite ,hacky..)
a3 = tofix(line.c[0][0].x, inversew);
if (a3 + 2 >= FIX_POINT_ONE)
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#endif
#ifdef IPOL_C1
//complete inside fog
if (TL_Flag & TL_FOG)
{
aFog = tofix(line.c[1][0].a, inversew);
if (aFog <= 0)
{
dst[i] = fog_color_sample;
continue;
}
}
#endif
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
@ -247,26 +297,7 @@ void CTRNormalMap::scanline_bilinear ()
ty1 = tofix ( line.t[1][0].y,inversew);
#ifdef IPOL_C0
r3 = tofix ( line.c[0][0].y ,inversew );
g3 = tofix ( line.c[0][0].z ,inversew );
b3 = tofix ( line.c[0][0].w ,inversew );
#endif
#else
inversew = FIX_POINT_F32_MUL;
tx0 = tofix(line.t[0][0].x, inversew);
ty0 = tofix(line.t[0][0].y, inversew);
tx1 = tofix(line.t[1][0].x, inversew);
ty1 = tofix(line.t[1][0].y, inversew);
#ifdef IPOL_C0
r3 = tofix ( line.c[0][0].y );
g3 = tofix ( line.c[0][0].z );
b3 = tofix ( line.c[0][0].w );
#endif
#endif
// diffuse map
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
// normal map
@ -276,24 +307,23 @@ void CTRNormalMap::scanline_bilinear ()
g1 = ( g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
b1 = ( b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);
/*
sVec3 l = line.l[0][0] * inversew;
l.setLength( 2.f );
lx = tofix ( l.x - 0.5f );
ly = tofix ( l.y - 0.5f );
lz = tofix ( l.z - 0.5f );
*/
#ifdef IPOL_L0
lx = tofix ( line.l[0][0].x, inversew );
ly = tofix ( line.l[0][0].y, inversew );
lz = tofix ( line.l[0][0].z, inversew );
// DOT 3 Normal Map light in tangent space
ndotl = saturateFix ( FIX_POINT_HALF_COLOR + (( imulFix ( r1, lx ) + imulFix ( g1, ly ) + imulFix ( b1, lz ) ) << (COLOR_MAX_LOG2-1)) );
ndotl = saturateFix ( FIX_POINT_HALF_COLOR + ((imulFix_simple(r1,lx) + imulFix_simple(g1,ly) + imulFix_simple(b1,lz) ) << (COLOR_MAX_LOG2-1)) );
#endif
#ifdef IPOL_C0
//getSample_color(a3,r3,g3,b3, line.c[0][0],inversew);
//a3 = tofix(line.c[0][0].x, inversew);
r3 = tofix(line.c[0][0].y, inversew);
g3 = tofix(line.c[0][0].z, inversew);
b3 = tofix(line.c[0][0].w, inversew);
// N . L
r2 = imulFix ( imulFix_tex1 ( r0, ndotl ), r3 );
g2 = imulFix ( imulFix_tex1 ( g0, ndotl ), g3 );
@ -307,27 +337,34 @@ void CTRNormalMap::scanline_bilinear ()
g2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( g0 + a4, g3 ) ) );
b2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( b0 + a4, b3 ) ) );
*/
//vertex alpha blend ( and omit depthwrite ,hacky..)
if (a3 + 2 < FIX_POINT_ONE)
{
color_to_fix(r1, g1, b1, dst[i]);
r2 = r1 + imulFix(a3, r2 - r1);
g2 = g1 + imulFix(a3, g2 - g1);
b2 = b1 + imulFix(a3, b2 - b1);
}
#ifdef IPOL_C1
//mix with distance
if (aFog < FIX_POINT_ONE)
{
r2 = fog_color[1] + imulFix(aFog, r2 - fog_color[1]);
g2 = fog_color[2] + imulFix(aFog, g2 - fog_color[2]);
b2 = fog_color[3] + imulFix(aFog, b2 - fog_color[3]);
}
#endif
dst[i] = fix_to_sample(r2, g2, b2);
/*
r2 = clampfix_maxcolor ( imulFix_tex1 ( r2, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex1 ( g2, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex1 ( b2, b1 ) );
*/
#else
r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );
r2 = imulFix_tex4 ( r0, r1 );
g2 = imulFix_tex4 ( g0, g1 );
b2 = imulFix_tex4 ( b0, b1 );
dst[i] = fix_to_sample(r2, g2, b2);
#endif
dst[i] = fix_to_color ( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
@ -339,6 +376,9 @@ void CTRNormalMap::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
@ -355,7 +395,7 @@ void CTRNormalMap::scanline_bilinear ()
}
void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -366,9 +406,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -403,6 +443,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@ -433,7 +478,6 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
// rasterize upper sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
@ -455,6 +499,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@ -476,8 +525,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -501,6 +550,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -544,6 +598,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -565,7 +624,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// render a scanline
scanline_bilinear ();
fragmentShader ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -585,6 +644,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -609,11 +673,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
//if( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
@ -628,6 +690,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@ -638,7 +703,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0];
#endif
#ifdef IPOL_L0
scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0];
scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];
#endif
}
@ -662,6 +727,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@ -683,8 +753,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -709,6 +779,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -752,6 +827,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -773,7 +853,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
#endif
// render a scanline
scanline_bilinear ();
fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -793,6 +873,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];

View File

@ -47,7 +47,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -84,19 +84,10 @@ public:
CTRStencilShadow(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
// fragment shader
typedef void (CTRStencilShadow::*tFragmentShader) ();
void fragment_zfail_decr ();
void fragment_zfail_incr ();
tFragmentShader fragmentShader;
sScanConvertData scan;
sScanLineData line;
void fragmentShader();
};
@ -112,36 +103,14 @@ CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver)
/*!
*/
void CTRStencilShadow::setParam ( u32 index, f32 value)
void CTRStencilShadow::fragmentShader()
{
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 ()
{
if (!Stencil)
return;
//tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#endif
#ifdef USE_SBUFFER
u32 *stencil;
tStencilSample *stencil;
#endif
s32 xStart;
@ -158,27 +127,19 @@ void CTRStencilShadow::fragment_zfail_decr ()
#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_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -186,21 +147,6 @@ void CTRStencilShadow::fragment_zfail_decr ()
#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
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
@ -210,23 +156,8 @@ void CTRStencilShadow::fragment_zfail_decr ()
#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
SOFTWARE_DRIVER_2_CLIPCHECK;
//dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -234,30 +165,43 @@ void CTRStencilShadow::fragment_zfail_decr ()
#endif
#ifdef USE_SBUFFER
stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
stencil = (tStencilSample*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef INVERSE_W
f32 inversew;
f32 inversew = FIX_POINT_F32_MUL;
#endif
#ifdef IPOL_C0
tFixPoint r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; i++ )
s32 i;
for (i = 0; i <= dx; i++)
{
#ifdef CMP_Z
if ( line.z[0] < z[i] )
if (line.z[0] < z[i])
#endif
#ifdef CMP_W
if ( line.w[0] < z[i] )
if (line.w[0] > z[i])
#endif
{
// zpass
switch (stencilOp[2])
{
case StencilOp_INCR: stencil[i] += 1; break;
case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;
default:
case StencilOp_KEEP: break;
}
}
else
{
// zfail
stencil[i] -= 1;
switch (stencilOp[1])
{
case StencilOp_INCR: stencil[i] += 1; break;
case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;
default:
case StencilOp_KEEP: break;
}
}
#ifdef IPOL_Z
@ -265,181 +209,13 @@ void CTRStencilShadow::fragment_zfail_decr ()
#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()
{
if (!Stencil)
return;
//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_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
dx = xEnd - xStart;
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
#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->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
#ifdef USE_SBUFFER
stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#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
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::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -450,9 +226,9 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -516,7 +292,6 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// rasterize upper sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
@ -559,8 +334,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -648,7 +423,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// render a scanline
(this->*fragmentShader) ();
fragmentShader ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -766,8 +541,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -856,7 +631,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
#endif
// render a scanline
(this->*fragmentShader) ();
fragmentShader ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -915,6 +690,7 @@ namespace video
//! creates a triangle renderer
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver)
{
//ETR_STENCIL_SHADOW
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRStencilShadow(driver);
#else

File diff suppressed because it is too large Load Diff

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -84,13 +84,11 @@ public:
CTRTextureDetailMap2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual bool canWireFrame () { return true; }
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
protected:
virtual void scanline_bilinear ();
};
@ -138,8 +136,8 @@ void CTRTextureDetailMap2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -147,7 +145,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -184,6 +182,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -203,6 +202,8 @@ void CTRTextureDetailMap2::scanline_bilinear ()
for ( s32 i = 0; i <= dx; ++i )
{
if ( (0 == EdgeTestPass) & i ) break;
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
@ -222,16 +223,13 @@ void CTRTextureDetailMap2::scanline_bilinear ()
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 );
// bias half color
r1 += -FIX_POINT_HALF_COLOR;
g1 += -FIX_POINT_HALF_COLOR;
b1 += -FIX_POINT_HALF_COLOR;
// add signed
r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) );
g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) );
b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) );
r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 - FIX_POINT_HALF_COLOR ) );
g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 - FIX_POINT_HALF_COLOR ) );
b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 - FIX_POINT_HALF_COLOR ) );
dst[i] = fix_to_color ( r2, g2, b2 );
dst[i] = fix_to_sample( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
@ -261,7 +259,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
}
void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -272,9 +270,9 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_edge( ca );
scan.invDeltaY[1] = reciprocal_edge( ba );
scan.invDeltaY[2] = reciprocal_edge( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -360,8 +358,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -519,8 +517,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL

View File

@ -21,8 +21,11 @@
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_C1
#undef IPOL_C2
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_L0
// define render case
#define SUBTEXEL
@ -34,8 +37,11 @@
#define WRITE_W
#define IPOL_C0
#define IPOL_C1
//#define IPOL_C2
#define IPOL_T0
//#define IPOL_T1
//#define IPOL_L0
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
@ -46,10 +52,23 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1
#endif
#if BURNING_MATERIAL_MAX_COLORS < 3
#undef IPOL_C2
#endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
#undef IPOL_L0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@ -83,14 +102,12 @@ public:
CTRTextureGouraud2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual bool canWireFrame () { return true; }
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
void fragmentShader ();
};
//! constructor
@ -106,7 +123,7 @@ CTRTextureGouraud2::CTRTextureGouraud2(CBurningVideoDriver* driver)
/*!
*/
void CTRTextureGouraud2::scanline_bilinear ()
void CTRTextureGouraud2::fragmentShader ()
{
tVideoSample *dst;
@ -130,15 +147,19 @@ void CTRTextureGouraud2::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#ifdef IPOL_L0
sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -146,7 +167,7 @@ void CTRTextureGouraud2::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -155,7 +176,13 @@ void CTRTextureGouraud2::scanline_bilinear ()
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif
#ifdef IPOL_C2
slopeC[2] = (line.c[2][1] - line.c[2][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@ -163,6 +190,10 @@ void CTRTextureGouraud2::scanline_bilinear ()
#ifdef IPOL_T1
slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
#endif
#ifdef IPOL_L0
slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
@ -173,7 +204,13 @@ void CTRTextureGouraud2::scanline_bilinear ()
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_C2
line.c[2][0] += slopeC[2] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
@ -181,8 +218,12 @@ void CTRTextureGouraud2::scanline_bilinear ()
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0] * subPixel;
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -195,18 +236,29 @@ void CTRTextureGouraud2::scanline_bilinear ()
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
#ifdef IPOL_C0
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
#ifdef IPOL_C1
tFixPoint aFog = FIX_POINT_ONE;
#endif
#ifdef IPOL_C2
tFixPoint r3, g3, b3;
#endif
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = ( line.y & 3 ) << 2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
//if test active only first pixel
if ( (0 == EdgeTestPass) & i ) break;
#ifdef CMP_Z
if ( line.z[0] < z[i] )
#endif
@ -221,41 +273,70 @@ void CTRTextureGouraud2::scanline_bilinear ()
z[i] = line.w[0];
#endif
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
#ifdef IPOL_C1
//complete inside fog
if (TL_Flag & TL_FOG)
{
aFog = tofix(line.c[1][0].a, inversew);
if (aFog <= 0)
{
dst[i] = fog_color_sample;
continue;
}
}
#endif
tx0 = tofix ( line.t[0][0].x, inversew);
ty0 = tofix ( line.t[0][0].y, inversew);
#ifdef IPOL_C0
r1 = tofix ( line.c[0][0].y ,inversew );
g1 = tofix ( line.c[0][0].z ,inversew );
b1 = tofix ( line.c[0][0].w ,inversew );
getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);
vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r0, r1);
g0 = imulFix_simple(g0, g1);
b0 = imulFix_simple(b0, b1);
#ifdef IPOL_C1
//specular highlight
if (TL_Flag & TL_SPECULAR)
{
vec4_to_fix(r1, g1, b1, line.c[1][0], inversew*COLOR_MAX);
r0 = clampfix_maxcolor(r1 + r0);
g0 = clampfix_maxcolor(g1 + g0);
b0 = clampfix_maxcolor(b1 + b0);
}
//mix with distance
if (aFog < FIX_POINT_ONE)
{
r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);
g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);
b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);
}
dst[i] = fix_to_sample(r0, g0, b0);
#else
dst[i] = fix_to_sample(
imulFix_simple(r0, r1),
imulFix_simple(g0, g1),
imulFix_simple(b0, b1)
);
#endif
#else
tx0 = tofix(line.t[0][0].x, inversew);
ty0 = tofix(line.t[0][0].y, inversew);
#ifdef IPOL_C0
getTexel_plain2 ( r1, g1, b1, line.c[0][0] );
#endif
#endif
#ifdef IPOL_C0
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
dst[i] = fix_to_color ( imulFix ( r0, r1 ),
imulFix ( g0, g1 ),
imulFix ( b0, b1 )
);
#else
#ifdef BURNINGVIDEO_RENDERER_FAST
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
dst[i] = getTexel_plain ( &IT[0], d + tx0, d + ty0 );
#else
getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );
dst[i] = fix_to_color ( r0, g0, b0 );
dst[i] = fix_to_sample( r0, g0, b0 );
#endif
#endif
@ -269,19 +350,28 @@ void CTRTextureGouraud2::scanline_bilinear ()
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_C2
line.c[2][0] += slopeC[2];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
#ifdef IPOL_L0
line.l[0][0] += slopeL[0];
#endif
}
}
void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -292,9 +382,9 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -329,6 +419,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_C2
scan.slopeC[2][0] = (c->Color[2] - a->Color[2]) * scan.invDeltaY[0];
scan.c[2][0] = a->Color[2];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@ -339,6 +439,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][0] = a->Tex[1];
#endif
#ifdef IPOL_L0
scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0];
scan.l[0][0] = a->LightTangent[0];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
@ -348,7 +453,7 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
if ( F32_GREATER_0(scan.invDeltaY[1]) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@ -369,6 +474,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_C2
scan.slopeC[2][1] = (b->Color[2] - a->Color[2]) * scan.invDeltaY[1];
scan.c[2][1] = a->Color[2];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@ -379,9 +494,14 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] = a->Tex[1];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1];
scan.l[0][1] = a->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -405,6 +525,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_C2
scan.c[2][0] += scan.slopeC[2][0] * subPixel;
scan.c[2][1] += scan.slopeC[2][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -415,6 +545,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
@ -438,6 +573,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_C2
line.c[2][scan.left] = scan.c[2][0];
line.c[2][scan.right] = scan.c[2][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -448,8 +593,15 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
scanline_bilinear ();
fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -469,6 +621,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_C2
scan.c[2][0] += scan.slopeC[2][0];
scan.c[2][1] += scan.slopeC[2][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -479,14 +641,19 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
if (F32_GREATER_0(scan.invDeltaY[2]) )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
if(F32_GREATER_0(scan.invDeltaY[1]) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
@ -500,6 +667,12 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_C2
scan.c[2][0] = a->Color[2] + scan.slopeC[2][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@ -507,6 +680,9 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
#ifdef IPOL_L0
scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
@ -528,6 +704,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_C2
scan.slopeC[2][1] = (c->Color[2] - b->Color[2]) * scan.invDeltaY[2];
scan.c[2][1] = b->Color[2];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@ -538,9 +724,14 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] = b->Tex[1];
#endif
#ifdef IPOL_L0
scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2];
scan.l[0][1] = b->LightTangent[0];
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -565,6 +756,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[2][0] += scan.slopeC[2][0] * subPixel;
scan.c[2][1] += scan.slopeC[2][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -575,6 +776,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0] * subPixel;
scan.l[0][1] += scan.slopeL[0][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
@ -598,6 +804,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_C2
line.c[2][scan.left] = scan.c[2][0];
line.c[2][scan.right] = scan.c[2][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -608,8 +824,15 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
line.t[1][scan.right] = scan.t[1][1];
#endif
#ifdef IPOL_L0
line.l[0][scan.left] = scan.l[0][0];
line.l[0][scan.right] = scan.l[0][1];
#endif
// render a scanline
scanline_bilinear ( );
fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -629,6 +852,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_C2
scan.c[2][0] += scan.slopeC[2][0];
scan.c[2][1] += scan.slopeC[2][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -639,6 +872,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
scan.t[1][1] += scan.slopeT[1][1];
#endif
#ifdef IPOL_L0
scan.l[0][0] += scan.slopeL[0][0];
scan.l[0][1] += scan.slopeL[0][1];
#endif
}
}
@ -657,6 +895,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver)
{
// ETR_TEXTURE_GOURAUD
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraud2(driver);
#else

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -84,13 +84,11 @@ public:
CTRTextureGouraudAdd2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanLineData line;
};
//! constructor
@ -137,8 +135,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -146,7 +144,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -183,6 +181,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -193,9 +192,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
f32 inversew = FIX_POINT_F32_MUL;
#ifdef BURNINGVIDEO_RENDERER_FAST
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = ( line.y & 3 ) << 2;
#else
tFixPoint tx0;
tFixPoint ty0;
@ -216,32 +214,28 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
{
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
dst[i] = PixelAdd32 (
dst[i],
getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
d + tofix ( line.t[0][0].y,inversew) )
);
dst[i] = PixelAdd32 (
dst[i],
getTexel_plain ( &IT[0], d + tofix ( line.t[0][0].x,inversew),
d + tofix ( line.t[0][0].y,inversew) )
);
#else
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
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 );
color_to_fix ( r1, g1, b1, dst[i] );
dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + r0 ),
dst[i] = fix_to_sample( clampfix_maxcolor ( r1 + r0 ),
clampfix_maxcolor ( g1 + g0 ),
clampfix_maxcolor ( b1 + b0 )
);
@ -275,10 +269,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
}
void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
sScanConvertData scan;
// sort on height, y
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);
@ -288,9 +280,9 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
// find if the major edge is left or right aligned
f32 temp[4];
@ -373,8 +365,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -532,8 +524,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -651,6 +643,8 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver)
{
//ETR_TEXTURE_GOURAUD_ADD
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAdd2(driver);
#else

View File

@ -33,38 +33,38 @@
#define CMP_W
//#define WRITE_W
//#define IPOL_C0
#define IPOL_C0
#define IPOL_T0
//#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#undef IPOL_C0
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#define IPOL_Z
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
@ -83,13 +83,11 @@ public:
CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
void fragmentShader();
};
@ -106,7 +104,7 @@ CTRTextureGouraudAddNoZ2::CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)
/*!
*/
void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
void CTRTextureGouraudAddNoZ2::fragmentShader()
{
tVideoSample *dst;
@ -137,16 +135,15 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -155,7 +152,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[1] - line.c[0]) * invDeltaX;
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@ -173,7 +170,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC * subPixel;
line.c[0][0] += slopeC * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
@ -183,6 +180,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -198,6 +196,10 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#ifdef IPOL_C0
tFixPoint r2, g2, b2;
#endif
for ( s32 i = 0; i <= dx; ++i )
{
#ifdef CMP_Z
@ -207,20 +209,30 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
if ( line.w[0] >= z[i] )
#endif
{
#ifdef IPOL_W
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
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 );
getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);
color_to_fix ( r1, g1, b1, dst[i] );
dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + (r0 >> 1 ) ),
clampfix_maxcolor ( g1 + (g0 >> 1 ) ),
clampfix_maxcolor ( b1 + (b0 >> 1) )
);
#ifdef IPOL_C0
vec4_to_fix(r2, g2, b2, line.c[0][0], inversew);
r0 = imulFix(r2, r0);
g0 = imulFix(g2, g0);
b0 = imulFix(b2, b0);
#endif
//glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
if (r0 | g0 | b0)
{
color_to_fix(r1, g1, b1, dst[i]);
r1 = imulFix_tex1(r1, FIXPOINT_COLOR_MAX - r0);
g1 = imulFix_tex1(g1, FIXPOINT_COLOR_MAX - g0);
b1 = imulFix_tex1(b1, FIXPOINT_COLOR_MAX - b0);
dst[i] = fix_to_sample(r0+r1, g0+g1, b0+b1);
}
#ifdef WRITE_Z
z[i] = line.z[0];
@ -237,7 +249,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0] += slopeC;
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
@ -249,8 +261,11 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
}
void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
//billboard discard
//if (a->Color[0].r <= 0.f) return;
// sort on height, y
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);
@ -260,9 +275,9 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -293,8 +308,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
@ -316,7 +331,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] )
if (F32_GREATER_0(scan.invDeltaY[1]) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@ -333,8 +348,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
@ -348,8 +363,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -369,8 +384,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
@ -402,8 +417,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
@ -417,7 +432,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// render a scanline
scanline_bilinear ();
fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -433,8 +448,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
@ -451,10 +466,10 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
}
// rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] )
if (F32_GREATER_0(scan.invDeltaY[2]) )
{
// advance to middle point
if( (f32) 0.0 != scan.invDeltaY[1] )
if(F32_GREATER_0(scan.invDeltaY[1]) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
@ -466,7 +481,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
@ -492,8 +507,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
@ -507,8 +522,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -529,8 +544,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
@ -562,8 +577,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
@ -577,7 +592,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// render a scanline
scanline_bilinear ( );
fragmentShader( );
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -593,8 +608,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
@ -625,6 +640,20 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)
{
/*
ETR_TEXTURE_GOURAUD_ADD_NO_Z
Irrlicht:
Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;
Material.ZBuffer = ECFN_DISABLED;
-> need Material.ZWriteEnable off
OpenGL
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
*/
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAddNoZ2(driver);
#else

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -84,18 +84,12 @@ public:
CTRTextureGouraudAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
u32 AlphaRef;
};
//! constructor
@ -105,19 +99,17 @@ CTRTextureGouraudAlpha2::CTRTextureGouraudAlpha2(CBurningVideoDriver* driver)
#ifdef _DEBUG
setDebugName("CTRTextureGouraudAlpha2");
#endif
AlphaRef = 0;
}
/*!
*/
void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value)
void CTRTextureGouraudAlpha2::OnSetMaterial(const SBurningShaderMaterial& material)
{
#ifdef BURNINGVIDEO_RENDERER_FAST
AlphaRef = core::floor32_fast( value * 256.f );
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);
#else
AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );
AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
#endif
}
@ -147,15 +139,15 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -163,7 +155,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -200,6 +192,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -209,17 +202,15 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
f32 inversew = FIX_POINT_F32_MUL;
#ifdef BURNINGVIDEO_RENDERER_FAST
u32 dIndex = ( line.y & 3 ) << 2;
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = (line.y & 3) << 2;
#else
tFixPoint a0;
tFixPoint r0, g0, b0;
#endif
tFixPoint a0, r0, g0, b0;
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
#endif
for ( s32 i = 0; i <= dx; ++i )
@ -233,7 +224,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
{
#ifdef BURNINGVIDEO_RENDERER_FAST
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
@ -245,7 +236,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
d + tofix ( line.t[0][0].y,inversew)
);
const u32 alpha = ( argb >> 24 );
const tFixPoint alpha = ( argb >> 24 );
if ( alpha > AlphaRef )
{
#ifdef WRITE_Z
@ -263,19 +254,14 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
getSample_texture ( a0,r0,g0,b0,
&IT[0],
tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew)
);
#else
getSample_texture ( a0,r0,g0,b0,
&IT[0],
tofix ( line.t[0][0].x),
tofix ( line.t[0][0].y)
);
#endif
if ( (tFixPointu) a0 > AlphaRef )
if ( a0 > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
@ -284,30 +270,23 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
z[i] = line.w[0];
#endif
#ifdef INVERSE_W
getSample_color ( r2, g2, b2, line.c[0][0], inversew );
#else
getSample_color ( r2, g2, b2, line.c[0][0] );
#endif
r0 = imulFix ( r0, r2 );
g0 = imulFix ( g0, g2 );
b0 = imulFix ( b0, b2 );
#ifdef IPOL_C0
vec4_to_fix( r2, g2, b2, line.c[0][0], inversew );
r0 = imulFix_simple( r0, r2 );
g0 = imulFix_simple( g0, g2 );
b0 = imulFix_simple( b0, b2 );
color_to_fix ( r1, g1, b1, dst[i] );
a0 >>= 8;
fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_color ( a0, r2, g2, b2 );
dst[i] = fix4_to_sample( a0, r2, g2, b2 );
/*
dst[i] = PixelBlend32 ( dst[i],
fix_to_color ( r0,g0, b0 ),
fixPointu_to_u32 ( a0 )
);
*/
/*
getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );
color_to_fix ( r1, g1, b1, dst[i] );
@ -315,9 +294,14 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
r2 = r0 + imulFix ( a0, r1 - r0 );
g2 = g0 + imulFix ( a0, g1 - g0 );
b2 = b0 + imulFix ( a0, b1 - b0 );
dst[i] = fix_to_color ( r2, g2, b2 );
dst[i] = fix_to_sample ( r2, g2, b2 );
*/
#else
dst[i] = PixelBlend32 ( dst[i],
fix_to_sample( r0,g0, b0 ),
fixPointu_to_u32 ( a0 )
);
#endif
}
#endif
@ -342,7 +326,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
}
void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -353,9 +337,9 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -441,8 +425,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -600,8 +584,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -720,6 +704,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver)
{
//ETR_TEXTURE_GOURAUD_ALPHA
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAlpha2(driver);
#else

View File

@ -21,6 +21,7 @@
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_C1
#undef IPOL_T0
#undef IPOL_T1
@ -34,6 +35,7 @@
//#define WRITE_W
#define IPOL_C0
//#define IPOL_C1
#define IPOL_T0
//#define IPOL_T1
@ -46,10 +48,14 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@ -84,18 +90,34 @@ public:
CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1)
SBurningShaderMaterial Material;
virtual void setMaterial(const SBurningShaderMaterial &material)
{
Material = material;
}
virtual void setParam(u32 index, f32 value)
{
OnSetMaterial(Material);
}
#endif
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
// fragment shader
typedef void (CTRTextureGouraudAlphaNoZ::*tFragmentShader) ();
void fragment_linear();
void fragment_linear_test();
void fragment_point_noz();
tFragmentShader fragmentShader;
u32 AlphaRef;
};
//! constructor
@ -106,24 +128,37 @@ CTRTextureGouraudAlphaNoZ::CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver
setDebugName("CTRTextureGouraudAlphaNoZ");
#endif
AlphaRef = 0;
fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;
}
/*!
*/
void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value)
void CTRTextureGouraudAlphaNoZ::OnSetMaterial(const SBurningShaderMaterial& material)
{
#ifdef BURNINGVIDEO_RENDERER_FAST
AlphaRef = core::floor32_fast( value * 256.f );
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);
#else
AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );
AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
#endif
//check triangle on w = 1.f instead..
#ifdef SOFTWARE_DRIVER_2_BILINEAR
if (material.Fallback_MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear_test;
else
if ( material.org.TextureLayer[0].BilinearFilter )
fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;
else
#endif
fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_point_noz;
}
/*!
*/
void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
void CTRTextureGouraudAlphaNoZ::fragment_linear()
{
tVideoSample *dst;
@ -147,15 +182,15 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC[MATERIAL_MAX_COLORS];
sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -163,7 +198,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -174,6 +209,9 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif
@ -192,6 +230,9 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
@ -200,6 +241,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -209,7 +251,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
f32 inversew = FIX_POINT_F32_MUL;
#ifdef BURNINGVIDEO_RENDERER_FAST
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = ( line.y & 3 ) << 2;
#else
@ -219,7 +261,11 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
tFixPoint a2,r2, g2, b2;
#endif
#ifdef IPOL_C1
tFixPoint a3,r3, g3, b3;
#endif
for ( s32 i = 0; i <= dx; ++i )
@ -233,7 +279,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
{
#ifdef BURNINGVIDEO_RENDERER_FAST
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
@ -244,7 +290,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
d + tofix ( line.t[0][0].y,inversew)
);
const u32 alpha = ( argb >> 24 );
const tFixPoint alpha = ( argb >> 24 );
if ( alpha > AlphaRef )
{
#ifdef WRITE_Z
@ -262,19 +308,14 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
getSample_texture ( a0, r0, g0, b0,
&IT[0],
tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew)
);
#else
getSample_texture ( a0, r0, g0,b0,
&IT[0],
tofix ( line.t[0][0].x),
tofix ( line.t[0][0].y)
);
#endif
if ( (tFixPointu) a0 > AlphaRef )
if ( a0 > AlphaRef )
{
#ifdef WRITE_Z
z[i] = line.z[0];
@ -283,39 +324,30 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
z[i] = line.w[0];
#endif
#ifdef INVERSE_W
getSample_color ( r2, g2, b2, line.c[0][0], inversew );
#else
getSample_color ( r2, g2, b2, line.c[0][0] );
#endif
r0 = imulFix ( r0, r2 );
g0 = imulFix ( g0, g2 );
b0 = imulFix ( b0, b2 );
#ifdef IPOL_C0
vec4_to_fix( a2,r2, g2, b2, line.c[0][0], inversew );
//a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha
r0 = imulFix_simple( r0, r2 );
g0 = imulFix_simple( g0, g2 );
b0 = imulFix_simple( b0, b2 );
color_to_fix ( r1, g1, b1, dst[i] );
a0 >>= 8;
fix_color_norm(a0);
r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_color ( a0, r2, g2, b2 );
dst[i] = fix4_to_sample( a0, r2, g2, b2 );
/*
#else
dst[i] = PixelBlend32 ( dst[i],
fix_to_color ( r0,g0, b0 ),
fix_to_sample( r0,g0, b0 ),
fixPointu_to_u32 ( a0 )
);
*/
/*
getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );
color_to_fix ( r1, g1, b1, dst[i] );
r2 = r0 + imulFix ( a0, r1 - r0 );
g2 = g0 + imulFix ( a0, g1 - g0 );
b2 = b0 + imulFix ( a0, b1 - b0 );
dst[i] = fix_to_color ( r2, g2, b2 );
*/
#endif
}
#endif
@ -331,6 +363,9 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
#ifdef IPOL_C0
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
@ -341,7 +376,447 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
}
void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
/*!
*/
void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#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[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = fill_convention_left(line.x[0]);
xEnd = fill_convention_right(line.x[1]);
dx = xEnd - xStart;
if (dx < 0)
return;
// slopes
const f32 invDeltaX = reciprocal_zero2(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_C1
slopeC[1] = (line.c[1][1] - line.c[1][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 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_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif
f32 inversew = FIX_POINT_F32_MUL;
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = (line.y & 3) << 2;
#else
tFixPoint a0;
tFixPoint r0, g0, b0;
#endif
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
tFixPoint a2, r2, g2, b2;
#endif
#ifdef IPOL_C1
tFixPoint a3, 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
{
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask[dIndex | (i) & 3];
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
#endif
u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),
d + tofix(line.t[0][0].y, inversew)
);
const tFixPoint alpha = (argb >> 24);
if (alpha > AlphaRef)
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
dst[i] = PixelBlend32(dst[i], argb, alpha);
}
#else
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
#endif
getSample_texture(a0, r0, g0, b0,
&IT[0],
tofix(line.t[0][0].x, inversew),
tofix(line.t[0][0].y, inversew)
);
if (a0 > AlphaRef)
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#ifdef IPOL_C0
vec4_to_fix(a2, r2, g2, b2, line.c[0][0], inversew);
a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha
r0 = imulFix(r0, r2);
g0 = imulFix(g0, g2);
b0 = imulFix(b0, b2);
color_to_fix(r1, g1, b1, dst[i]);
fix_color_norm(a0);
r2 = r1 + imulFix(a0, r0 - r1);
g2 = g1 + imulFix(a0, g0 - g1);
b2 = b1 + imulFix(a0, b0 - b1);
dst[i] = fix4_to_sample(a0, r2, g2, b2);
#else
dst[i] = PixelBlend32(dst[i],
fix_to_sample(r0, g0, b0),
fixPointu_to_u32(a0)
);
#endif
}
#endif
}
#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_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
/*!
*/
void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
//fp24 *z;
#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[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = fill_convention_left(line.x[0]);
xEnd = fill_convention_right(line.x[1]);
dx = xEnd - xStart;
if (dx < 0)
return;
// slopes
const f32 invDeltaX = reciprocal_zero2(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_C1
slopeC[1] = (line.c[1][1] - line.c[1][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 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_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
#ifdef USE_ZBUFFER
//z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif
f32 inversew = FIX_POINT_F32_MUL;
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = (line.y & 3) << 2;
#else
tFixPoint a0;
tFixPoint r0, g0, b0;
#endif
#ifdef IPOL_C0
tFixPoint r1, g1, b1;
tFixPoint a2,r2, g2, b2;
#endif
#ifdef IPOL_C1
tFixPoint a3, 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
{
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask[dIndex | (i) & 3];
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
#endif
u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),
d + tofix(line.t[0][0].y, inversew)
);
const tFixPoint alpha = (argb >> 24);
if (alpha > AlphaRef)
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
dst[i] = PixelBlend32(dst[i], argb, alpha);
}
#else
#ifdef INVERSE_W
//inversew = fix_inverse32(line.w[0]);
#endif
getTexel_fix(a0, r0, g0, b0,
&IT[0],
tofix(line.t[0][0].x, inversew),
tofix(line.t[0][0].y, inversew)
);
if (a0 > AlphaRef)
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
//z[i] = line.w[0];
#endif
#ifdef IPOL_C0
vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);
a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha
r0 = imulFix(r0, r2);
g0 = imulFix(g0, g2);
b0 = imulFix(b0, b2);
color_to_fix(r1, g1, b1, dst[i]);
fix_color_norm(a0);
r2 = r1 + imulFix(a0, r0 - r1);
g2 = g1 + imulFix(a0, g0 - g1);
b2 = b1 + imulFix(a0, b0 - b1);
dst[i] = fix4_to_sample(a0, r2, g2, b2);
#else
dst[i] = PixelBlend32(dst[i],
fix_to_sample(r0, g0, b0),
fixPointu_to_u32(a0)
);
#endif
}
#endif
}
#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_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -352,9 +827,9 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -389,6 +864,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@ -429,6 +909,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@ -440,8 +925,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -465,6 +950,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -498,6 +988,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -509,7 +1004,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// render a scanline
scanline_bilinear ( );
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -529,6 +1024,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -560,6 +1060,10 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@ -588,6 +1092,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@ -599,8 +1108,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -625,6 +1134,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -658,6 +1172,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -669,7 +1188,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
#endif
// render a scanline
scanline_bilinear ( );
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -689,6 +1208,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -720,6 +1244,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
{
// ETR_TEXTURE_GOURAUD_ALPHA_NOZ
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudAlphaNoZ(driver);
#else
@ -728,6 +1253,7 @@ IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
}
} // end namespace video
} // end namespace irr

View File

@ -42,7 +42,7 @@
#define IPOL_T0
//#define IPOL_T1
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -88,13 +88,11 @@ public:
CTRTextureGouraudNoZ2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
@ -142,8 +140,8 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -151,7 +149,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -188,6 +186,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -199,7 +198,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
for ( s32 i = 0; i <= dx; ++i )
{
@ -216,12 +215,12 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );
//skybox
//dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );
getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 );
dst[i] = fix_to_sample( r0, g0, b0 );
/*
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
dst[i] = fix_to_color ( r0, g0, b0 );
*/
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
@ -249,7 +248,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
}
void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -260,9 +259,9 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -348,8 +347,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -507,8 +506,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -626,6 +625,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
{
// ETR_TEXTURE_GOURAUD_NOZ
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudNoZ2( driver );
#else

View File

@ -21,6 +21,7 @@
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_C1
#undef IPOL_T0
#undef IPOL_T1
@ -34,6 +35,7 @@
//#define WRITE_W
#define IPOL_C0
#define IPOL_C1
#define IPOL_T0
//#define IPOL_T1
@ -46,10 +48,15 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@ -82,13 +89,11 @@ public:
CTRTextureVertexAlpha2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
@ -129,15 +134,15 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -145,7 +150,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -154,7 +159,10 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@ -172,8 +180,12 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
@ -182,6 +194,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -191,22 +204,18 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
f32 inversew = FIX_POINT_F32_MUL;
//#define __TEST_THIS
#ifdef __TEST_THIS
#else
tFixPoint tx0;
tFixPoint ty0;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2;
#endif
#ifdef IPOL_C0
tFixPoint a3;
tFixPoint a2,r2, g2, b2;
#endif
#ifdef IPOL_C1
tFixPoint aFog = FIX_POINT_ONE;
#endif
@ -220,50 +229,74 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
#endif
{
#ifdef __TEST_THIS
inversew = fix_inverse32 ( line.w[0] );
dst[i] = PixelAdd32 (
dst[i],
getTexel_plain ( &IT[0], tofix ( line.t[0][0].x,inversew),
tofix ( line.t[0][0].y,inversew) )
);
#else
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
tx0 = tofix ( line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew);
#ifdef IPOL_C0
a3 = tofix ( line.c[0][0].y,inversew );
#endif
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
r2 = clampfix_maxcolor ( r1 + imulFix ( r0, a3 ) );
g2 = clampfix_maxcolor ( g1 + imulFix ( g0, a3 ) );
b2 = clampfix_maxcolor ( b1 + imulFix ( b0, a3 ) );
#else
r2 = clampfix_maxcolor ( r1 + r0 );
g2 = clampfix_maxcolor ( g1 + g0 );
b2 = clampfix_maxcolor ( b1 + b0 );
#endif
dst[i] = fix_to_color ( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
#endif
#ifdef IPOL_C1
//complete inside fog
if (TL_Flag & TL_FOG)
{
aFog = tofix(line.c[1][0].a, inversew);
if (aFog <= 0)
{
dst[i] = fog_color_sample;
continue;
}
}
#endif
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 );
color_to_fix ( r1, g1, b1, dst[i] );
#ifdef IPOL_C0
vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);
r0 = imulFix_simple(r0, r2);
g0 = imulFix_simple(g0, g2);
b0 = imulFix_simple(b0, b2);
#ifdef IPOL_C1
//specular highlight
if (TL_Flag & TL_SPECULAR)
{
vec4_to_fix(r2, g2, b2, line.c[1][0], inversew*COLOR_MAX);
r0 = clampfix_maxcolor(r2 + r0);
g0 = clampfix_maxcolor(g2 + g0);
b0 = clampfix_maxcolor(b2 + b0);
}
#endif
//blend background
r0 = r1 + imulFix(a2, r0 - r1);
g0 = g1 + imulFix(a2, g0 - g1);
b0 = b1 + imulFix(a2, b0 - b1);
#ifdef IPOL_C1
//mix with distance
if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)
{
r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);
g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);
b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);
}
#endif
#else
r0 = clampfix_maxcolor ( r1 + r0 );
g0 = clampfix_maxcolor ( g1 + g0 );
b0 = clampfix_maxcolor ( b1 + b0 );
#endif
dst[i] = fix_to_sample( r0, g0, b0 );
}
#ifdef IPOL_Z
@ -273,7 +306,10 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
@ -285,7 +321,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
}
void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -296,9 +332,9 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -333,6 +369,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@ -373,6 +414,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@ -384,8 +430,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -409,6 +455,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -442,6 +493,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -473,6 +529,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -504,6 +565,9 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@ -532,6 +596,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@ -543,8 +612,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -569,6 +638,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -602,6 +676,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -633,6 +712,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -662,6 +746,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver)
{
/* ETR_TEXTURE_GOURAUD_VERTEX_ALPHA */
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureVertexAlpha2(driver);
#else

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -82,15 +82,12 @@ public:
CTRTextureLightMap2_Add(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
@ -137,8 +134,8 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -146,7 +143,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -183,6 +180,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -190,11 +188,10 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
f32 inversew = FIX_POINT_F32_MUL;
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
u32 dIndex = ( line.y & 3 ) << 2;
#else
//
tFixPoint r0, g0, b0;
@ -219,11 +216,12 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
z[i] = line.w[0];
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
#ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] );
inversew = fix_inverse32(line.w[0]);
#endif
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
dst[i] = PixelAdd32 (
@ -234,12 +232,11 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
);
#else
const 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[0][1].x,inversew), tofix ( line.t[0][1].y,inversew) );
dst[i] = fix_to_color ( clampfix_maxcolor ( r0 + r1 ),
dst[i] = fix_to_sample( clampfix_maxcolor ( r0 + r1 ),
clampfix_maxcolor ( g0 + g1 ),
clampfix_maxcolor ( b0 + b1 )
);
@ -266,7 +263,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
}
void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -277,9 +274,9 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -365,8 +362,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -524,8 +521,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -82,14 +82,12 @@ public:
CTRTextureLightMap2_M1(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear2 ();
sScanLineData line;
};
//! constructor
@ -115,15 +113,15 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -170,6 +168,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
line.z[0] = a;
line.z[1] = b;
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
@ -226,7 +225,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
#endif
dst[i] = fix_to_color ( imulFix_tex1 ( r0, r1 ),
dst[i] = fix_to_sample( imulFix_tex1 ( r0, r1 ),
imulFix_tex1 ( g0, g1 ),
imulFix_tex1 ( b0, b1 )
);
@ -244,9 +243,8 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
}
void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
sScanConvertData scan;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -257,9 +255,9 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -345,8 +343,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -505,8 +503,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -626,6 +624,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver)
{
//ETR_TEXTURE_GOURAUD_LIGHTMAP_M1
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureLightMap2_M1(driver);
#else

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -82,14 +82,12 @@ public:
CTRTextureLightMap2_M2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear2 ();
sScanLineData line;
};
//! constructor
@ -115,15 +113,15 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -170,6 +168,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
line.z[0] = a;
line.z[1] = b;
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
@ -226,7 +225,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
#endif
dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )
);
@ -244,10 +243,8 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
}
void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
sScanConvertData scan;
// sort on height, y
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);
@ -257,9 +254,9 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -345,8 +342,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -505,8 +502,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -82,19 +82,21 @@ public:
CTRTextureLightMap2_M4(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
void drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
void scanline_bilinear ();
#if defined(SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)
void drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );
void drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );
void scanline_bilinear2_mag ();
void scanline_bilinear2_min ();
#else
#define scanline_bilinear2_mag scanline_bilinear
#endif
sScanLineData line;
void scanline_bilinear ();
};
@ -109,14 +111,14 @@ CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(CBurningVideoDriver* driver)
/*!
*/
REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
{
tVideoSample *dst;
fp24 *z;
// apply top-left fill-convention, left
const s32 xStart = irr::core::ceil32_fast( line.x[0] );
const s32 xEnd = irr::core::ceil32_fast( line.x[1] ) - 1;
const s32 xStart = fill_convention_left(line.x[0]);
const s32 xEnd = fill_convention_right(line.x[1]);
s32 dx;
s32 i;
@ -125,8 +127,10 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
if ( dx < 0 )
return;
SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
i = ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -229,11 +233,7 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
#endif
dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )
);
dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));
}
#ifdef IPOL_W
@ -248,7 +248,8 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
}
REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)
void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
{
tVideoSample *dst;
fp24 *z;
@ -260,15 +261,17 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left(line.x[0]);
xEnd = fill_convention_right(line.x[1]);
dx = xEnd - xStart;
if ( dx < 0 )
return;
SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -315,6 +318,7 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
line.z[0] = a;
line.z[1] = b;
#endif
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
a = (f32) i + subPixel;
@ -352,10 +356,7 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
getTexel_fix ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),
clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),
clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )
);
dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));
}
#ifdef IPOL_W
@ -369,21 +370,20 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
}
//#ifdef BURNINGVIDEO_RENDERER_FAST
#if 1
void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
if ( IT[0].lodLevel <= 2 )
drawTriangle_Mag ( a, b, c );
if (IT[0].lodFactor < 4)
{
drawTriangle_Mag(a, b, c);
}
else
drawTriangle_Min ( a, b, c );
{
drawTriangle_Min(a, b, c);
}
}
void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
{
sScanConvertData scan;
// sort on height, y
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);
@ -393,9 +393,9 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
@ -481,8 +481,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -641,8 +641,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -746,16 +746,15 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
}
void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
#else
#else //#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)
void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
#endif
{
sScanConvertData scan;
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -765,14 +764,18 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
if ( F32_LOWER_EQUAL_0 ( ca ) )
return;
// calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
//if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
// return;
// find if the major edge is left or right aligned
f32 temp[4];
@ -855,8 +858,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -1015,8 +1018,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
@ -1120,6 +1123,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
}
#undef scanline_bilinear2_mag
} // end namespace video
} // end namespace irr

View File

@ -46,7 +46,7 @@
#undef SUBTEXEL
#endif
#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
@ -82,15 +82,12 @@ public:
CTRGTextureLightMap2_M4(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
private:
void scanline_bilinear ();
sScanConvertData scan;
sScanLineData line;
};
//! constructor
@ -137,8 +134,8 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
#endif
// apply top-left fill-convention, left
xStart = core::ceil32_fast( line.x[0] );
xEnd = core::ceil32_fast( line.x[1] ) - 1;
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
@ -146,7 +143,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
return;
// slopes
const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );
#ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -183,6 +180,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
@ -230,26 +228,22 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );
#ifdef IPOL_C0
r2 = imulFix ( r0, r3 );
g2 = imulFix ( g0, g3 );
b2 = imulFix ( b0, b3 );
r2 = imulFix_simple( r0, r3 );
g2 = imulFix_simple( g0, g3 );
b2 = imulFix_simple( b0, b3 );
r2 = imulFix_tex4 ( r2, r1 );
g2 = imulFix_tex4 ( g2, g1 );
b2 = imulFix_tex4 ( b2, b1 );
r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) );
/*
r2 = r3 << 8;
g2 = g3 << 8;
b2 = b3 << 8;
*/
#else
r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );
g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );
b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );
r2 = imulFix_tex4 ( r0, r1 );
g2 = imulFix_tex4 ( g0, g1 );
b2 = imulFix_tex4 ( b0, b1 );
#endif
dst[i] = fix_to_color ( r2, g2, b2 );
dst[i] = fix_to_sample( r2, g2, b2 );
#ifdef WRITE_Z
z[i] = line.z[0];
@ -278,7 +272,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
}
void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
@ -289,9 +283,9 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = core::reciprocal( ca );
scan.invDeltaY[1] = core::reciprocal( ba );
scan.invDeltaY[2] = core::reciprocal( cb );
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_0 ( scan.invDeltaY[0] ) )
return;
@ -379,8 +373,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( a->Pos.y );
yEnd = core::ceil32_fast( b->Pos.y ) - 1;
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -540,8 +534,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
#endif
// apply top-left fill convention, top part
yStart = core::ceil32_fast( b->Pos.y );
yEnd = core::ceil32_fast( c->Pos.y ) - 1;
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL

View File

@ -28,14 +28,14 @@
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
//#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
//#define CMP_W
//#define WRITE_W
//#define IPOL_C0
#define IPOL_T0
#define IPOL_C0
//#define IPOL_T0
//#define IPOL_T1
// apply global override
@ -47,6 +47,10 @@
#undef SUBTEXEL
#endif
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
@ -80,14 +84,17 @@ public:
CTRTextureWire2(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) _IRR_OVERRIDE_;
virtual void drawPoint( const s4DVertex *a) _IRR_OVERRIDE_;
virtual bool canWireFrame () _IRR_OVERRIDE_ { return true; }
virtual bool canPointCloud() _IRR_OVERRIDE_ { return true; }
protected:
virtual void scanline_bilinear ();
private:
void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;
void renderLine ( const s4DVertex *a,const s4DVertex *b ) const;
void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const;
};
@ -101,26 +108,20 @@ CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
}
// swap integer with xor
static inline void swap_xor ( s32 &a, s32 &b )
{
a ^= b;
b ^= a;
a ^= b;
}
/*!
2d line
*/
void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const
{
int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY;
int pitch1 = RenderTarget->getDimension().Width << 2;
int aposx = (int) a->Pos.x;
int aposy = (int) a->Pos.y;
int bposx = (int) b->Pos.x;
int bposy = (int) b->Pos.y;
//todo:!
int aposx = fill_convention_none(a->Pos.x);
int aposy = fill_convention_none(a->Pos.y);
int bposx = fill_convention_none(b->Pos.x);
int bposy = fill_convention_none(b->Pos.y);
int dx = bposx - aposx;
int dy = bposy - aposy;
@ -138,37 +139,39 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY;
int yInc0 = pitch0;
#ifdef USE_ZBUFFER
int xInc1 = 4;
int yInc1 = pitch1;
tVideoSample color;
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
tFixPoint r0, g0, b0;
getSample_color ( r0, g0, b0, a->Color[0] );
color = fix_to_color ( r0, g0, b0 );
#else
color = (tVideoSample) 0xFFFFFFFF;
#endif
if ( dx < 0 )
{
xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY);
#ifdef USE_ZBUFFER
xInc1 = -4;
#endif
dx = -dx;
}
if ( dy > dx )
{
swap_xor ( dx, dy );
swap_xor ( xInc0, yInc0 );
swap_xor ( xInc1, yInc1 );
//swap
register s32 t;
t = dx;dx=dy;dy=t;
t = xInc0;xInc0=yInc0;yInc0=t;
#ifdef USE_ZBUFFER
t = xInc1;xInc1=yInc1;yInc1=t;
#endif
}
if ( 0 == dx )
return;
if (0 == dx)
{
if (!renderZero) return;
dx = 1;
}
dst = (tVideoSample*) ( (u8*) (tVideoSample*)RenderTarget->getData() + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) );
SOFTWARE_DRIVER_2_CLIPCHECK_WIRE;
dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< VIDEO_SAMPLE_GRANULARITY) ) );
#ifdef USE_ZBUFFER
z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );
#endif
@ -176,16 +179,43 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
c = dx << 1;
m = dy << 1;
// slopes
const f32 invDeltaX = reciprocal_zero2( (f32)dx );
#ifdef IPOL_Z
f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx);
f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX;
f32 dataZ = a->Pos.z;
#endif
#ifdef IPOL_W
fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx );
fp24 slopeW = (b->Pos.w - a->Pos.w) * invDeltaX;
fp24 dataW = a->Pos.w;
#endif
f32 inversew = FIX_POINT_F32_MUL;
tVideoSample color;
#if BURNING_MATERIAL_MAX_COLORS > 0
tFixPoint r0, g0, b0;
#ifdef IPOL_C0
sVec4 slopeC;
sVec4 C;
slopeC = (b->Color[0] - a->Color[0]) * invDeltaX;
C = a->Color[0];
#endif
#ifdef INVERSE_W
inversew = fix_inverse32_color(dataW);
#endif
vec4_to_fix( r0, g0, b0, a->Color[0], inversew);
color = fix_to_sample( r0, g0, b0 );
#else
color = (tVideoSample) 0xFFFFFFFF;
#endif
run = dx;
while ( run )
{
@ -203,15 +233,22 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
*z = dataW;
#endif
*dst = color;
#ifdef IPOL_C0
#ifdef INVERSE_W
inversew = fix_inverse32_color(dataW);
#endif
vec4_to_fix(r0, g0, b0, C,inversew);
color = fix_to_sample( r0, g0, b0 );
#endif
*dst = color;
}
dst = (tVideoSample*) ( (u8*) dst + xInc0 ); // x += xInc
#ifdef IPOL_Z
#ifdef CMP_Z
z = (fp24*) ( (u8*) z + xInc1 );
#endif
#ifdef IPOL_W
#ifdef CMP_W
z = (fp24*) ( (u8*) z + xInc1 );
#endif
@ -219,10 +256,10 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
if ( d > dx )
{
dst = (tVideoSample*) ( (u8*) dst + yInc0 ); // y += yInc
#ifdef IPOL_Z
#ifdef CMP_Z
z = (fp24*) ( (u8*) z + yInc1 );
#endif
#ifdef IPOL_W
#ifdef CMP_W
z = (fp24*) ( (u8*) z + yInc1 );
#endif
@ -235,15 +272,21 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
#ifdef IPOL_W
dataW += slopeW;
#endif
#ifdef IPOL_C0
C += slopeC;
#endif
}
}
void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
void CTRTextureWire2::scanline_bilinear()
{
sScanLineData line;
}
void CTRTextureWire2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
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);
@ -258,14 +301,17 @@ void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b)
{
// query access to TexMaps
// sort on height, y
if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);
if (F32_A_GREATER_B(a->Pos.y,b->Pos.y )) swapVertexPointer(&a, &b);
renderLine ( a, b );
}
void CTRTextureWire2::drawPoint(const s4DVertex *a)
{
if ( (a->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) renderLine(a, a,1);
}
@ -283,6 +329,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver)
{
//ETR_TEXTURE_GOURAUD_WIRE
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureWire2(driver);
#else

View File

@ -0,0 +1,729 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
// compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_T0
#undef IPOL_T1
// define render case
#define SUBTEXEL
#define INVERSE_W
#define USE_ZBUFFER
#define IPOL_W
#define CMP_W
#define WRITE_W
#define IPOL_C0
#define IPOL_T0
#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
class CTR_transparent_reflection_2_layer : public IBurningShader
{
public:
//! constructor
CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private:
void fragmentShader();
E_MATERIAL_TYPE MaterialType;
};
//! constructor
CTR_transparent_reflection_2_layer::CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName("CTR_transparent_reflection_2_layer");
#endif
}
void CTR_transparent_reflection_2_layer::OnSetMaterial(const SBurningShaderMaterial& material)
{
MaterialType = material.org.MaterialType;
}
/*!
*/
void CTR_transparent_reflection_2_layer::fragmentShader()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#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;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart;
if ( dx < 0 )
return;
// slopes
const f32 invDeltaX = reciprocal_zero2( 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 = (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 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 * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
#endif
f32 inversew = FIX_POINT_F32_MUL;
tFixPoint r0, g0, b0;
tFixPoint r1, g1, b1;
#ifdef IPOL_C0
tFixPoint a1;
#endif
switch(MaterialType) {
default:
case EMT_REFLECTION_2_LAYER:
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
{
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
#endif
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));
r0 = imulFix_tex1(r0, r1);
g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1);
#ifdef IPOL_C0
vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0);
#endif
dst[i] = fix_to_sample(r0, g0, b0);
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
break;
case EMT_TRANSPARENT_REFLECTION_2_LAYER:
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
{
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
#endif
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));
r0 = imulFix_tex1(r0, r1);
g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1);
#ifdef IPOL_C0
vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0);
//vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER
if (a1 + 2 < FIX_POINT_ONE)
{
color_to_fix(r1, g1, b1, dst[i]);
r0 = r1 + imulFix(a1, r0 - r1);
g0 = g1 + imulFix(a1, g0 - g1);
b0 = b1 + imulFix(a1, b0 - b1);
}
#endif
dst[i] = fix_to_sample(r0, g0, b0);
#ifdef WRITE_Z
//z[i] = line.z[0];
#endif
#ifdef WRITE_W
//z[i] = line.w[0];
#endif
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
break;
}
}
void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
{
// sort on height, y
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);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca );
scan.invDeltaY[1] = reciprocal_zero( ba );
scan.invDeltaY[2] = reciprocal_zero( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( F32_GREATER_0(scan.invDeltaY[1]) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if ( F32_GREATER_0(scan.invDeltaY[2]) )
{
// advance to middle point
if( F32_GREATER_0(scan.invDeltaY[1]) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
//! creates a flat triangle renderer
IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver)
{
/*
ETR_TRANSPARENT_REFLECTION_2_LAYER
Irrlicht EMT_REFLECTION_2_LAYER,EMT_TRANSPARENT_REFLECTION_2_LAYER
*/
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTR_transparent_reflection_2_layer(driver);
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr

View File

@ -8,9 +8,12 @@
#include "SoftwareDriver2_compile_config.h"
#include "IBurningShader.h"
#include "CSoftwareDriver2.h"
#include "IShaderConstantSetCallBack.h"
namespace irr
{
namespace video
{
@ -22,95 +25,369 @@ namespace video
0xf0,0x70,0xd0,0x50
};
IBurningShader::IBurningShader(CBurningVideoDriver* driver)
IBurningShader::IBurningShader(CBurningVideoDriver* driver)
{
#ifdef _DEBUG
setDebugName("IBurningShader");
#endif
EdgeTestPass = edge_test_pass;
EdgeTestPass_stack = edge_test_pass;
for ( u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
#ifdef _DEBUG
setDebugName("IBurningShader");
#endif
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
IT[i].Texture = 0;
}
Driver = driver;
RenderTarget = 0;
ColorMask = COLOR_BRIGHT_WHITE;
DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();
if ( DepthBuffer )
DepthBuffer->grab();
Stencil = (CStencilBuffer*) driver->getStencilBuffer ();
if ( Stencil )
Stencil->grab();
IT[i].Texture = 0;
}
Driver = driver;
CallBack = 0;
//! destructor
IBurningShader::~IBurningShader()
RenderTarget = 0;
ColorMask = COLOR_BRIGHT_WHITE;
DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();
if ( DepthBuffer )
DepthBuffer->grab();
Stencil = (CStencilBuffer*) driver->getStencilBuffer ();
if ( Stencil )
Stencil->grab();
stencilOp[0] = StencilOp_KEEP;
stencilOp[1] = StencilOp_KEEP;
stencilOp[2] = StencilOp_KEEP;
AlphaRef = 0;
RenderPass_ShaderIsTransparent = 0;
PrimitiveColor = COLOR_BRIGHT_WHITE;
TL_Flag = 0;
}
//! Constructor
IBurningShader::IBurningShader(
CBurningVideoDriver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName,
E_VERTEX_SHADER_TYPE vsCompileTarget,
const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram ,
const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget,
scene::E_PRIMITIVE_TYPE inType,
scene::E_PRIMITIVE_TYPE outType,
u32 verticesOut,
IShaderConstantSetCallBack* callback,
E_MATERIAL_TYPE baseMaterial,
s32 userData)
:IBurningShader(driver)
{
BaseMaterial = baseMaterial;
CallBack = callback;
if (CallBack)
CallBack->grab();
// register myself as new material
outMaterialTypeNr = Driver->addMaterialRenderer(this);
}
//! destructor
IBurningShader::~IBurningShader()
{
if (RenderTarget)
RenderTarget->drop();
if (DepthBuffer)
DepthBuffer->drop();
if (Stencil)
Stencil->drop();
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
if (RenderTarget)
RenderTarget->drop();
if (DepthBuffer)
DepthBuffer->drop();
if (Stencil)
Stencil->drop();
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )
{
if ( IT[i].Texture )
IT[i].Texture->drop();
}
if ( IT[i].Texture )
IT[i].Texture->drop();
}
//! sets a render target
void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)
if (CallBack)
CallBack->drop();
}
//! sets a render target
void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)
{
if (RenderTarget)
RenderTarget->drop();
RenderTarget = (video::CImage* ) surface;
if (RenderTarget)
{
if (RenderTarget)
RenderTarget->drop();
RenderTarget->grab();
RenderTarget = (video::CImage* ) surface;
//(fp24*) DepthBuffer->lock() = DepthBuffer->lock();
}
}
if (RenderTarget)
{
RenderTarget->grab();
//(fp24*) DepthBuffer->lock() = DepthBuffer->lock();
}
//! sets the Texture
void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor)
{
sInternalTexture *it = &IT[stage];
if ( it->Texture)
it->Texture->drop();
it->Texture = texture;
if ( it->Texture)
{
it->Texture->grab();
// select mignify and magnify
it->lodFactor = lodFactor;
//only mipmap chain (means positive lodFactor)
u32 existing_level = it->Texture->getMipmapLevel(lodFactor);
it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY, existing_level, 0);
// prepare for optimal fixpoint
it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );
const core::dimension2d<u32> &dim = it->Texture->getSize();
it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
}
}
//emulate a line with degenerate triangle and special shader mode (not perfect...)
void IBurningShader::drawLine ( const s4DVertex *a,const s4DVertex *b)
{
sVec2 d;
d.x = b->Pos.x - a->Pos.x; d.x *= d.x;
d.y = b->Pos.y - a->Pos.y; d.y *= d.y;
//if ( d.x * d.y < 0.001f ) return;
if ( a->Pos.x > b->Pos.x ) swapVertexPointer(&a, &b);
s4DVertex c = *a;
const f32 w = (f32)RenderTarget->getDimension().Width-1;
const f32 h = (f32)RenderTarget->getDimension().Height-1;
if ( d.x < 2.f ) { c.Pos.x = b->Pos.x + 1.f + d.y; if ( c.Pos.x > w ) c.Pos.x = w; }
else c.Pos.x = b->Pos.x;
if ( d.y < 2.f ) { c.Pos.y = b->Pos.y + 1.f; if ( c.Pos.y > h ) c.Pos.y = h; EdgeTestPass |= edge_test_first_line; }
drawTriangle ( a,b,&c );
EdgeTestPass &= ~edge_test_first_line;
}
void IBurningShader::drawPoint(const s4DVertex *a)
{
}
void IBurningShader::drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )
{
if ( EdgeTestPass & edge_test_pass ) drawTriangle(a, b, c);
else if (EdgeTestPass & edge_test_point)
{
drawPoint(a);
drawPoint(b);
drawPoint(c);
}
else
{
drawLine(a, b);
drawLine(b, c);
drawLine(a, c);
}
}
void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services)
{
if (Driver)
Driver->setFallback_Material(BaseMaterial);
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (CallBack)
CallBack->OnSetMaterial(material);
}
void IBurningShader::OnUnsetMaterial()
{
}
bool IBurningShader::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
{
// call callback to set shader constants
if (CallBack)
CallBack->OnSetConstants(this, UserData);
return true;
}
//! Returns if the material is transparent.
bool IBurningShader::isTransparent() const
{
return RenderPass_ShaderIsTransparent != 0;
}
//! Access the callback provided by the users when creating shader materials
IShaderConstantSetCallBack* IBurningShader::getShaderConstantSetCallBack() const
{
return CallBack;
}
// implementations for the render services
void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates)
{
// forward
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags,const c8* name)
{
if (!name || !name[0])
return -1;
BurningUniform add;
tiny_strcpy(add.name, name);
add.type = flags;
s32 index = UniformInfo.linear_search(add);
if (index < 0)
{
UniformInfo.push_back(add);
index = UniformInfo.size() - 1;
}
return index;
}
//! sets the Texture
void IBurningShader::setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel)
const char* tiny_itoa(s32 value, int base)
{
static char b[32];
int p = 31;
//int sign = 0;
//if (value < 0) { sign = 1; value = -value; }
b[p] = '\0';
do {
b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value%base];
value /= base;
} while (value && p > 0);
//if (sign && p > 0) { b[--p] = '-'; }
return b + p;
}
bool IBurningShader::setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count)
{
if ((u32)index >= UniformInfo.size())
return false;
#if 0
BurningUniform add;
while ((u32)index >= UniformInfo.size())
{
sInternalTexture *it = &IT[stage];
if ( it->Texture)
it->Texture->drop();
it->Texture = texture;
if ( it->Texture)
{
it->Texture->grab();
// select mignify and magnify ( lodLevel )
//SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS
it->lodLevel = lodLevel;
it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY,
core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ), 0);
// prepare for optimal fixpoint
it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );
const core::dimension2d<u32> &dim = it->Texture->getSize();
it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;
}
tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(),10));
add.type = flags;
UniformInfo.push_back(add);
}
#endif
BurningUniform& use = UniformInfo[index];
use.type = flags;
const u32* s = (u32*)data;
u32* d = (u32*)use.data;
if (!s) u32_count = 0;
if (u32_count > array_size(use.data)) u32_count = array_size(use.data);
for (size_t i = 0; i < u32_count; ++i)
{
d[i] = s[i];
}
return true;
}
s32 IBurningShader::getVertexShaderConstantID(const c8* name)
{
return getShaderConstantID(BL_VERTEX_PROGRAM, name);
}
s32 IBurningShader::getPixelShaderConstantID(const c8* name)
{
return getShaderConstantID(BL_FRAGMENT_PROGRAM, name);
}
void IBurningShader::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
tiny_strcpy(name, tiny_itoa(startRegister, 10));
setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM,name), data, constantAmount);
}
void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)
{
c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
tiny_strcpy(name, tiny_itoa(startRegister, 10));
setShaderConstantID(BL_FRAGMENT_FLOAT, getShaderConstantID(BL_FRAGMENT_PROGRAM, name), data, constantAmount);
}
bool IBurningShader::setVertexShaderConstant(s32 index, const f32* floats, int count)
{
return setShaderConstantID(BL_VERTEX_FLOAT, index, floats, count);
}
bool IBurningShader::setVertexShaderConstant(s32 index, const s32* ints, int count)
{
return setShaderConstantID(BL_VERTEX_INT, index, ints, count);
}
bool IBurningShader::setVertexShaderConstant(s32 index, const u32* ints, int count)
{
return setShaderConstantID(BL_VERTEX_UINT, index, ints, count);
}
bool IBurningShader::setPixelShaderConstant(s32 index, const f32* floats, int count)
{
return setShaderConstantID(BL_FRAGMENT_FLOAT, index, floats, count);
}
bool IBurningShader::setPixelShaderConstant(s32 index, const s32* ints, int count)
{
return setShaderConstantID(BL_FRAGMENT_INT, index, ints, count);
}
bool IBurningShader::setPixelShaderConstant(s32 index, const u32* ints, int count)
{
return setShaderConstantID(BL_FRAGMENT_UINT, index, ints, count);
}
void IBurningShader::setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass)
{
stencilOp[0] = sfail;
stencilOp[1] = dpfail;
stencilOp[2] = dppass;
}
IVideoDriver* IBurningShader::getVideoDriver()
{
return Driver;
}
} // end namespace video

View File

@ -18,7 +18,9 @@
#include "SLight.h"
#include "SMaterial.h"
#include "os.h"
#include "IMaterialRenderer.h"
#include "IMaterialRendererServices.h"
#include "IGPUProgrammingServices.h"
namespace irr
{
@ -29,56 +31,109 @@ namespace video
struct SBurningShaderLight
{
//SLight org;
bool LightIsOn;
sVec4 pos; //light position input
sVec4 pos4; //light position Model*View (Identity*View)
E_LIGHT_TYPE Type;
f32 radius;
f32 linearAttenuation;
f32 constantAttenuation;
f32 quadraticAttenuation;
sVec4 pos;
sVec3 AmbientColor;
sVec3 DiffuseColor;
sVec3 SpecularColor;
sVec4 pos_objectspace;
sVec4 spotDirection;
sVec4 spotDirection4;
f32 spotCosCutoff;
f32 spotCosInnerCutoff;
f32 spotExponent;
bool LightIsOn;
sVec3Color AmbientColor;
sVec3Color DiffuseColor;
sVec3Color SpecularColor;
};
enum eLightFlags
enum eTransformLightFlags
{
ENABLED = 0x01,
POINTLIGHT = 0x02,
SPECULAR = 0x04,
FOG = 0x08,
NORMALIZE = 0x10,
VERTEXTRANSFORM = 0x20,
//ENABLED = 0x01,
TL_SCISSOR = 0x02,
TL_LIGHT = 0x04,
TL_SPECULAR = 0x08,
TL_FOG = 0x10,
TL_NORMALIZE_NORMALS = 0x20,
TL_TEXTURE_TRANSFORM = 0x40,
TL_LIGHT_LOCAL_VIEWER = 0x80,
TL_LIGHT0_IS_NORMAL_MAP = 0x100 //sVec4 Light Vector is used as normal or specular
};
struct SBurningShaderLightSpace
struct SBurningShaderEyeSpace
{
SBurningShaderEyeSpace() {}
virtual ~SBurningShaderEyeSpace() {}
void reset ()
{
Light.set_used ( 0 );
Global_AmbientLight.set ( 0.f, 0.f, 0.f );
Flags = 0;
Global_AmbientLight.set ( 0.f );
TL_Flag = TL_LIGHT_LOCAL_VIEWER;
}
void resetFog()
{
fog_scale = 0.f;
//cam_distance = 0.f;
}
core::array<SBurningShaderLight> Light;
sVec3 Global_AmbientLight;
sVec4 FogColor;
sVec4 campos;
sVec4 vertex;
sVec4 normal;
u32 Flags;
sVec3Color Global_AmbientLight;
//sVec4 cam_eye_pos; //Camera Position in eye Space (0,0,-1)
//sVec4 cam_world_pos; //Camera Position in world Space
//sVec4 vertex4; //eye coordinate position of vertex
sVec4 normal; //transformed normal
sVec4 vertex; //eye coordinate position of vertex projected
//derivative of vertex
//f32 cam_distance; // vertex.length();
sVec4 cam_dir; //vertex.normalize();
f32 fog_scale; // 1 / (fog.end-fog.start)
size_t TL_Flag; // eTransformLightFlags
};
enum eBurningCullFlag
{
CULL_FRONT = 1,
CULL_BACK = 2,
CULL_INVISIBLE = 4, //primitive smaller than a pixel (AreaMinDrawSize)
CULL_FRONT_AND_BACK = 8,
};
enum eBurningStencilOp
{
StencilOp_KEEP = 0x1E00,
StencilOp_INCR = 0x1E02,
StencilOp_DECR = 0x1E03
};
struct SBurningShaderMaterial
{
SMaterial org;
SMaterial lastMaterial;
bool resetRenderStates;
sVec3 AmbientColor;
sVec3 DiffuseColor;
sVec3 SpecularColor;
sVec3 EmissiveColor;
E_MATERIAL_TYPE Fallback_MaterialType;
SMaterial mat2D;
//SMaterial save3D;
size_t CullFlag; //eCullFlag
u32 depth_write;
u32 depth_test;
sVec3Color AmbientColor;
sVec3Color DiffuseColor;
sVec3Color SpecularColor;
sVec3Color EmissiveColor;
};
@ -106,29 +161,88 @@ namespace video
ETR_TEXTURE_GOURAUD_DETAIL_MAP,
ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD,
ETR_GOURAUD_ALPHA,
ETR_GOURAUD_NOZ,
//ETR_GOURAUD_ALPHA,
ETR_GOURAUD_ALPHA_NOZ,
ETR_TEXTURE_GOURAUD_ALPHA,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ_NOPERSPECTIVE_CORRECT,
ETR_NORMAL_MAP_SOLID,
ETR_STENCIL_SHADOW,
ETR_TEXTURE_BLEND,
ETR_REFERENCE,
ETR_TRANSPARENT_REFLECTION_2_LAYER,
ETR_COLOR,
//ETR_REFERENCE,
ETR_INVALID,
ETR2_COUNT
};
typedef enum
{
BL_VERTEX_PROGRAM = 1,
BL_FRAGMENT_PROGRAM = 2,
BL_TYPE_FLOAT = 4,
BL_TYPE_INT = 8,
BL_TYPE_UINT = 16,
BL_VERTEX_FLOAT = (BL_VERTEX_PROGRAM | BL_TYPE_FLOAT),
BL_VERTEX_INT = (BL_VERTEX_PROGRAM | BL_TYPE_INT),
BL_VERTEX_UINT = (BL_VERTEX_PROGRAM | BL_TYPE_UINT),
BL_FRAGMENT_FLOAT = (BL_FRAGMENT_PROGRAM | BL_TYPE_FLOAT),
BL_FRAGMENT_INT = (BL_FRAGMENT_PROGRAM | BL_TYPE_INT),
BL_FRAGMENT_UINT = (BL_FRAGMENT_PROGRAM | BL_TYPE_UINT),
BL_ACTIVE_UNIFORM_MAX_LENGTH = 28
} EBurningUniformFlags;
struct BurningUniform
{
c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
u32 type; //EBurningUniformFlags
//int location; // UniformLocation is index
f32 data[16]; // simple LocalParameter
bool operator==(const BurningUniform& other) const
{
return tiny_istoken(name, other.name);
}
};
class CBurningVideoDriver;
class IBurningShader : public virtual IReferenceCounted
class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices
{
public:
//! Constructor
IBurningShader(CBurningVideoDriver* driver);
//! Constructor
IBurningShader(
CBurningVideoDriver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram = 0,
const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
//! destructor
virtual ~IBurningShader();
@ -136,27 +250,119 @@ namespace video
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort);
//! sets the Texture
virtual void setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel);
virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) = 0;
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) {};
virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) {};
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b);
virtual void drawPoint(const s4DVertex *a);
virtual void setParam ( u32 index, f32 value) {};
virtual void setZCompareFunc ( u32 func) {};
void drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void setMaterial ( const SBurningShaderMaterial &material ) {};
virtual void OnSetMaterial( const SBurningShaderMaterial& material ) {};
void pushEdgeTest(const int wireFrame,const int point,int save)
{
if ( save ) EdgeTestPass_stack = EdgeTestPass;
EdgeTestPass = point ? edge_test_point : wireFrame ? edge_test_left : edge_test_pass;
}
void popEdgeTest() { EdgeTestPass = EdgeTestPass_stack; }
virtual bool canWireFrame () { return false; }
virtual bool canPointCloud() { return false; }
void setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass);
//IMaterialRenderer
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_;
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_;
virtual void OnUnsetMaterial() _IRR_OVERRIDE_;
//! Returns if the material is transparent.
virtual bool isTransparent() const _IRR_OVERRIDE_;
//! Access the callback provided by the users when creating shader materials
virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const _IRR_OVERRIDE_;
// implementations for the render services
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) _IRR_OVERRIDE_;
virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;
virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;
virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;
virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;
virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
//used if no color interpolation is defined
void setPrimitiveColor(const video::SColor& color)
{
#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8
PrimitiveColor = color.color;
#else
PrimitiveColor = color.toA1R5G5B5();
#endif
}
void setTLFlag(size_t in /*eTransformLightFlags*/)
{
TL_Flag = in;
}
void setFog(SColor color_fog)
{
#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8
fog_color_sample = color_fog.color;
#else
fog_color_sample = color_fog.toA1R5G5B5();
#endif
color_to_fix(fog_color, fog_color_sample);
}
void setScissor(const AbsRectangle& scissor)
{
Scissor = scissor;
}
protected:
CBurningVideoDriver *Driver;
IShaderConstantSetCallBack* CallBack;
E_MATERIAL_TYPE BaseMaterial;
s32 UserData;
core::array<BurningUniform> UniformInfo;
s32 getShaderConstantID(EBurningUniformFlags program, const c8* name);
bool setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count);
video::CImage* RenderTarget;
CDepthBuffer* DepthBuffer;
CStencilBuffer * Stencil;
CStencilBuffer* Stencil;
tVideoSample ColorMask;
sInternalTexture IT[ BURNING_MATERIAL_MAX_TEXTURES ];
static const tFixPointu dithermask[ 4 * 4];
//draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham
int EdgeTestPass; //edge_test_flag
int EdgeTestPass_stack;
eBurningStencilOp stencilOp[4];
tFixPoint AlphaRef;
int RenderPass_ShaderIsTransparent;
sScanConvertData scan;
sScanLineData line;
tVideoSample PrimitiveColor; //used if no color interpolation is defined
size_t /*eTransformLightFlags*/ TL_Flag;
tFixPoint fog_color[4];
tVideoSample fog_color_sample;
AbsRectangle Scissor;
};
@ -172,6 +378,7 @@ namespace video
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);
@ -192,8 +399,9 @@ namespace video
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver);
IBurningShader* create_burning_shader_color(CBurningVideoDriver* driver);
} // end namespace video
} // end namespace irr

View File

@ -21,7 +21,7 @@ namespace video
virtual ~IDepthBuffer() {};
//! clears the zbuffer
virtual void clear() = 0;
virtual void clear(f32 value) = 0;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0;
@ -51,29 +51,29 @@ namespace video
//! destructor
virtual ~IStencilBuffer() {};
//! clears the zbuffer
virtual void clear() = 0;
//! clears the stencil buffer
virtual void clear(u8 value) = 0;
//! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0;
//! returns the size of the zbuffer
//! returns the size of the stencil buffer
virtual const core::dimension2d<u32>& getSize() const = 0;
//! locks the zbuffer
//! locks the stencil buffer
virtual void* lock() = 0;
//! unlocks the zbuffer
//! unlocks the stencil buffer
virtual void unlock() = 0;
//! returns pitch of depthbuffer (in bytes)
//! returns pitch of stencil buffer (in bytes)
virtual u32 getPitch() const = 0;
};
//! creates a Stencil Buffer
IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size);
IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit);
} // end namespace video
} // end namespace irr

View File

@ -60,11 +60,21 @@ namespace irr
return createDeviceEx(p);
}
#if defined(IRRLICHT_FREE_CANVAS)
extern "C" IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& _params)
{
SIrrlichtCreationParameters params = _params;
params.WindowResizable = true;
#else
extern "C" IRRLICHT_API IrrlichtDevice* IRRCALLCONV createDeviceEx(const SIrrlichtCreationParameters& params)
{
#endif
IrrlichtDevice* dev = 0;
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
if (params.DeviceType == EIDT_WIN32 || (!dev && params.DeviceType == EIDT_BEST))
dev = new CIrrDeviceWin32(params);

View File

@ -1004,6 +1004,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
<ClInclude Include="burning_shader_color_fraq.h" />
<ClInclude Include="burning_shader_compile_fragment_default.h" />
<ClInclude Include="burning_shader_compile_fragment_end.h" />
<ClInclude Include="burning_shader_compile_fragment_start.h" />
<ClInclude Include="burning_shader_compile_start.h" />
<ClInclude Include="burning_shader_compile_triangle.h" />
<ClInclude Include="burning_shader_compile_verify.h" />
<ClInclude Include="CB3DMeshWriter.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
@ -1257,6 +1264,7 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="burning_shader_color.cpp" />
<ClCompile Include="CB3DMeshWriter.cpp" />
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
@ -1298,6 +1306,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
<ClCompile Include="CTRGouraudNoZ2.cpp" />
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />

View File

@ -1345,6 +1345,27 @@
<ClInclude Include="..\..\include\IOctreeSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="burning_shader_color_fraq.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_default.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_end.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_start.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_start.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_triangle.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_verify.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2282,6 +2303,15 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
<ClCompile Include="burning_shader_color.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
<ClCompile Include="CTRGouraudNoZ2.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -1298,6 +1298,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
<ClCompile Include="CTRGouraudNoZ2.cpp" />
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />

View File

@ -2282,6 +2282,12 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
<ClCompile Include="CTRGouraudNoZ2.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -1015,7 +1015,15 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
<ClInclude Include="burning_shader_color_fraq.h" />
<ClInclude Include="burning_shader_compile_fragment_default.h" />
<ClInclude Include="burning_shader_compile_fragment_end.h" />
<ClInclude Include="burning_shader_compile_fragment_start.h" />
<ClInclude Include="burning_shader_compile_start.h" />
<ClInclude Include="burning_shader_compile_triangle.h" />
<ClInclude Include="burning_shader_compile_verify.h" />
<ClInclude Include="CB3DMeshWriter.h" />
<ClInclude Include="CBlit.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
<ClInclude Include="CDefaultSceneNodeFactory.h" />
@ -1268,6 +1276,7 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="burning_shader_color.cpp" />
<ClCompile Include="CB3DMeshWriter.cpp" />
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
@ -1309,6 +1318,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
<ClCompile Include="CTRGouraudNoZ2.cpp" />
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />

View File

@ -1345,6 +1345,30 @@
<ClInclude Include="..\..\include\IOctreeSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="burning_shader_color_fraq.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_default.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_end.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_start.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_start.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_triangle.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_verify.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="CBlit.h">
<Filter>Irrlicht\video\Null</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2282,6 +2306,15 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
<ClCompile Include="burning_shader_color.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
<ClCompile Include="CTRGouraudNoZ2.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -1014,6 +1014,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
<ClInclude Include="burning_shader_color_fraq.h" />
<ClInclude Include="burning_shader_compile_fragment_default.h" />
<ClInclude Include="burning_shader_compile_fragment_end.h" />
<ClInclude Include="burning_shader_compile_fragment_start.h" />
<ClInclude Include="burning_shader_compile_start.h" />
<ClInclude Include="burning_shader_compile_triangle.h" />
<ClInclude Include="burning_shader_compile_verify.h" />
<ClInclude Include="CB3DMeshWriter.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
@ -1268,6 +1275,7 @@
<None Include="Irrlicht.ruleset" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="burning_shader_color.cpp" />
<ClCompile Include="CB3DMeshWriter.cpp" />
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
@ -1309,6 +1317,8 @@
<ClCompile Include="CQ3LevelMesh.cpp" />
<ClCompile Include="CSkinnedMesh.cpp" />
<ClCompile Include="CSTLMeshFileLoader.cpp" />
<ClCompile Include="CTRGouraudNoZ2.cpp" />
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />
<ClCompile Include="CWGLManager.cpp" />
<ClCompile Include="CXMeshFileLoader.cpp" />
<ClCompile Include="CAnimatedMeshSceneNode.cpp" />

View File

@ -1342,6 +1342,27 @@
<ClInclude Include="..\..\include\SOverrideMaterial.h">
<Filter>include\video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_color_fraq.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_default.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_end.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_fragment_start.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_start.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_triangle.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
<ClInclude Include="burning_shader_compile_verify.h">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2280,6 +2301,15 @@
<ClCompile Include="CWGLManager.cpp">
<Filter>Irrlicht\video\OpenGL Context</Filter>
</ClCompile>
<ClCompile Include="burning_shader_color.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
<ClCompile Include="CTR_transparent_reflection_2_layer.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
<ClCompile Include="CTRGouraudNoZ2.cpp">
<Filter>Irrlicht\video\Burning Video</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -44,7 +44,13 @@ IRRDRVROBJ = CNullDriver.o COpenGLCacheHandler.o COpenGLDriver.o COpenGLNormalMa
IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderDDS.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderPVR.o CImageLoaderTGA.o CImageLoaderPPM.o CImageLoaderWAL.o CImageLoaderRGB.o \
CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)
IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o
IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o \
CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o \
CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o \
CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o \
CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o \
CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o \
CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o CTR_transparent_reflection_2_layer.o CTRGouraudNoZ2.o burning_shader_color.o
IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CWADReader.o CZipReader.o CPakReader.o CNPKReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o lzma/LzmaDec.o
IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CIrrDeviceFB.o CLogger.o COSOperator.o Irrlicht.o os.o leakHunter.o CProfiler.o utf8.o
IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o CGUIProfiler.o

File diff suppressed because it is too large Load Diff

View File

@ -7,10 +7,28 @@
#include "IrrCompileConfig.h"
// Generic Render Flags for burning's video rasterizer
// defined now in irrlicht compile config
#if defined(PATCH_SUPERTUX_8_0_1)
#undef BURNINGVIDEO_RENDERER_BEAUTIFUL
//#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
@ -18,11 +36,15 @@
#define SOFTWARE_DRIVER_2_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D
#endif
//! Set Flags for Windows Mobile
@ -36,7 +58,10 @@
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 64
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
@ -44,25 +69,34 @@
#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING
//#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_16BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
#ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST
#define BURNINGVIDEO_RENDERER_FAST
//#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_SUBTEXEL
//#define SOFTWARE_DRIVER_2_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING
//#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0
#define SOFTWARE_DRIVER_2_16BIT
//#define SOFTWARE_DRIVER_2_MIPMAPPING
//#define SOFTWARE_DRIVER_2_USE_WBUFFER
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
// Derivate flags
@ -74,24 +108,24 @@
#define BURNINGSHADER_COLOR_FORMAT ECF_A1R5G5B5
#endif
// mip mapping
// mip mapping - precalculated texture filter
#if defined ( SOFTWARE_DRIVER_2_MIPMAPPING )
#if defined( BURNINGVIDEO_RENDERER_BEAUTIFUL )
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#elif defined ( BURNINGVIDEO_RENDERER_CE )
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#endif
#else
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#endif
#define SOFTWARE_DRIVER_2_MIPMAPPING_SCALE (16/SOFTWARE_DRIVER_2_MIPMAPPING_MAX)
#ifndef REALINLINE
#ifdef _MSC_VER
@ -101,4 +135,155 @@
#endif
#endif
// null check necessary (burningvideo only)
#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)
static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f; }
#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
#define fill_convention_left(x) (s32) ceilf(x)
#define fill_convention_right(x) ((s32) ceilf(x))-1
#define fill_convention_none(x) (s32) (x)
//#define fill_convention_left(x) 65536 - int(65536.0f - x)
//#define fill_convention_right(x) 65535 - int(65536.0f - x)
//Check coordinates are in render target/window space
//#define SOFTWARE_DRIVER_2_DO_CLIPCHECK
#if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32)
#define SOFTWARE_DRIVER_2_CLIPCHECK if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
#define SOFTWARE_DRIVER_2_CLIPCHECK_REF if( pShader.xStart < 0 || pShader.xStart + pShader.dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE if( aposx < 0 || aposx >= (s32)RenderTarget->getDimension().Width || aposy < 0 || aposy >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
inline float reciprocal_zero_no(const float x)
{
if (x*x <= 0.00001f) __debugbreak();
return 1.f / x;
}
#else
#define SOFTWARE_DRIVER_2_CLIPCHECK
#define SOFTWARE_DRIVER_2_CLIPCHECK_REF
#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE
#define reciprocal_zero_no(x) 1.f/x
#endif
//!scanline renderer emulate line
enum edge_test_flag
{
edge_test_pass = 1, //! not wireframe
edge_test_left = 0,
edge_test_first_line = 2,
edge_test_point = 4
};
//if any edge test flag is set result=1 else 0. ( pass height test for degenerate triangle )
#define reciprocal_edge(x) ((x) != 0.f ? 1.f / (x):(~EdgeTestPass)&1)
//! normalize from fixed point Color Max to fixed point [0;1]
#define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2
//! from 1 bit to 5 bit
#ifdef SOFTWARE_DRIVER_2_32BIT
#define fix_alpha_color_max(x)
#else
#define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1
#endif
// Check windows
#if _WIN32 || _WIN64
#if _WIN64
#define ENV64BIT
#else
#define ENV32BIT
#endif
#endif
// Check GCC
#if __GNUC__
#if __x86_64__ || __ppc64__
#define ENV64BIT
#else
#define ENV32BIT
#endif
#endif
#if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL)
typedef float ipoltype;
#else
typedef float ipoltype;
#endif
#define ipol_lower_equal_0(n) ((n) <= (ipoltype)0.0)
#define ipol_greater_0(n) ((n) > (ipoltype)0.0)
#if (_MSC_VER >= 1600 )
#define burning_restrict __restrict
#else
#define burning_restrict
#endif
/*
if (condition) state |= mask; else state &= ~mask;
*/
static inline void burning_setbit(size_t &state, int condition, size_t mask)
{
if (condition) state |= mask;
else state &= ~mask;
}
/*
if (condition) state |= m; else state &= ~m;
*/
REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsigned int mask)
{
// 0, or any positive to mask
//s32 conmask = -condition >> 31;
state ^= ((-condition >> 31) ^ state) & mask;
}
#define burning_stringify(s) #s
#define burning_create_indirect(s) create_##s
#define burning_create(s) burning_create_indirect(s)
#if defined(PATCH_SUPERTUX_8_0_1)
#define getData lock
#define snprintf_irr sprintf_s
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#ifdef SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define BURNING_MATERIAL_MAX_COLORS 2
#else
#define BURNING_MATERIAL_MAX_COLORS 1
#endif
#else
#define BURNING_MATERIAL_MAX_COLORS 0
#endif
#ifndef _IRR_OVERRIDE_
#define _IRR_OVERRIDE_ /**/
#endif
#define fix_to_color fix_to_sample
#define fix4_to_color fix4_to_sample
#define vec4_to_fix getSample_color
#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0
namespace irr {
REALINLINE void memcpy32_small(void * dest, const void *source, size_t bytesize)
{
size_t c = bytesize >> 2;
do
{
((unsigned int *)dest)[c - 1] = ((unsigned int *)source)[c - 1];
} while (--c);
}
} // namespace irr
#endif // #if defined(PATCH_SUPERTUX_8_0_1)
#endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,95 @@
// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "IrrCompileConfig.h"
#include "IBurningShader.h"
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
#define burning_shader_class burning_shader_color
#define burning_shader_frag "burning_shader_color_fraq.h"
#include "burning_shader_compile_fragment_default.h"
/*!
*/
void burning_shader_class::OnSetMaterial(const SBurningShaderMaterial& material)
{
switch (material.org.MaterialType)
{
case EMT_TRANSPARENT_ADD_COLOR:
case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
//glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
case EMT_TRANSPARENT_ALPHA_CHANNEL:
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
//? glBlendFunc(GL_ONE,GL_ZERO) or glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
case EMT_TRANSPARENT_REFLECTION_2_LAYER:
case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
RenderPass_ShaderIsTransparent = 1;
AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
break;
default:
RenderPass_ShaderIsTransparent = 0;
AlphaRef = 0;
break;
}
if (0 == RenderPass_ShaderIsTransparent)
{
if (material.org.ZBuffer == ECFN_LESSEQUAL)
{
if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;
else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_one_zero;
}
else /*if (material.org.ZBuffer == ECFN_DISABLED)*/
{
//check triangle on w = 1.f instead..
#ifdef SOFTWARE_DRIVER_2_BILINEAR
if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_one_zero;
else
#endif
fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_one_zero;
}
}
else
{
if (material.org.ZBuffer == ECFN_LESSEQUAL)
{
if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha;
else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha;
}
else /*if (material.org.ZBuffer == ECFN_DISABLED)*/
{
//check triangle on w = 1.f instead..
#ifdef SOFTWARE_DRIVER_2_BILINEAR
if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha;
else
#endif
fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha;
}
}
}
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

View File

@ -0,0 +1,24 @@
// pixelshader
#ifdef IPOL_C0
#ifdef IPOL_A0
vec4_to_fix(a0, r0, g0, b0, line.c[0][0], inversew);
if (a0 > AlphaRef)
{
color_to_fix(r1, g1, b1, dst[i]);
fix_color_norm(a0);
r0 = r1 + imulFix(a0, r0 - r1);
g0 = g1 + imulFix(a0, g0 - g1);
b0 = b1 + imulFix(a0, b0 - b1);
dst[i] = fix_to_sample(r0, g0, b0);
}
#else
vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);
dst[i] = fix_to_sample(r0, g0, b0);
#endif
#else
dst[i] = PrimitiveColor;
#endif

View File

@ -0,0 +1,164 @@
class burning_shader_class : public IBurningShader
{
public:
//! constructor
burning_shader_class(CBurningVideoDriver* driver);
//! draws an indexed triangle list
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;
virtual bool canWireFrame() { return true; }
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private:
// fragment shader
typedef void (burning_shader_class::*tFragmentShader) ();
void fragment_depth_less_equal_depth_write_blend_one_zero();
void fragment_depth_less_equal_no_depth_write_blend_one_zero();
void fragment_nodepth_perspective_blend_one_zero();
void fragment_nodepth_noperspective_blend_one_zero(); // 2D Gradient
void fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha();
void fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha();
void fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha();
void fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha();
tFragmentShader fragmentShader;
};
//! constructor
burning_shader_class::burning_shader_color(CBurningVideoDriver* driver)
: IBurningShader(driver)
{
#ifdef _DEBUG
setDebugName(burning_stringify(burning_shader_class) );
#endif
fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;
}
IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver)
{
return new burning_shader_class(driver);
}
// compile flag for this triangle
#include "burning_shader_compile_start.h"
#define SUBTEXEL
#define IPOL_W
#define IPOL_C0
#define USE_ZBUFFER
#define CMP_W
#include "burning_shader_compile_triangle.h"
// compile flag for this scanline fragment
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_nodepth_noperspective_blend_one_zero
#define SUBTEXEL
#define IPOL_C0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_nodepth_perspective_blend_one_zero
#define SUBTEXEL
#define INVERSE_W
#define IPOL_W
#define IPOL_C0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_one_zero
#define SUBTEXEL
#define INVERSE_W
#define IPOL_W
#define IPOL_C0
#define USE_ZBUFFER
#define CMP_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_one_zero
#define SUBTEXEL
#define INVERSE_W
#define IPOL_W
#define IPOL_C0
#define USE_ZBUFFER
#define CMP_W
#define WRITE_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
// compile flag for this scanline fragment
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha
#define SUBTEXEL
#define IPOL_C0
#define IPOL_A0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha
#define SUBTEXEL
#define INVERSE_W
#define IPOL_W
#define IPOL_C0
#define IPOL_A0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha
#define SUBTEXEL
#define INVERSE_W
#define IPOL_W
#define IPOL_C0
#define IPOL_A0
#define USE_ZBUFFER
#define CMP_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha
#define SUBTEXEL
#define INVERSE_W
#define IPOL_W
#define IPOL_C0
#define IPOL_A0
#define USE_ZBUFFER
#define CMP_W
#define WRITE_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"

View File

@ -0,0 +1,20 @@
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}

View File

@ -0,0 +1,119 @@
#include "burning_shader_compile_verify.h"
/*!
*/
void burning_shader_class::burning_shader_fragment()
{
tVideoSample *dst;
#ifdef USE_ZBUFFER
fp24 *z;
#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;
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = fill_convention_left(line.x[0]);
xEnd = fill_convention_right(line.x[1]);
dx = xEnd - xStart;
if (dx < 0)
return;
// slopes
const f32 invDeltaX = reciprocal_zero2(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 = (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 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 * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1] * subPixel;
#endif
#endif
SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
#ifdef USE_ZBUFFER
z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif
f32 inversew = INVERSE_W_RANGE;
#ifdef IPOL_C0
tFixPoint r0, g0, b0;
#endif
#ifdef IPOL_A0
tFixPoint a0;
tFixPoint r1, g1, b1;
#endif
for (s32 i = 0; i <= dx; ++i)
{
if ((0 == EdgeTestPass) & i) break;
#ifdef CMP_Z
if (line.z[0] < z[i])
#endif
#ifdef CMP_W
if (line.w[0] >= z[i])
#endif
{
#ifdef WRITE_Z
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
#endif
/* Pixel Shader here */
#ifdef INVERSE_W
inversew = (INVERSE_W_RANGE) / line.w[0]; /* fix_inverse32(line.w[0]);*/
#endif

View File

@ -0,0 +1,24 @@
// undef compile flag for this file
#undef USE_ZBUFFER
#undef IPOL_Z
#undef CMP_Z
#undef WRITE_Z
#undef IPOL_W
#undef CMP_W
#undef WRITE_W
#undef SUBTEXEL
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_A0
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_T2
#undef IPOL_L0
#undef burning_shader_fragment
#undef ipol_test
#undef INVERSE_W_RANGE

View File

@ -0,0 +1,368 @@
#include "burning_shader_compile_verify.h"
void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{
// sort on height, y
if (a->Pos.y > b->Pos.y) swapVertexPointer(&a, &b);
if (a->Pos.y > c->Pos.y) swapVertexPointer(&a, &c);
if (b->Pos.y > c->Pos.y) swapVertexPointer(&b, &c);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_edge(ca);
scan.invDeltaY[1] = reciprocal_edge(ba);
scan.invDeltaY[2] = reciprocal_edge(cb);
if (F32_LOWER_EQUAL_0(scan.invDeltaY[0]))
return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0][0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if (F32_GREATER_0(scan.invDeltaY[1]))
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left(a->Pos.y);
yEnd = fill_convention_right(b->Pos.y);
#ifdef SUBTEXEL
subPixel = ((f32)yStart) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for (line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
(this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
if (F32_GREATER_0(scan.invDeltaY[2]))
{
// advance to middle point
if (F32_GREATER_0(scan.invDeltaY[1]))
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left(b->Pos.y);
yEnd = fill_convention_right(c->Pos.y);
#ifdef SUBTEXEL
subPixel = ((f32)yStart) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for (line.y = yStart; line.y <= yEnd; ++line.y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[0][scan.left] = scan.c[0][0];
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
(this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break;
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0][0] += scan.slopeC[0][0];
scan.c[0][1] += scan.slopeC[0][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}

View File

@ -0,0 +1,43 @@
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#endif
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#undef IPOL_A0
#endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
#undef IPOL_L0
#endif
// 1/x * FIX_POINT
#if !defined(INVERSE_W_RANGE)
#define INVERSE_W_RANGE FIX_POINT_F32_MUL
#endif
#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )
#else
#ifdef IPOL_W
#undef IPOL_W
#define IPOL_Z
#endif
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif