Burningsvideo 0.52

- scissor for 2D
- downscaled internal rendertargets,interlaced drawing
- supertuxkart gui ok

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6154 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
engineer_apple 2020-11-10 18:49:39 +00:00
parent 6805226b5b
commit 5cb28ea357
59 changed files with 2115 additions and 1848 deletions

@ -13,15 +13,16 @@ Changes in 1.9 (not yet released)
- Improvements to B3D writer for speed, readability and handling of low framerate animations. - Improvements to B3D writer for speed, readability and handling of low framerate animations.
Thanks @JLouisB for the patch (For more info, see: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=2&t=50067&start=15) Thanks @JLouisB for the patch (For more info, see: http://irrlicht.sourceforge.net/forum/viewtopic.php?f=2&t=50067&start=15)
- Add another render pass ESNRP_GUI which is drawn last and is p.E. useful for rendering gui nodes in the scenemanager. - Add another render pass ESNRP_GUI which is drawn last and is p.E. useful for rendering gui nodes in the scenemanager.
- BurningVideo: 0.51 - BurningVideo: 0.52
- 10 year anniversary update - 10 year anniversary update
- Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map] - 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] - increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]
- Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption - 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 - 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D, scissor
- Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE] - Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]
- NormalMap for 1 Light accurate. still all lights are accumulated - NormalMap for 1 Light accurate. still all lights are accumulated
- SuperTuxKart 8.0.1 playable - SuperTuxKart 8.0.1 playable
- Internal Backbuffer Scaling and Interlacing
- Known Problems - Known Problems
- Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows - Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows
- Triangle MipMap Selection. Wrong for TextureAtlas and Billboards - Triangle MipMap Selection. Wrong for TextureAtlas and Billboards

@ -70,7 +70,7 @@ bool CMainMenu::run()
gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1); gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1);
box->addItem(L"OpenGL 1.5"); box->addItem(L"OpenGL 1.5");
box->addItem(L"Direct3D 9.0c"); box->addItem(L"Direct3D 9.0c");
box->addItem(L"Burning's Video 0.51"); box->addItem(L"Burning's Video 0.52");
box->addItem(L"Irrlicht Software Renderer 1.0"); box->addItem(L"Irrlicht Software Renderer 1.0");
switch (driverType ) switch (driverType )
{ {

@ -29,6 +29,9 @@ public:
//! constructor //! constructor
IImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, bool deleteMemory) : IImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, bool deleteMemory) :
Format(format), Size(size), Data(0), MipMapsData(0), BytesPerPixel(0), Pitch(0), DeleteMemory(deleteMemory), DeleteMipMapsMemory(false) Format(format), Size(size), Data(0), MipMapsData(0), BytesPerPixel(0), Pitch(0), DeleteMemory(deleteMemory), DeleteMipMapsMemory(false)
#if defined(IRRLICHT_sRGB)
,Format_sRGB(1)
#endif
{ {
BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8; BytesPerPixel = getBitsPerPixelFromFormat(Format) / 8;
Pitch = BytesPerPixel * Size.Width; Pitch = BytesPerPixel * Size.Width;
@ -50,6 +53,18 @@ public:
return Format; return Format;
} }
#if defined(IRRLICHT_sRGB)
//! Texture is linear/sRGB (should be part of ColorFormat: default yes)
int get_sRGB() const
{
return Format_sRGB;
}
void set_sRGB(int val)
{
Format_sRGB = val;
}
#endif
//! Returns width and height of image data. //! Returns width and height of image data.
const core::dimension2d<u32>& getDimension() const const core::dimension2d<u32>& getDimension() const
{ {
@ -531,6 +546,22 @@ public:
return false; return false;
} }
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
static bool isRenderTargetOnlyFormat(const ECOLOR_FORMAT format)
{
switch (format)
{
case ECF_A1R5G5B5:
case ECF_R5G6B5:
case ECF_R8G8B8:
case ECF_A8R8G8B8:
return false;
default:
return true;
}
}
#endif
protected: protected:
ECOLOR_FORMAT Format; ECOLOR_FORMAT Format;
core::dimension2d<u32> Size; core::dimension2d<u32> Size;
@ -545,8 +576,12 @@ protected:
bool DeleteMipMapsMemory; bool DeleteMipMapsMemory;
core::irrAllocator<u8> Allocator; core::irrAllocator<u8> Allocator;
#if defined(IRRLICHT_sRGB)
int Format_sRGB;
#endif
}; };
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr

@ -698,7 +698,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0]; const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
// store slopes in endpoint, and correct first pixel // store slopes in endpoint, and correct first pixel
@ -722,8 +722,8 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
} }
SOFTWARE_DRIVER_2_CLIPCHECK_REF; SOFTWARE_DRIVER_2_CLIPCHECK_REF;
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
for ( pShader.i = 0; pShader.i <= pShader.dx; ++pShader.i ) for ( pShader.i = 0; pShader.i <= pShader.dx; ++pShader.i )
{ {
@ -764,10 +764,10 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
// subTexel // subTexel
const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0]; const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];
@ -807,7 +807,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
line.w[0] = a; line.w[0] = a;
line.w[1] = b; line.w[1] = b;
pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) ); pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) );
a = (f32) pShader.i + subPixel; a = (f32) pShader.i + subPixel;
@ -863,9 +863,9 @@ void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_rest
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero2( c->Pos.y - a->Pos.y ); scan.invDeltaY[0] = fill_step_y( c->Pos.y - a->Pos.y );
scan.invDeltaY[1] = reciprocal_zero2( b->Pos.y - a->Pos.y ); scan.invDeltaY[1] = fill_step_y( b->Pos.y - a->Pos.y );
scan.invDeltaY[2] = reciprocal_zero2( c->Pos.y - b->Pos.y ); scan.invDeltaY[2] = fill_step_y( c->Pos.y - b->Pos.y );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -959,7 +959,7 @@ void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_rest
} }
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.w[scan.left] = scan.w[0]; line.w[scan.left] = scan.w[0];
@ -1076,7 +1076,7 @@ void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_rest
} }
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.w[scan.left] = scan.w[0]; line.w[scan.left] = scan.w[0];

@ -40,7 +40,7 @@ CDepthBuffer::~CDepthBuffer()
//! clears the zbuffer //! clears the zbuffer
void CDepthBuffer::clear(f32 value) void CDepthBuffer::clear(f32 value, interlaced_control interlaced)
{ {
ieee754 zMaxValue; ieee754 zMaxValue;
@ -50,7 +50,7 @@ void CDepthBuffer::clear(f32 value)
zMaxValue.f = value; zMaxValue.f = value;
#endif #endif
memset32 ( Buffer, zMaxValue.u, TotalSize ); memset32_interlaced(Buffer, zMaxValue.u, Pitch, Size.Height, interlaced);
} }
@ -66,9 +66,10 @@ void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
delete [] Buffer; delete [] Buffer;
Pitch = size.Width * sizeof ( fp24 ); Pitch = size.Width * sizeof ( fp24 );
TotalSize = Pitch * size.Height; size_t TotalSize = Pitch * size.Height;
Buffer = new u8[align_next(TotalSize,16)]; Buffer = new u8[align_next(TotalSize,16)];
clear ();
clear( 1.f, interlace_disabled());
} }
@ -107,7 +108,7 @@ CStencilBuffer::~CStencilBuffer()
//! clears the buffer //! clears the buffer
void CStencilBuffer::clear(u8 value) void CStencilBuffer::clear(u32 value, const interlaced_control interlaced)
{ {
u32 set = value; u32 set = value;
if (Bit == 8) if (Bit == 8)
@ -115,7 +116,7 @@ void CStencilBuffer::clear(u8 value)
set |= set << 8; set |= set << 8;
set |= set << 16; set |= set << 16;
} }
memset32 ( Buffer, set, TotalSize ); memset32_interlaced ( Buffer, set, Pitch,Size.Height,interlaced );
} }
@ -131,9 +132,10 @@ void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
delete [] Buffer; delete [] Buffer;
Pitch = size.Width * sizeof (tStencilSample); Pitch = size.Width * sizeof (tStencilSample);
TotalSize = Pitch * size.Height; size_t TotalSize = Pitch * size.Height;
Buffer = new u8[align_next(TotalSize,16)]; Buffer = new u8[align_next(TotalSize,16)];
clear ();
clear(0, interlace_disabled());
} }

@ -23,7 +23,7 @@ namespace video
virtual ~CDepthBuffer(); virtual ~CDepthBuffer();
//! clears the zbuffer //! clears the zbuffer
virtual void clear(f32 value=1.f) _IRR_OVERRIDE_; virtual void clear(f32 value, const interlaced_control interlaced) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_; virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@ -45,7 +45,6 @@ namespace video
u8* Buffer; u8* Buffer;
core::dimension2d<u32> Size; core::dimension2d<u32> Size;
u32 TotalSize;
u32 Pitch; u32 Pitch;
}; };
@ -61,7 +60,7 @@ namespace video
virtual ~CStencilBuffer(); virtual ~CStencilBuffer();
//! clears the zbuffer //! clears the zbuffer
virtual void clear(u8 value=0) _IRR_OVERRIDE_; virtual void clear(u32 value, const interlaced_control interlaced) _IRR_OVERRIDE_;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_; virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@ -82,7 +81,6 @@ namespace video
private: private:
u8* Buffer; u8* Buffer;
core::dimension2d<u32> Size; core::dimension2d<u32> Size;
u32 TotalSize;
u32 Pitch; u32 Pitch;
u32 Bit; u32 Bit;
}; };

File diff suppressed because it is too large Load Diff

@ -50,6 +50,18 @@ namespace video
virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil,
const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_; const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual bool beginScene(bool backBuffer, bool zBuffer, SColor color,
const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
{
u16 flag = 0;
if (backBuffer) flag |= ECBF_COLOR;
if (zBuffer) flag |= ECBF_DEPTH;
return beginScene(flag, color, 1.f, 0, videoData, sourceRect);
}
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer, bool clearZBuffer, SColor color);
#endif
virtual bool endScene() _IRR_OVERRIDE_; virtual bool endScene() _IRR_OVERRIDE_;
//! Only used by the internal engine. Used to notify the driver that //! Only used by the internal engine. Used to notify the driver that
@ -152,7 +164,12 @@ namespace video
//! Creates a render target texture. //! Creates a render target texture.
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size, virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_; const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
, const bool useStencil = false
#endif
) _IRR_OVERRIDE_;
virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_; virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_;
@ -190,8 +207,10 @@ namespace video
//! Check if the driver supports creating textures with the given color format //! Check if the driver supports creating textures with the given color format
virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_; virtual bool queryTextureFormat(ECOLOR_FORMAT format) const _IRR_OVERRIDE_;
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
//! Used by some SceneNodes to check if a material should be rendered in the transparent render pass //! Used by some SceneNodes to check if a material should be rendered in the transparent render pass
virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_; virtual bool needsTransparentRenderPass(const irr::video::SMaterial& material) const _IRR_OVERRIDE_;
#endif
IDepthBuffer * getDepthBuffer () { return DepthBuffer; } IDepthBuffer * getDepthBuffer () { return DepthBuffer; }
IStencilBuffer * getStencilBuffer () { return StencilBuffer; } IStencilBuffer * getStencilBuffer () { return StencilBuffer; }
@ -252,6 +271,33 @@ namespace video
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_; virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
}
virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
}
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
}
virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
}
#endif
//! Get pointer to the IVideoDriver interface //! Get pointer to the IVideoDriver interface
/** \return Pointer to the IVideoDriver interface */ /** \return Pointer to the IVideoDriver interface */
virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_; virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
@ -261,7 +307,7 @@ namespace video
void saveBuffer(); void saveBuffer();
//! sets a render target //! sets a render target
void setRenderTargetImage(video::CImage* image); void setRenderTargetImage2(video::IImage* color, video::IImage* depth=0, video::IImage* stencil=0);
//! sets the current Texture //! sets the current Texture
//bool setTexture(u32 stage, video::ITexture* texture); //bool setTexture(u32 stage, video::ITexture* texture);
@ -278,6 +324,7 @@ namespace video
video::ITexture* RenderTargetTexture; video::ITexture* RenderTargetTexture;
video::IImage* RenderTargetSurface; video::IImage* RenderTargetSurface;
core::dimension2d<u32> RenderTargetSize; core::dimension2d<u32> RenderTargetSize;
sVec4 RatioRenderTargetScreen; // Smaller Render Target
IBurningShader* CurrentShader; IBurningShader* CurrentShader;
IBurningShader* BurningShader[ETR2_COUNT]; IBurningShader* BurningShader[ETR2_COUNT];
@ -302,6 +349,8 @@ namespace video
ETS_COUNT_BURNING = 16 ETS_COUNT_BURNING = 16
}; };
// align manually to 16 byte start address
//u8 _pack_0[8];
enum E_TRANSFORMATION_FLAG enum E_TRANSFORMATION_FLAG
{ {
ETF_VALID = 1, ETF_VALID = 1,
@ -311,12 +360,12 @@ namespace video
ETF_TEXGEN_WRAP = 16, ETF_TEXGEN_WRAP = 16,
ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP
}; };
size_t TransformationStack; // 0 .. 3D , 1 .. 2D
core::matrix4 Transformation[2][ETS_COUNT_BURNING]; core::matrix4 Transformation[2][ETS_COUNT_BURNING];
size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG
size_t TransformationStack; // 0 .. 3D , 1 .. 2D
void setRenderStates2DMode(const video::SColor& color,video::ITexture* texture,bool useAlphaChannelOfTexture); void setRenderStates2DMode(const video::SColor& color,const video::ITexture* texture,bool useAlphaChannelOfTexture);
void setRenderStates3DMode(); void setRenderStates3DMode();
//ETS_CLIPSCALE, // moved outside to stay at 16 matrices //ETS_CLIPSCALE, // moved outside to stay at 16 matrices
@ -366,7 +415,7 @@ namespace video
//const is misleading. **v is const that true, but not *v.. //const is misleading. **v is const that true, but not *v..
f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const; 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; s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, const f32 dc_area, const f32 lod_bias ) const;
void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const; void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;
void getCameraPosWorldSpace(); void getCameraPosWorldSpace();
@ -377,6 +426,20 @@ namespace video
//! Built-in 2D quad for 2D rendering. //! Built-in 2D quad for 2D rendering.
S3DVertex Quad2DVertices[4]; S3DVertex Quad2DVertices[4];
interlaced_control Interlaced;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
core::array<IRenderTarget*> RenderTargets;
inline bool getWriteZBuffer(const SMaterial& material) const
{
return material.ZWriteEnable && (AllowZWriteOnTransparent || !material.isTransparent());
}
virtual video::ITexture* createDeviceDependentTexture(IImage* surface, const io::path& name, void* mipmapData = 0)
{
return createDeviceDependentTexture(name, surface);
}
#endif
}; };

@ -20,6 +20,30 @@ namespace video
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB) //! 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, size_t flags); void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect, size_t flags);
//nearest pow of 2 ( 257 will be 256 not 512 )
static inline core::dimension2d<u32> getOptimalSize(const core::dimension2d<u32>& original, const u32 allowNonPowerOfTwo, const u32 maxSize)
{
u32 w, h;
if (allowNonPowerOfTwo)
{
w = original.Width;
h = original.Height;
}
else
{
w = 1;
while (w * 2 < original.Width) w *= 2;
if (w * 2 - original.Width < original.Width - w) w *= 2;
h = 1;
while (h * 2 < original.Height) h *= 2;
if (h * 2 - original.Height < original.Height - h) h *= 2;
}
if (maxSize && w > maxSize) w = maxSize;
if (maxSize && h > maxSize) h = maxSize;
return core::dimension2d<u32>(w, h);
}
//! constructor //! constructor
CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver) CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver)
: ITexture(name : ITexture(name
@ -27,24 +51,24 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
, ETT_2D , ETT_2D
#endif #endif
) )
,MipMapLOD(0), Flags(flags), Driver(driver) , MipMapLOD(0), Flags(flags), Driver(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSoftwareTexture2"); setDebugName("CSoftwareTexture2");
#endif #endif
#ifndef SOFTWARE_DRIVER_2_MIPMAPPING #if SOFTWARE_DRIVER_2_MIPMAPPING_MAX <= 1
Flags &= ~(GEN_MIPMAP| GEN_MIPMAP_AUTO); Flags &= ~(GEN_MIPMAP | GEN_MIPMAP_AUTO);
#endif #endif
//set baseclass properties //set baseclass properties
DriverType = EDT_BURNINGSVIDEO; DriverType = EDT_BURNINGSVIDEO;
ColorFormat = BURNINGSHADER_COLOR_FORMAT; ColorFormat = (Flags & IS_RENDERTARGET) ? SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT : SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT;
IsRenderTarget = (Flags & IS_RENDERTARGET) != 0; IsRenderTarget = (Flags & IS_RENDERTARGET) != 0;
HasMipMaps = (Flags & GEN_MIPMAP) != 0; HasMipMaps = (Flags & GEN_MIPMAP) != 0;
MipMap0_Area[0] = 1; MipMap0_Area[0] = 1;
MipMap0_Area[1] = 1; MipMap0_Area[1] = 1;
LodBIAS = 0.75f; LodBIAS = 1.f;
for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) MipMap[i] = 0; for (size_t i = 0; i < array_size(MipMap); ++i) MipMap[i] = 0;
if (!image) return; if (!image) return;
OriginalSize = image->getDimension(); OriginalSize = image->getDimension();
@ -52,7 +76,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
if ( Flags & IMAGE_IS_LINEAR ) image->set_sRGB(0); if (Flags & IMAGE_IS_LINEAR) image->set_sRGB(0);
#else #else
//guessing linear image //guessing linear image
if (name.find("light") >= 0 || if (name.find("light") >= 0 ||
@ -72,47 +96,65 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
//visual studio code warning //visual studio code warning
u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE; u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE;
core::dimension2d<u32> optSize( OriginalSize.getOptimalSize(
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
if (IsRenderTarget && name.find("RaceGUI::markers") >= 0)
{
maxTexSize = 0;
}
#endif
/*
core::dimension2d<u32> optSize(OriginalSize.getOptimalSize(
(Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo (Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo
false, // requireSquare false, // requireSquare
(Flags & ALLOW_NPOT) ? 1 : maxTexSize == 0, // larger (Flags & ALLOW_NPOT) ? 1 : maxTexSize == SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, // larger
(Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue (Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue
) )
); );
*/
core::dimension2d<u32> optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize));
if (OriginalSize == optSize) if (OriginalSize == optSize)
{ {
MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension()); MipMap[0] = new CImage(ColorFormat, image->getDimension());
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() ); MipMap[0]->set_sRGB((Flags & TEXTURE_IS_LINEAR) ? 0 : image->get_sRGB());
#endif #endif
if (!isCompressed) if (!isCompressed && image->getData())
image->copyTo(MipMap[0]); image->copyTo(MipMap[0]);
} }
else else
{ {
char buf[256]; MipMap[0] = new CImage(ColorFormat, optSize);
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, OriginalColorFormat,
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) #if defined(IRRLICHT_sRGB)
MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB() ); MipMap[0]->set_sRGB((Flags & TEXTURE_IS_LINEAR) ? 0 : image->get_sRGB());
#endif #endif
if (!isCompressed) if (!isCompressed)
{ {
//image->copyToScalingBoxFilter ( MipMap[0],0, false ); //image->copyToScalingBoxFilter ( MipMap[0],0, false );
Resample_subSampling(BLITTER_TEXTURE,MipMap[0],0,image,0, Flags); Resample_subSampling(BLITTER_TEXTURE, MipMap[0], 0, image, 0, Flags);
} }
// if Original Size is used for calculation ( 2D position, font) it will be wrong // if Original Size is used for calculation ( 2D position, font) it will be wrong
//OriginalSize = optSize; //OriginalSize = optSize;
} }
// Show Information about resizing
if (OriginalSize != optSize ||
( OriginalColorFormat != ColorFormat &&
!((OriginalColorFormat == ECF_R8G8B8 || OriginalColorFormat == ECF_A1R5G5B5) && ColorFormat == ECF_A8R8G8B8)
)
)
{
char buf[256];
core::stringw showName(name);
snprintf_irr(buf, sizeof(buf), "Burningvideo: Texture '%ls' reformat %ux%u,%s -> %ux%u,%s",
showName.c_str(),
OriginalSize.Width, OriginalSize.Height, ColorFormatNames[OriginalColorFormat],
optSize.Width, optSize.Height, ColorFormatNames[ColorFormat]
);
os::Printer::log(buf, ELL_DEBUG);
}
//select highest mipmap 0 //select highest mipmap 0
regenerateMipMapLevels(image->getMipMapsData()); regenerateMipMapLevels(image->getMipMapsData());
} }
@ -121,9 +163,9 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
//! destructor //! destructor
CSoftwareTexture2::~CSoftwareTexture2() CSoftwareTexture2::~CSoftwareTexture2()
{ {
for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) for (size_t i = 0; i < array_size(MipMap); ++i)
{ {
if ( MipMap[i] ) if (MipMap[i])
{ {
MipMap[i]->drop(); MipMap[i]->drop();
MipMap[i] = 0; MipMap[i] = 0;
@ -132,7 +174,6 @@ CSoftwareTexture2::~CSoftwareTexture2()
} }
//! Regenerates the mip map levels of the texture. Useful after locking and //! Regenerates the mip map levels of the texture. Useful after locking and
//! modifying the texture //! modifying the texture
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
@ -144,9 +185,9 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
int i; int i;
// release // release
for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) for (i = 1; i < array_size(MipMap); ++i)
{ {
if ( MipMap[i] ) if (MipMap[i])
{ {
MipMap[i]->drop(); MipMap[i]->drop();
MipMap[i] = 0; MipMap[i] = 0;
@ -155,10 +196,10 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
core::dimension2d<u32> newSize; core::dimension2d<u32> newSize;
if (HasMipMaps && ( (Flags & GEN_MIPMAP_AUTO) || 0 == data ) ) if (HasMipMaps && ((Flags & GEN_MIPMAP_AUTO) || 0 == data))
{ {
//need memory also if autogen mipmap disabled //need memory also if autogen mipmap disabled
for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i) for (i = 1; i < array_size(MipMap); ++i)
{ {
const core::dimension2du& upperDim = MipMap[i - 1]->getDimension(); const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
//isotropic //isotropic
@ -167,7 +208,7 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
if (upperDim == newSize) if (upperDim == newSize)
break; break;
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); MipMap[i] = new CImage(ColorFormat, newSize);
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB()); MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB());
#endif #endif
@ -192,13 +233,13 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
if (origSize.Height > 1) origSize.Height >>= 1; if (origSize.Height > 1) origSize.Height >>= 1;
mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height); mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);
i += 1; i += 1;
} while ((origSize.Width != 1 || origSize.Height != 1) && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX); } while ((origSize.Width != 1 || origSize.Height != 1) && i < array_size(MipMap));
//TODO: this is not true //TODO: this is not true
LodBIAS = i*0.75f; LodBIAS = i * 2.f;
origSize = OriginalSize; origSize = OriginalSize;
for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX && mip_current < mip_end; ++i) for (i = 1; i < array_size(MipMap) && mip_current < mip_end; ++i)
{ {
const core::dimension2du& upperDim = MipMap[i - 1]->getDimension(); const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();
//isotropic //isotropic
@ -210,10 +251,10 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
if (origSize.Width > 1) origSize.Width >>= 1; if (origSize.Width > 1) origSize.Width >>= 1;
if (origSize.Height > 1) origSize.Height >>= 1; if (origSize.Height > 1) origSize.Height >>= 1;
if (OriginalColorFormat != BURNINGSHADER_COLOR_FORMAT) if (OriginalColorFormat != ColorFormat)
{ {
IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false); IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false);
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); MipMap[i] = new CImage(ColorFormat, newSize);
if (origSize == newSize) if (origSize == newSize)
tmpImage->copyTo(MipMap[i]); tmpImage->copyTo(MipMap[i]);
else else
@ -223,11 +264,11 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
else else
{ {
if (origSize == newSize) if (origSize == newSize)
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mip_current, false); MipMap[i] = new CImage(ColorFormat, newSize, mip_current, false);
else else
{ {
MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize); MipMap[i] = new CImage(ColorFormat, newSize);
IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mip_current, true, false); IImage* tmpImage = new CImage(ColorFormat, origSize, mip_current, true, false);
tmpImage->copyToScalingBoxFilter(MipMap[i]); tmpImage->copyToScalingBoxFilter(MipMap[i]);
tmpImage->drop(); tmpImage->drop();
} }
@ -238,33 +279,33 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
//visualize mipmap //visualize mipmap
for (i=1; i < 0 && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i) for (i = 1; i < 0 && i < array_size(MipMap); ++i)
{ {
/*
static u32 color[] = { static u32 color[] = {
0x30bf7f00,0x3040bf00,0x30bf00bf,0x3000bf00, 0xFFFF0000,
0x300080bf,0x30bf4000,0x300040bf,0x307f00bf, 0xFFFF0000,0xFF00FF00,0xFF0000FF,
0x30bf0000,0x3000bfbf,0x304000bf,0x307fbf00, 0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,
0x8000bf7f,0x80bf0040,0x80bfbf00,0x800000bf 0xFFff6600,0xFF00ff66,0xFF6600FF,
}; 0xFF66ff00,0xFF0066ff,0xFFff0066,
*/ 0xFF33ff00,0xFF0033ff,0xFF3300ff,
static u32 color[] = { 0xFF0000FF,0xFF0000FF,0xFF0000FF
0xFFFFFFFF,0xFFFF0000,0xFF00FF00,0xFF0000FF,
0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,0xFF0000FF,
0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFF0000FF,
0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFFFF00FF
}; };
if ( MipMap[i] ) if (MipMap[i])
{ {
core::rect<s32> p (core::position2di(0,0),MipMap[i]->getDimension()); int border = 0;
const core::dimension2du& d = MipMap[i]->getDimension();
core::rect<s32> p(0, 0, d.Width, d.Height);
SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000); SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);
Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], 0, 0, MipMap[i], &p, c.color);
core::rect<s32> dclip(border, border, d.Width - border, d.Height - border);
Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], &dclip, 0, MipMap[i], &p, c.color);
} }
} }
//save mipmap chain //save mipmap chain
if ( 0 ) if (0)
{ {
char buf[256]; char buf[256];
const char* name = getName().getPath().c_str(); const char* name = getName().getPath().c_str();
@ -277,11 +318,11 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
//if (name[i] == '.') ext = i; //if (name[i] == '.') ext = i;
i += 1; i += 1;
} }
for (i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i) for (i = 0; i < array_size(MipMap); ++i)
{ {
if (MipMap[i]) if (MipMap[i])
{ {
snprintf_irr(buf, sizeof(buf),"mip/%s_%02d.png", name + filename,i); snprintf_irr(buf, sizeof(buf), "mip/%s_%02d.png", name + filename, i);
Driver->writeImageToFile(MipMap[i], buf); Driver->writeImageToFile(MipMap[i], buf);
} }
} }
@ -300,12 +341,16 @@ void CSoftwareTexture2::calcDerivative()
MipMap0_Area[0] = dim.Width; MipMap0_Area[0] = dim.Width;
MipMap0_Area[1] = dim.Height; // screensize of a triangle MipMap0_Area[1] = dim.Height; // screensize of a triangle
//TA: try to mimic openGL mipmap. ( don't do this!)
//if (MipMap0_Area[0] < 32) MipMap0_Area[0] = 32;
//if (MipMap0_Area[1] < 32) MipMap0_Area[1] = 32;
Size = dim; // MipMap[MipMapLOD]->getDimension(); Size = dim; // MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch(); Pitch = MipMap[MipMapLOD]->getPitch();
} }
//preCalc mipmap texel center boundaries //preCalc mipmap texel center boundaries
for ( s32 i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) for (s32 i = 0; i < array_size(MipMap); ++i)
{ {
CSoftwareTexture2_Bound& b = TexBound[i]; CSoftwareTexture2_Bound& b = TexBound[i];
if (MipMap[i]) if (MipMap[i])
@ -335,7 +380,7 @@ void CSoftwareTexture2::calcDerivative()
CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver) CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver)
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
, IRenderTarget(0) , IRenderTarget(0)
#endif #endif
{ {
DriverType = EDT_BURNINGSVIDEO; DriverType = EDT_BURNINGSVIDEO;
@ -378,12 +423,6 @@ void CSoftwareRenderTarget2::setTexture(const core::array<ITexture*>& texture, I
} }
} }
ITexture* CSoftwareRenderTarget2::getTexture() const
{
return Texture[0];
}
static const float srgb_8bit_to_linear_float[1 << 8] = { static const float srgb_8bit_to_linear_float[1 << 8] = {
0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f, 0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f,
@ -474,7 +513,7 @@ u32 linear_to_srgb_8bit(const float v)
ieee754 c; ieee754 c;
c.f = v; c.f = v;
const size_t x = c.u; const size_t x = c.u;
const u32 *table = (u32*)srgb_8bit_to_linear_float; const u32* table = (u32*)srgb_8bit_to_linear_float;
u32 y = 0; u32 y = 0;
y += table[y + 128] <= x ? 128 : 0; y += table[y + 128] <= x ? 128 : 0;
y += table[y + 64] <= x ? 64 : 0; y += table[y + 64] <= x ? 64 : 0;
@ -497,7 +536,7 @@ struct absrect2
s32 y1; s32 y1;
}; };
static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2& b) static inline int clipTest(absrect2& o, const core::rect<s32>* a, const absrect2& b)
{ {
if (a == 0) if (a == 0)
{ {
@ -522,19 +561,19 @@ static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2
//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB) //! 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) // todo: texture jumps (mip selection problem)
void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect,
const video::IImage* src, const core::rect<s32>* srcRect,size_t flags) const video::IImage* src, const core::rect<s32>* srcRect, size_t flags)
{ {
u8* dstData = (u8*)dst->getData();
const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height }; const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height };
absrect2 dc; absrect2 dc;
if (clipTest(dc, dstRect, dst_clip)) return; if (clipTest(dc, dstRect, dst_clip) || !dstData) return;
const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat(); const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat();
u8* dstData = (u8*)dst->getData();
const u8* srcData = (u8*)src->getData();
const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height }; const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height };
absrect2 sc; absrect2 sc;
if (clipTest(sc, srcRect, src_clip)) return; if (clipTest(sc, srcRect, src_clip) || !srcData) return;
const video::ECOLOR_FORMAT srcFormat = src->getColorFormat(); const video::ECOLOR_FORMAT srcFormat = src->getColorFormat();
const u8* srcData = (u8*)src->getData();
#if defined(IRRLICHT_sRGB) #if defined(IRRLICHT_sRGB)
const int dst_sRGB = dst->get_sRGB(); const int dst_sRGB = dst->get_sRGB();
@ -560,14 +599,14 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
for (int dy = dc.y0; dy < dc.y1; ++dy) for (int dy = dc.y0; dy < dc.y1; ++dy)
{ {
f[1] = f[3]; f[1] = f[3];
f[3] = sc.y0 + (dy + 1 - dc.y0)*scale[1]; 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 if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough
f[2] = (float)sc.x0; f[2] = (float)sc.x0;
for (int dx = dc.x0; dx < dc.x1; ++dx) for (int dx = dc.x0; dx < dc.x1; ++dx)
{ {
f[0] = f[2]; f[0] = f[2];
f[2] = sc.x0 + (dx + 1 - dc.x0)*scale[0]; f[2] = sc.x0 + (dx + 1 - dc.x0) * scale[0];
if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f; if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;
//accumulate linear color //accumulate linear color
@ -599,12 +638,12 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
switch (srcFormat) switch (srcFormat)
{ {
case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break; 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_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_A8R8G8B8: sbgra = *(u32*)(srcData + (fy * src_clip.x1) * 4 + (fx * 4)); break;
case video::ECF_R8G8B8: case video::ECF_R8G8B8:
{ {
const u8* p = srcData + (fy*src_clip.x1) * 3 + (fx * 3); const u8* p = srcData + (fy * src_clip.x1) * 3 + (fx * 3);
sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2]; sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2];
} break; } break;
default: break; default: break;
@ -650,16 +689,16 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
} }
switch (dstFormat) switch (dstFormat)
{ {
case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy*dst_clip.x1) * 4 + (dx * 4)) = sbgra; break; case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy * dst_clip.x1) * 4 + (dx * 4)) = sbgra; break;
case video::ECF_R8G8B8: case video::ECF_R8G8B8:
{ {
u8* p = dstData + (dy*dst_clip.x1) * 3 + (dx * 3); u8* p = dstData + (dy * dst_clip.x1) * 3 + (dx * 3);
p[2] = (sbgra) & 0xFF; p[2] = (sbgra) & 0xFF;
p[1] = (sbgra >> 8) & 0xFF; p[1] = (sbgra >> 8) & 0xFF;
p[0] = (sbgra >> 16) & 0xFF; p[0] = (sbgra >> 16) & 0xFF;
} break; } break;
case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); 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; case video::ECF_R5G6B5: *(u16*)(dstData + (dy * dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break;
default: default:
break; break;
} }

@ -8,7 +8,11 @@
#include "SoftwareDriver2_compile_config.h" #include "SoftwareDriver2_compile_config.h"
#include "ITexture.h" #include "ITexture.h"
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#include "IVideoDriver.h"
#else
#include "IRenderTarget.h" #include "IRenderTarget.h"
#endif
#include "CImage.h" #include "CImage.h"
namespace irr namespace irr
@ -51,14 +55,18 @@ public:
u32 getMipmapLevel(s32 newLevel) const u32 getMipmapLevel(s32 newLevel) const
{ {
if ( newLevel < 0 ) newLevel = 0; if ( newLevel < 0 ) newLevel = 0;
else if ( newLevel >= SOFTWARE_DRIVER_2_MIPMAPPING_MAX ) newLevel = SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1; else if ( newLevel >= array_size(MipMap)) newLevel = array_size(MipMap) - 1;
while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1; while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1;
return newLevel; return newLevel;
} }
//! lock function //! lock function
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
#else
virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_ virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_
#endif
{ {
if (Flags & GEN_MIPMAP) if (Flags & GEN_MIPMAP)
{ {
@ -75,18 +83,20 @@ public:
virtual void unlock() _IRR_OVERRIDE_ virtual void unlock() _IRR_OVERRIDE_
{ {
} }
/*
//! compare the area drawn with the area of the texture //! compare the area drawn with the area of the texture
f32 getLODFactor( const f32 texArea ) const f32 getLODFactor( const f32 texArea ) const
{ {
return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea; return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;
//return MipMap[0]->getImageDataSizeInPixels () * texArea; //return MipMap[0]->getImageDataSizeInPixels () * texArea;
} }
*/
const u32* getMipMap0_Area() const const u32* getMipMap0_Area() const
{ {
return MipMap0_Area; return MipMap0_Area;
} }
f32 get_lod_bias() const { return LodBIAS; }
//! returns unoptimized surface (misleading name. burning can scale down originalimage) //! returns unoptimized surface (misleading name. burning can scale down originalimage)
virtual CImage* getImage() const virtual CImage* getImage() const
@ -106,9 +116,33 @@ public:
return TexBound[MipMapLOD]; return TexBound[MipMapLOD];
} }
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_; virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;
#else
virtual void regenerateMipMapLevels(void* data = 0);
#endif
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; };
const core::dimension2d<u32>& getSize() const { return Size; };
E_DRIVER_TYPE getDriverType() const { return DriverType; };
ECOLOR_FORMAT getColorFormat() const { return ColorFormat; };
ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; };
u32 getPitch() const { return Pitch; };
bool hasMipMaps() const { return HasMipMaps; }
bool isRenderTarget() const { return IsRenderTarget; }
core::dimension2d<u32> OriginalSize;
core::dimension2d<u32> Size;
E_DRIVER_TYPE DriverType;
ECOLOR_FORMAT OriginalColorFormat;
ECOLOR_FORMAT ColorFormat;
u32 Pitch;
bool HasMipMaps;
bool IsRenderTarget;
#endif
f32 get_lod_bias() const { return LodBIAS; }
private: private:
void calcDerivative(); void calcDerivative();
@ -120,7 +154,7 @@ private:
CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX]; CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX]; CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];
u32 MipMap0_Area[2]; u32 MipMap0_Area[2];
f32 LodBIAS; f32 LodBIAS; // Tweak mipmap selection
}; };
/*! /*!
@ -134,7 +168,10 @@ public:
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_; virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil, const core::array<E_CUBE_SURFACE>& cubeSurfaces) _IRR_OVERRIDE_;
ITexture* getTexture() const; #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
E_DRIVER_TYPE DriverType;
core::array<ITexture*> Texture;
#endif
protected: protected:
CBurningVideoDriver* Driver; CBurningVideoDriver* Driver;

@ -87,7 +87,7 @@ public:
//virtual bool canWireFrame () { return true; } //virtual bool canWireFrame () { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
}; };
@ -104,7 +104,7 @@ CTRGouraud2::CTRGouraud2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraud2::scanline_bilinear () void CTRGouraud2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -143,7 +143,7 @@ void CTRGouraud2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -196,10 +196,11 @@ void CTRGouraud2::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
//if test active only first pixel //if test active only first pixel
if ( (0 == EdgeTestPass) & i ) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
#endif #endif
@ -384,8 +385,9 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -416,7 +418,7 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -511,7 +513,6 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -545,8 +546,9 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -577,7 +579,7 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -88,7 +88,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -105,7 +105,7 @@ CTRGouraudAlpha2::CTRGouraudAlpha2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraudAlpha2::scanline_bilinear () void CTRGouraudAlpha2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -148,7 +148,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -204,7 +204,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -270,9 +270,9 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -397,7 +397,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -428,7 +428,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -522,7 +522,6 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -557,7 +556,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -588,7 +587,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -88,7 +88,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
//! constructor //! constructor
@ -104,7 +104,7 @@ CTRGouraudAlphaNoZ2::CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraudAlphaNoZ2::scanline_bilinear () void CTRGouraudAlphaNoZ2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -144,7 +144,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -201,7 +201,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -271,9 +271,9 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -397,7 +397,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -428,7 +428,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -557,7 +557,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -588,7 +588,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -87,7 +87,7 @@ public:
virtual bool canWireFrame () { return true; } virtual bool canWireFrame () { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
}; };
//! constructor //! constructor
@ -103,7 +103,7 @@ CTRGouraudNoZ2::CTRGouraudNoZ2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGouraudNoZ2::scanline_bilinear () void CTRGouraudNoZ2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -142,7 +142,7 @@ void CTRGouraudNoZ2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -195,9 +195,9 @@ void CTRGouraudNoZ2::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
if ( (0 == EdgeTestPass) & i ) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -383,8 +383,10 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -415,7 +417,7 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -509,7 +511,6 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -542,9 +543,10 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -575,7 +577,7 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -164,7 +164,7 @@ void CTRNormalMap::fragmentShader()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -254,7 +254,7 @@ void CTRNormalMap::fragmentShader()
#endif #endif
for ( s32 i = 0; i <= dx; i++ ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -400,9 +400,9 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -572,7 +572,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -618,7 +618,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -751,7 +751,6 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -801,7 +800,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -847,7 +846,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// render a scanline // render a scanline
fragmentShader(); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -139,7 +139,7 @@ void CTRStencilShadow::fragmentShader()
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -174,7 +174,7 @@ void CTRStencilShadow::fragmentShader()
#endif #endif
s32 i; s32 i;
for (i = 0; i <= dx; i++) for (i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
@ -226,9 +226,9 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -382,7 +382,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -423,7 +423,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -545,7 +545,6 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -590,7 +589,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -631,7 +630,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -87,22 +87,6 @@ namespace video
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict 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 OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1)
virtual void setZCompareFunc(u32 func)
{
depth_func = (E_COMPARISON_FUNC)func;
}
virtual void setParam(u32 index, f32 value)
{
SBurningShaderMaterial material;
material.org.ZBuffer = depth_func;
material.org.MaterialTypeParam = value;
OnSetMaterial(material);
}
#endif
private: private:
// fragment shader // fragment shader
typedef void (CTRTextureBlend::*tFragmentShader) (); typedef void (CTRTextureBlend::*tFragmentShader) ();
@ -269,7 +253,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -325,7 +309,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -368,7 +352,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -454,7 +438,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -514,7 +498,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -561,7 +545,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -649,7 +633,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2 ( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -707,7 +691,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -757,7 +741,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -850,7 +834,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -908,7 +892,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -957,7 +941,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1050,7 +1034,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1108,7 +1092,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1174,7 +1158,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1280,7 +1264,7 @@ void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1337,7 +1321,7 @@ void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for (i = 0; i <= dx; ++i) for (i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if (line.w[0] >= z[i]) if (line.w[0] >= z[i])
@ -1434,7 +1418,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1492,7 +1476,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1541,7 +1525,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1633,7 +1617,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1691,7 +1675,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1739,7 +1723,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -1830,7 +1814,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -1888,7 +1872,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -1937,7 +1921,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -2030,7 +2014,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -2088,7 +2072,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
{ {
default: default:
case ECFN_LESSEQUAL: case ECFN_LESSEQUAL:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -2137,7 +2121,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
break; break;
case 2: case 2:
for ( i = 0; i <= dx; ++i ) for ( i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] == z[i] ) if ( line.w[0] == z[i] )
@ -2202,9 +2186,9 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -2328,7 +2312,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -2359,7 +2343,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// render a scanline // render a scanline
(this->*fragmentShader) (); interlace_scanline (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -2453,7 +2437,6 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -2488,7 +2471,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -2519,7 +2502,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// render a scanline // render a scanline
(this->*fragmentShader) (); interlace_scanline (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -88,7 +88,7 @@ public:
virtual bool canWireFrame () { return true; } virtual bool canWireFrame () { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
}; };
@ -105,7 +105,7 @@ CTRTextureDetailMap2::CTRTextureDetailMap2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRTextureDetailMap2::scanline_bilinear () void CTRTextureDetailMap2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -140,12 +140,11 @@ void CTRTextureDetailMap2::scanline_bilinear ()
xEnd = fill_convention_right( line.x[1] ); xEnd = fill_convention_right( line.x[1] );
dx = xEnd - xStart; dx = xEnd - xStart;
if ( dx < 0 ) if ( dx < 0 )
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -200,9 +199,9 @@ void CTRTextureDetailMap2::scanline_bilinear ()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
if ( (0 == EdgeTestPass) & i ) break; if ( (0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -326,7 +325,7 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// rasterize upper sub-triangle // rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] ) if (F32_GREATER_0(scan.invDeltaY[1]) )
{ {
// calculate slopes for top edge // calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@ -394,9 +393,10 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -427,7 +427,8 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if (EdgeTestPass & edge_test_first_line) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -461,10 +462,10 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] ) if (F32_GREATER_0(scan.invDeltaY[2]) )
{ {
// advance to middle point // 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 temp[0] = b->Pos.y - a->Pos.y; // dy
@ -521,7 +522,6 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -555,8 +555,10 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -587,7 +589,8 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
if (EdgeTestPass & edge_test_first_line) break;
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -167,7 +167,7 @@ void CTRTextureGouraud2::fragmentShader ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -254,10 +254,10 @@ void CTRTextureGouraud2::fragmentShader ()
u32 dIndex = ( line.y & 3 ) << 2; u32 dIndex = ( line.y & 3 ) << 2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
//if test active only first pixel //if test active only first pixel
if ( (0 == EdgeTestPass) & i ) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -382,9 +382,9 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -551,9 +551,10 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -599,7 +600,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
@ -734,7 +735,6 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -761,7 +761,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
scan.c[1][1] += scan.slopeC[1][1] * subPixel; scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif #endif
#ifdef IPOL_C1 #ifdef IPOL_C2
scan.c[2][0] += scan.slopeC[2][0] * subPixel; scan.c[2][0] += scan.slopeC[2][0] * subPixel;
scan.c[2][1] += scan.slopeC[2][1] * subPixel; scan.c[2][1] += scan.slopeC[2][1] * subPixel;
#endif #endif
@ -782,9 +782,10 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -830,7 +831,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// render a scanline // render a scanline
fragmentShader (); interlace_scanline fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;

@ -88,7 +88,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
//! constructor //! constructor
@ -104,7 +104,7 @@ CTRTextureGouraudAdd2::CTRTextureGouraudAdd2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRTextureGouraudAdd2::scanline_bilinear () void CTRTextureGouraudAdd2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -144,7 +144,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -203,7 +203,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -280,9 +280,9 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
// find if the major edge is left or right aligned // find if the major edge is left or right aligned
f32 temp[4]; f32 temp[4];
@ -403,7 +403,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -434,7 +434,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -563,7 +563,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -594,7 +594,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -143,7 +143,7 @@ void CTRTextureGouraudAddNoZ2::fragmentShader()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -200,7 +200,7 @@ void CTRTextureGouraudAddNoZ2::fragmentShader()
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -275,9 +275,9 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -401,7 +401,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -432,7 +432,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
fragmentShader(); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -526,7 +526,6 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -561,7 +560,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -592,7 +591,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
fragmentShader( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -88,7 +88,7 @@ public:
virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_; virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -115,7 +115,7 @@ void CTRTextureGouraudAlpha2::OnSetMaterial(const SBurningShaderMaterial& materi
/*! /*!
*/ */
void CTRTextureGouraudAlpha2::scanline_bilinear () void CTRTextureGouraudAlpha2::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -155,7 +155,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -213,7 +213,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
#endif #endif
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -337,9 +337,9 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -463,7 +463,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -494,7 +494,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -588,7 +588,6 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -623,7 +622,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -654,7 +653,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -93,20 +93,6 @@ public:
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict 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 OnSetMaterial(const SBurningShaderMaterial& material) _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: private:
// fragment shader // fragment shader
@ -198,7 +184,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -268,7 +254,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
tFixPoint a3,r3, g3, b3; tFixPoint a3,r3, g3, b3;
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -276,7 +262,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
#endif #endif
scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -418,7 +404,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -488,7 +474,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
tFixPoint a3, r3, g3, b3; tFixPoint a3, r3, g3, b3;
#endif #endif
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
@ -496,7 +482,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
#ifdef CMP_W #ifdef CMP_W
if (line.w[0] >= z[i]) if (line.w[0] >= z[i])
#endif #endif
scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -639,7 +625,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -708,15 +694,15 @@ void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
#ifdef IPOL_C1 #ifdef IPOL_C1
tFixPoint a3, r3, g3, b3; tFixPoint a3, r3, g3, b3;
#endif #endif
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) //if (line.z[0] < z[i])
#endif #endif
#ifdef CMP_W #ifdef CMP_W
// if (line.w[0] >= z[i]) // if (line.w[0] >= z[i])
#endif #endif
scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -827,9 +813,9 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -968,7 +954,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -1004,6 +990,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// render a scanline // render a scanline
interlace_scanline
scissor_test_y
(this->*fragmentShader) (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -1112,7 +1100,6 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -1152,7 +1139,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -1188,6 +1175,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// render a scanline // render a scanline
interlace_scanline
scissor_test_y
(this->*fragmentShader) (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -89,11 +89,16 @@ public:
//! draws an indexed triangle list //! 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 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: private:
void scanline_bilinear ();
// fragment shader
typedef void (CTRTextureGouraudNoZ2::* tFragmentShader) ();
void fragment_bilinear();
void fragment_no_filter();
tFragmentShader fragmentShader;
}; };
//! constructor //! constructor
@ -103,13 +108,32 @@ CTRTextureGouraudNoZ2::CTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTRTextureGouraudNoZ2"); setDebugName("CTRTextureGouraudNoZ2");
#endif #endif
fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear;
} }
/*! /*!
*/ */
void CTRTextureGouraudNoZ2::scanline_bilinear ( ) void CTRTextureGouraudNoZ2::OnSetMaterial(const SBurningShaderMaterial& material)
{
if (material.org.TextureLayer[0].BilinearFilter ||
material.org.TextureLayer[0].TrilinearFilter ||
material.org.TextureLayer[0].AnisotropicFilter
)
{
fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear;
}
else
{
fragmentShader = &CTRTextureGouraudNoZ2::fragment_no_filter;
}
}
/*!
*/
void CTRTextureGouraudNoZ2::fragment_bilinear()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -149,7 +173,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -168,7 +192,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#endif #endif
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0]; subPixel = ((f32) xStart) - line.x[0];
#ifdef IPOL_Z #ifdef IPOL_Z
line.z[0] += slopeZ * subPixel; line.z[0] += slopeZ * subPixel;
#endif #endif
@ -200,7 +224,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
tFixPoint ty0; tFixPoint ty0;
tFixPoint r0, g0, b0; tFixPoint r0, g0, b0;
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -208,7 +232,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
#endif #endif
scissor_test_x
{ {
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] ); inversew = fix_inverse32 ( line.w[0] );
@ -248,6 +272,146 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
} }
/*!
*/
void CTRTextureGouraudNoZ2::fragment_no_filter()
{
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 = fill_step_x(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[1] - line.c[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] += 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 tx0;
tFixPoint ty0;
//tFixPoint r0, g0, b0;
for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{
#ifdef CMP_Z
if (line.z[0] < z[i])
#endif
#ifdef CMP_W
if (line.w[0] >= z[i])
#endif
//scissor_test_x
{
#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);
//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 );
#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] += slopeC;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
#endif
}
}
void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{ {
// sort on height, y // sort on height, y
@ -258,10 +422,11 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
const f32 ca = c->Pos.y - a->Pos.y; const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -315,7 +480,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize upper sub-triangle // rasterize upper sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[1] ) if (F32_GREATER_0(scan.invDeltaY[1]) )
{ {
// calculate slopes for top edge // calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1]; scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@ -385,7 +550,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -415,8 +580,11 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
line.t[1][scan.right] = scan.t[1][1]; line.t[1][scan.right] = scan.t[1][1];
#endif #endif
// render a scanline // render a scanline
scanline_bilinear ( ); interlace_scanline
scissor_test_y
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -450,10 +618,10 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if ( (f32) 0.0 != scan.invDeltaY[2] ) if (F32_GREATER_0(scan.invDeltaY[2]) )
{ {
// advance to middle point // 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 temp[0] = b->Pos.y - a->Pos.y; // dy
@ -545,7 +713,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -576,7 +744,9 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline
scissor_test_y
(this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -93,7 +93,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -110,7 +110,7 @@ CTRTextureVertexAlpha2::CTRTextureVertexAlpha2(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRTextureVertexAlpha2::scanline_bilinear ( ) void CTRTextureVertexAlpha2::fragmentShader( )
{ {
tVideoSample *dst; tVideoSample *dst;
@ -150,7 +150,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -219,7 +219,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear ( )
#endif #endif
for ( s32 i = 0; i <= dx; ++i ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -332,9 +332,9 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -473,7 +473,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -509,7 +509,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -656,7 +656,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -692,7 +692,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -86,7 +86,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -103,7 +103,7 @@ CTRTextureLightMap2_Add::CTRTextureLightMap2_Add(CBurningVideoDriver* driver)
/*! /*!
*/ */
REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear () REALINLINE void CTRTextureLightMap2_Add::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -143,7 +143,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -199,7 +199,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
#endif #endif
for ( s32 i = 0; i <= dx; i++ ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -274,9 +274,9 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -400,7 +400,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -431,7 +431,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -560,7 +560,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -591,7 +591,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -121,7 +121,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -193,7 +193,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
#endif #endif
for ( ;i <= dx; i++ ) for ( ;i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef IPOL_W #ifdef IPOL_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -255,9 +255,9 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -381,7 +381,7 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -542,7 +542,7 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];

@ -121,7 +121,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -254,9 +254,9 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -380,7 +380,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -411,7 +411,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2 (); interlace_scanline scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -541,7 +541,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -572,7 +572,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2 (); interlace_scanline scanline_bilinear2 ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -93,10 +93,10 @@ private:
void scanline_bilinear2_mag (); void scanline_bilinear2_mag ();
void scanline_bilinear2_min (); void scanline_bilinear2_min ();
#else #else
#define scanline_bilinear2_mag scanline_bilinear #define scanline_bilinear2_mag fragmentShader
#endif #endif
void scanline_bilinear (); void fragmentShader();
}; };
@ -130,7 +130,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
i = ( line.y * RenderTarget->getDimension().Width ) + xStart; i = ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -202,7 +202,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
#endif #endif
for ( ;i <= dx; i++ ) for ( ;i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef IPOL_W #ifdef IPOL_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -271,7 +271,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
// search z-buffer for first not occulled pixel // search z-buffer for first not occulled pixel
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
@ -334,7 +334,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
tFixPoint r1, g1, b1; tFixPoint r1, g1, b1;
for ( ;i <= dx; i++ ) for ( ;i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef IPOL_W #ifdef IPOL_W
if ( line.w[0] >= z[i] ) if ( line.w[0] >= z[i] )
@ -393,9 +393,9 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -519,7 +519,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -550,7 +550,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_min (); interlace_scanline scanline_bilinear2_min ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -680,7 +680,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -711,7 +711,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_min (); interlace_scanline scanline_bilinear2_min ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -769,9 +769,9 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
return; return;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
//if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) //if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
// return; // return;
@ -896,7 +896,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -927,7 +927,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_mag (); interlace_scanline scanline_bilinear2_mag ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -1057,7 +1057,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -1088,7 +1088,7 @@ void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
scanline_bilinear2_mag (); interlace_scanline scanline_bilinear2_mag ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -86,7 +86,7 @@ public:
private: private:
void scanline_bilinear (); void fragmentShader();
}; };
@ -103,7 +103,7 @@ CTRGTextureLightMap2_M4::CTRGTextureLightMap2_M4(CBurningVideoDriver* driver)
/*! /*!
*/ */
void CTRGTextureLightMap2_M4::scanline_bilinear () void CTRGTextureLightMap2_M4::fragmentShader()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -143,7 +143,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -201,7 +201,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
tFixPoint r3, g3, b3; tFixPoint r3, g3, b3;
#endif #endif
for ( s32 i = 0; i <= dx; i++ ) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X )
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( line.z[0] < z[i] ) if ( line.z[0] < z[i] )
@ -283,9 +283,9 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_0 ( scan.invDeltaY[0] ) )
return; return;
@ -411,7 +411,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -442,7 +442,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];
@ -573,7 +573,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -604,7 +604,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
scanline_bilinear (); interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1]; scan.x[1] += scan.slopeX[1];

@ -91,7 +91,7 @@ public:
virtual bool canPointCloud() _IRR_OVERRIDE_ { return true; } virtual bool canPointCloud() _IRR_OVERRIDE_ { return true; }
protected: protected:
virtual void scanline_bilinear (); virtual void fragmentShader();
void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const; void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;
void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const; void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const;
@ -114,7 +114,7 @@ CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
*/ */
void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const
{ {
int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY; int pitch0 = RenderTarget->getDimension().Width << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
int pitch1 = RenderTarget->getDimension().Width << 2; int pitch1 = RenderTarget->getDimension().Width << 2;
#endif #endif
@ -138,7 +138,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
fp24 *z; fp24 *z;
#endif #endif
int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY; int xInc0 = 1 << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY;
int yInc0 = pitch0; int yInc0 = pitch0;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
@ -148,7 +148,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
if ( dx < 0 ) if ( dx < 0 )
{ {
xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY); xInc0 = - ( 1 << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY);
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
xInc1 = -4; xInc1 = -4;
#endif #endif
@ -173,7 +173,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
} }
SOFTWARE_DRIVER_2_CLIPCHECK_WIRE; SOFTWARE_DRIVER_2_CLIPCHECK_WIRE;
dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< VIDEO_SAMPLE_GRANULARITY) ) ); dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) ) );
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) ); z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );
#endif #endif
@ -182,7 +182,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
m = dy << 1; m = dy << 1;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( (f32)dx ); const f32 invDeltaX = fill_step_x( (f32)dx );
#ifdef IPOL_Z #ifdef IPOL_Z
f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX; f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX;
@ -283,7 +283,7 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
} }
void CTRTextureWire2::scanline_bilinear() void CTRTextureWire2::fragmentShader()
{ {
} }

@ -149,7 +149,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] ); const f32 invDeltaX = fill_step_x( line.x[1] - line.x[0] );
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -206,7 +206,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
switch(MaterialType) { switch(MaterialType) {
default: default:
case EMT_REFLECTION_2_LAYER: case EMT_REFLECTION_2_LAYER:
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
@ -263,7 +263,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
break; break;
case EMT_TRANSPARENT_REFLECTION_2_LAYER: case EMT_TRANSPARENT_REFLECTION_2_LAYER:
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])
@ -344,9 +344,9 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
const f32 ba = b->Pos.y - a->Pos.y; const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y; const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges // calculate delta y of the edges
scan.invDeltaY[0] = reciprocal_zero( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = reciprocal_zero( ba ); scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = reciprocal_zero( cb ); scan.invDeltaY[2] = fill_step_y( cb );
if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) ) if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
return; return;
@ -470,7 +470,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -501,6 +501,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// render a scanline // render a scanline
interlace_scanline
fragmentShader(); fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -630,7 +631,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// rasterize the edge scanlines // rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; ++line.y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -661,6 +662,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// render a scanline // render a scanline
interlace_scanline
fragmentShader(); fragmentShader();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];

@ -12,29 +12,37 @@
namespace irr namespace irr
{ {
namespace video namespace video
{ {
const tFixPointu IBurningShader::dithermask[] = const tFixPointu IBurningShader::dithermask[] =
{ {
0x00,0x80,0x20,0xa0, 0x00,0x80,0x20,0xa0,
0xc0,0x40,0xe0,0x60, 0xc0,0x40,0xe0,0x60,
0x30,0xb0,0x10,0x90, 0x30,0xb0,0x10,0x90,
0xf0,0x70,0xd0,0x50 0xf0,0x70,0xd0,0x50
}; };
void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver) void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("IBurningShader"); setDebugName("IBurningShader");
#endif #endif
if (((unsigned long long)&scan & 15) || ((unsigned long long)&line & 15))
{
os::Printer::log("BurningVideo Shader not 16 byte aligned", ELL_ERROR);
_IRR_DEBUG_BREAK_IF(1);
}
Interlaced.enable = 0;
Interlaced.bypass = 1;
Interlaced.nr = 0;
EdgeTestPass = edge_test_pass; EdgeTestPass = edge_test_pass;
EdgeTestPass_stack = edge_test_pass; EdgeTestPass_stack = edge_test_pass;
for ( u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i ) for (u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i)
{ {
IT[i].Texture = 0; IT[i].Texture = 0;
} }
@ -44,12 +52,12 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
RenderTarget = 0; RenderTarget = 0;
ColorMask = COLOR_BRIGHT_WHITE; ColorMask = COLOR_BRIGHT_WHITE;
DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer (); DepthBuffer = (CDepthBuffer*)driver->getDepthBuffer();
if ( DepthBuffer ) if (DepthBuffer)
DepthBuffer->grab(); DepthBuffer->grab();
Stencil = (CStencilBuffer*) driver->getStencilBuffer (); Stencil = (CStencilBuffer*)driver->getStencilBuffer();
if ( Stencil ) if (Stencil)
Stencil->grab(); Stencil->grab();
stencilOp[0] = StencilOp_KEEP; stencilOp[0] = StencilOp_KEEP;
@ -76,7 +84,7 @@ IBurningShader::IBurningShader(
const c8* pixelShaderProgram, const c8* pixelShaderProgram,
const c8* pixelShaderEntryPointName, const c8* pixelShaderEntryPointName,
E_PIXEL_SHADER_TYPE psCompileTarget, E_PIXEL_SHADER_TYPE psCompileTarget,
const c8* geometryShaderProgram , const c8* geometryShaderProgram,
const c8* geometryShaderEntryPointName, const c8* geometryShaderEntryPointName,
E_GEOMETRY_SHADER_TYPE gsCompileTarget, E_GEOMETRY_SHADER_TYPE gsCompileTarget,
scene::E_PRIMITIVE_TYPE inType, scene::E_PRIMITIVE_TYPE inType,
@ -109,9 +117,9 @@ IBurningShader::~IBurningShader()
if (Stencil) if (Stencil)
Stencil->drop(); Stencil->drop();
for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i ) for (u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i)
{ {
if ( IT[i].Texture ) if (IT[i].Texture)
IT[i].Texture->drop(); IT[i].Texture->drop();
} }
@ -121,12 +129,14 @@ IBurningShader::~IBurningShader()
} }
//! sets a render target //! sets a render target
void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort) void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort, const interlaced_control interlaced)
{ {
Interlaced = interlaced;
if (RenderTarget) if (RenderTarget)
RenderTarget->drop(); RenderTarget->drop();
RenderTarget = (video::CImage* ) surface; RenderTarget = (video::CImage*) surface;
if (RenderTarget) if (RenderTarget)
{ {
@ -138,16 +148,16 @@ void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s3
//! sets the Texture //! sets the Texture
void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor) void IBurningShader::setTextureParam(const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor)
{ {
sInternalTexture *it = &IT[stage]; sInternalTexture* it = &IT[stage];
if ( it->Texture) if (it->Texture)
it->Texture->drop(); it->Texture->drop();
it->Texture = texture; it->Texture = texture;
if ( it->Texture) if (it->Texture)
{ {
it->Texture->grab(); it->Texture->grab();
@ -156,48 +166,52 @@ void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTextur
//only mipmap chain (means positive lodFactor) //only mipmap chain (means positive lodFactor)
u32 existing_level = it->Texture->getMipmapLevel(lodFactor); u32 existing_level = it->Texture->getMipmapLevel(lodFactor);
it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY, existing_level, 0); #if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
it->data = (tVideoSample*)it->Texture->lock(ETLM_READ_ONLY, existing_level, 0);
#else
it->data = (tVideoSample*)it->Texture->lock(ETLM_READ_ONLY, existing_level);
#endif
// prepare for optimal fixpoint // prepare for optimal fixpoint
it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() ); it->pitchlog2 = s32_log2_s32(it->Texture->getPitch());
const core::dimension2d<u32> &dim = it->Texture->getSize(); const core::dimension2d<u32>& dim = it->Texture->getSize();
it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK; it->textureXMask = s32_to_fixPoint(dim.Width - 1) & FIX_POINT_UNSIGNED_MASK;
it->textureYMask = s32_to_fixPoint ( dim.Height - 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...) //emulate a line with degenerate triangle and special shader mode (not perfect...)
void IBurningShader::drawLine ( const s4DVertex *a,const s4DVertex *b) void IBurningShader::drawLine(const s4DVertex* a, const s4DVertex* b)
{ {
sVec2 d; sVec2 d;
d.x = b->Pos.x - a->Pos.x; d.x *= d.x; d.x = b->Pos.x - a->Pos.x; d.x *= d.x;
d.y = b->Pos.y - a->Pos.y; d.y *= d.y; d.y = b->Pos.y - a->Pos.y; d.y *= d.y;
//if ( d.x * d.y < 0.001f ) return; //if ( d.x * d.y < 0.001f ) return;
if ( a->Pos.x > b->Pos.x ) swapVertexPointer(&a, &b); if (a->Pos.x > b->Pos.x) swapVertexPointer(&a, &b);
s4DVertex c = *a; s4DVertex c = *a;
const f32 w = (f32)RenderTarget->getDimension().Width-1; const f32 w = (f32)RenderTarget->getDimension().Width - 1;
const f32 h = (f32)RenderTarget->getDimension().Height-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; } 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; 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; } 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 ); drawTriangle(a, b, &c);
EdgeTestPass &= ~edge_test_first_line; EdgeTestPass &= ~edge_test_first_line;
} }
void IBurningShader::drawPoint(const s4DVertex *a) void IBurningShader::drawPoint(const s4DVertex* a)
{ {
} }
void IBurningShader::drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) void IBurningShader::drawWireFrameTriangle(const s4DVertex* a, const s4DVertex* b, const s4DVertex* c)
{ {
if ( EdgeTestPass & edge_test_pass ) drawTriangle(a, b, c); if (EdgeTestPass & edge_test_pass) drawTriangle(a, b, c);
else if (EdgeTestPass & edge_test_point) else if (EdgeTestPass & edge_test_point)
{ {
drawPoint(a); drawPoint(a);
@ -256,7 +270,7 @@ void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMate
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
} }
s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags,const c8* name) s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags, const c8* name)
{ {
if (!name || !name[0]) if (!name || !name[0])
return -1; return -1;
@ -285,7 +299,7 @@ const char* tiny_itoa(s32 value, int base)
b[p] = '\0'; b[p] = '\0';
do { do {
b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value%base]; b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value % base];
value /= base; value /= base;
} while (value && p > 0); } while (value && p > 0);
@ -302,7 +316,7 @@ bool IBurningShader::setShaderConstantID(EBurningUniformFlags flags, s32 index,
BurningUniform add; BurningUniform add;
while ((u32)index >= UniformInfo.size()) while ((u32)index >= UniformInfo.size())
{ {
tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(),10)); tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(), 10));
add.type = flags; add.type = flags;
UniformInfo.push_back(add); UniformInfo.push_back(add);
} }
@ -340,7 +354,7 @@ void IBurningShader::setVertexShaderConstant(const f32* data, s32 startRegister,
c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH]; c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
tiny_strcpy(name, tiny_itoa(startRegister, 10)); tiny_strcpy(name, tiny_itoa(startRegister, 10));
setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM,name), data, constantAmount); setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM, name), data, constantAmount);
} }
void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)

@ -215,7 +215,6 @@ namespace video
}; };
class CBurningVideoDriver; class CBurningVideoDriver;
class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices
{ {
@ -247,7 +246,7 @@ namespace video
virtual ~IBurningShader(); virtual ~IBurningShader();
//! sets a render target //! sets a render target
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort); virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort, const interlaced_control interlaced);
//! sets the Texture //! sets the Texture
virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor); virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);
@ -299,14 +298,38 @@ namespace video
virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_; virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;
virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_; virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
}
virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
}
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
}
virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
}
#endif
//used if no color interpolation is defined //used if no color interpolation is defined
void setPrimitiveColor(const video::SColor& color) void setPrimitiveColor(const video::SColor& color)
{ {
#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8 PrimitiveColor = color_to_sample(color);
PrimitiveColor = color.color;
#else
PrimitiveColor = color.toA1R5G5B5();
#endif
} }
void setTLFlag(size_t in /*eTransformLightFlags*/) void setTLFlag(size_t in /*eTransformLightFlags*/)
{ {
@ -314,11 +337,7 @@ namespace video
} }
void setFog(SColor color_fog) void setFog(SColor color_fog)
{ {
#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8 fog_color_sample = color_to_sample(color_fog);
fog_color_sample = color_fog.color;
#else
fog_color_sample = color_fog.toA1R5G5B5();
#endif
color_to_fix(fog_color, fog_color_sample); color_to_fix(fog_color, fog_color_sample);
} }
void setScissor(const AbsRectangle& scissor) void setScissor(const AbsRectangle& scissor)
@ -349,13 +368,15 @@ namespace video
static const tFixPointu dithermask[ 4 * 4]; static const tFixPointu dithermask[ 4 * 4];
//draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham //draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham
int EdgeTestPass; //edge_test_flag size_t EdgeTestPass; //edge_test_flag
int EdgeTestPass_stack; size_t EdgeTestPass_stack;
interlaced_control Interlaced; // passed from driver
eBurningStencilOp stencilOp[4]; eBurningStencilOp stencilOp[4];
tFixPoint AlphaRef; tFixPoint AlphaRef;
int RenderPass_ShaderIsTransparent; int RenderPass_ShaderIsTransparent;
u8 _unused_pack[4];
sScanConvertData scan; sScanConvertData scan;
sScanLineData line; sScanLineData line;
tVideoSample PrimitiveColor; //used if no color interpolation is defined tVideoSample PrimitiveColor; //used if no color interpolation is defined
@ -365,6 +386,17 @@ namespace video
tVideoSample fog_color_sample; tVideoSample fog_color_sample;
AbsRectangle Scissor; AbsRectangle Scissor;
inline tVideoSample color_to_sample(const video::SColor& color) const
{
//RenderTarget->getColorFormat()
#if SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT == ECF_A8R8G8B8
return color.color;
#else
return color.toA1R5G5B5();
#endif
}
}; };

@ -21,7 +21,7 @@ namespace video
virtual ~IDepthBuffer() {}; virtual ~IDepthBuffer() {};
//! clears the zbuffer //! clears the zbuffer
virtual void clear(f32 value) = 0; virtual void clear(f32 value, const interlaced_control interlaced) = 0;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0; virtual void setSize(const core::dimension2d<u32>& size) = 0;
@ -52,7 +52,7 @@ namespace video
virtual ~IStencilBuffer() {}; virtual ~IStencilBuffer() {};
//! clears the stencil buffer //! clears the stencil buffer
virtual void clear(u8 value) = 0; virtual void clear(u32 value, const interlaced_control interlaced) = 0;
//! sets the new size of the zbuffer //! sets the new size of the zbuffer
virtual void setSize(const core::dimension2d<u32>& size) = 0; virtual void setSize(const core::dimension2d<u32>& size) = 0;

@ -79,6 +79,13 @@ struct sVec2
#include "irrpack.h" #include "irrpack.h"
//! sVec2Pack is Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents Texutre Coordinates.
// Start address is not 4 byte aligned
struct sVec2Pack
{
f32 x, y;
};
//! sVec3Pack used in BurningShader, packed direction //! sVec3Pack used in BurningShader, packed direction
struct sVec3Pack struct sVec3Pack
{ {
@ -553,8 +560,11 @@ struct SAligned4DVertex
} }
s4DVertex* data; //align to 16 byte s4DVertex* data; //align to 16 byte
u8* mem;
size_t ElementSize; size_t ElementSize;
private:
u8* mem;
}; };
//#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2) //#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2)
@ -732,7 +742,7 @@ struct sScanConvertData
{ {
u32 left; // major edge left/right u32 left; // major edge left/right
u32 right; // !left u32 right; // !left
u32 _unused_pack[2]; u8 _unused_pack[8];
f32 invDeltaY[4]; // inverse edge delta for screen space sorted triangle f32 invDeltaY[4]; // inverse edge delta for screen space sorted triangle
@ -767,7 +777,7 @@ struct sScanConvertData
struct sScanLineData struct sScanLineData
{ {
s32 y; // y position of scanline s32 y; // y position of scanline
u32 _unused_pack[1]; u8 _unused_pack[4];
f32 x[2]; // x start, x end of scanline f32 x[2]; // x start, x end of scanline
#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT ) #if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )
@ -776,7 +786,8 @@ struct sScanLineData
f32 z[2]; // z start, z end of scanline f32 z[2]; // z start, z end of scanline
#endif #endif
u32 _unused_pack_1[2]; s32 x_edgetest; // slope x
u8 _unused_pack_1[4];
#if BURNING_MATERIAL_MAX_COLORS > 0 #if BURNING_MATERIAL_MAX_COLORS > 0
sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color start, color end of scanline sVec4 c[BURNING_MATERIAL_MAX_COLORS][2]; // color start, color end of scanline

@ -10,140 +10,167 @@
// Generic Render Flags for burning's video rasterizer // Generic Render Flags for burning's video rasterizer
// defined now in irrlicht compile config // defined now in irrlicht compile config
#if defined(PATCH_SUPERTUX_8_0_1) #if 1 && defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#undef BURNINGVIDEO_RENDERER_BEAUTIFUL #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_USE_WBUFFER
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED
//#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 #endif
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #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_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING #define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_32BIT #define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0 #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0x100000
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
#define SOFTWARE_DRIVER_2_2D_AS_3D #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED
#endif #endif
//! Set Flags for Windows Mobile //! Set Flags for Windows Mobile
#ifdef BURNINGVIDEO_RENDERER_CE #ifdef BURNINGVIDEO_RENDERER_CE
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #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_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING //#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define SOFTWARE_DRIVER_2_16BIT #define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_16BIT
#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 64 #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 64
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
//#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif #endif
#ifdef BURNINGVIDEO_RENDERER_FAST #ifdef BURNINGVIDEO_RENDERER_FAST
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #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_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING //#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_USE_WBUFFER
#define SOFTWARE_DRIVER_2_16BIT #define SOFTWARE_DRIVER_2_16BIT
#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256 #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED
#endif #endif
#ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST #ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST
#define BURNINGVIDEO_RENDERER_FAST #define BURNINGVIDEO_RENDERER_FAST
//#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT //#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_BILINEAR
//#define SOFTWARE_DRIVER_2_LIGHTING //#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_USE_WBUFFER
#define SOFTWARE_DRIVER_2_16BIT #define SOFTWARE_DRIVER_2_16BIT
//#define SOFTWARE_DRIVER_2_MIPMAPPING #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128
//#define SOFTWARE_DRIVER_2_USE_WBUFFER #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128 //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1
//#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED
#endif #endif
// Derivate flags
// texture format
#ifdef SOFTWARE_DRIVER_2_32BIT
#define BURNINGSHADER_COLOR_FORMAT ECF_A8R8G8B8
#else
#define BURNINGSHADER_COLOR_FORMAT ECF_A1R5G5B5
#endif
// 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_MIN_SIZE 1
#elif defined ( BURNINGVIDEO_RENDERER_CE )
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#else
#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_MIN_SIZE 1
#endif
#ifndef REALINLINE #ifndef REALINLINE
#ifdef _MSC_VER #ifdef _MSC_VER
#define REALINLINE __forceinline #define REALINLINE __forceinline
#else #else
#define REALINLINE inline #define REALINLINE inline
#endif #endif
#endif #endif
#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)
#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
//Control Scanline output
#define SOFTWARE_DRIVER_2_STEP_X 1
#define SOFTWARE_DRIVER_2_STEP_Y 1
// null check necessary (burningvideo only) // null check necessary (burningvideo only)
#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f) #define fill_step_y(y) ((y) != 0.f ? (float)1.f / (y):0.f)
static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f; } static inline float fill_step_x(float x) { return x != 0.f ? (float)SOFTWARE_DRIVER_2_STEP_X / x : 0.f; }
#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
#define interlace_control_bit 1
#define interlace_control_mask ((1<<interlace_control_bit)-1)
struct interlaced_control
{
unsigned enable : 1;
unsigned bypass : 1;
unsigned nr : interlace_control_bit;
};
struct interlace_scanline_data { unsigned int y; };
static inline interlaced_control interlace_disabled()
{
interlaced_control v;
v.enable = 0;
v.bypass = 1;
v.nr = 0;
return v;
}
#if defined(SOFTWARE_DRIVER_2_INTERLACED)
#define interlace_scanline if ( Interlaced.bypass | ((line.y & interlace_control_mask) == Interlaced.nr) )
#define interlace_scanline_enabled if ( (line.y & interlace_control_mask) == Interlaced.nr )
//#define interlace_scanline if ( Interlaced.disabled | (((line.y >> (interlace_control_bit-1) ) & 1) == (Interlaced.nr & 1)) )
//#define interlace_scanline
#else
#define interlace_scanline
#define interlace_scanline_enabled
#endif
#define scissor_test_y if ((~TL_Flag & TL_SCISSOR) || ((line.y >= Scissor.y0) & (line.y <= Scissor.y1)))
#define scissor_test_x if ((~TL_Flag & TL_SCISSOR) || ((i+xStart >= Scissor.x0) & (i+xStart <= Scissor.x1)))
#define fill_convention_left(x) (s32) ceilf(x) #define fill_convention_left(x) (s32) ceilf(x)
#define fill_convention_right(x) ((s32) ceilf(x))-1 #define fill_convention_right(x) ((s32) ceilf(x))-1
#define fill_convention_none(x) (s32) (x) #define fill_convention_none(x) (s32) (x)
#define fill_convention_edge(x) (s32) floorf(fabsf(x)+0.f)
//#define fill_convention_left(x) 65536 - int(65536.0f - x) //#define fill_convention_left(x) 65536 - int(65536.0f - x)
//#define fill_convention_right(x) 65535 - int(65536.0f - x) //#define fill_convention_right(x) 65535 - int(65536.0f - x)
@ -157,7 +184,7 @@ static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f;
inline float reciprocal_zero_no(const float x) inline float reciprocal_zero_no(const float x)
{ {
if (x*x <= 0.00001f) __debugbreak(); if (x * x <= 0.00001f) __debugbreak();
return 1.f / x; return 1.f / x;
} }
#else #else
@ -183,49 +210,49 @@ enum edge_test_flag
#define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2 #define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2
//! from 1 bit to 5 bit //! from 1 bit to 5 bit
#ifdef SOFTWARE_DRIVER_2_32BIT #if defined(SOFTWARE_DRIVER_2_32BIT)
#define fix_alpha_color_max(x) #define fix_alpha_color_max(x)
#else #else
#define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1 #define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1
#endif #endif
// Check windows // Check windows
#if _WIN32 || _WIN64 #if _WIN32 || _WIN64
#if _WIN64 #if _WIN64
#define ENV64BIT #define ENV64BIT
#else #else
#define ENV32BIT #define ENV32BIT
#endif #endif
#endif #endif
// Check GCC // Check GCC
#if __GNUC__ #if __GNUC__
#if __x86_64__ || __ppc64__ #if __x86_64__ || __ppc64__
#define ENV64BIT #define ENV64BIT
#else #else
#define ENV32BIT #define ENV32BIT
#endif #endif
#endif #endif
#if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL) #if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL)
typedef float ipoltype; typedef float ipoltype;
#else #else
typedef float ipoltype; typedef float ipoltype;
#endif #endif
#define ipol_lower_equal_0(n) ((n) <= (ipoltype)0.0) #define ipol_lower_equal_0(n) ((n) <= (ipoltype)0.0)
#define ipol_greater_0(n) ((n) > (ipoltype)0.0) #define ipol_greater_0(n) ((n) > (ipoltype)0.0)
#if (_MSC_VER > 1700 ) #if (_MSC_VER > 1700 )
#define burning_restrict __restrict #define burning_restrict __restrict
#else #else
#define burning_restrict #define burning_restrict
#endif #endif
/* /*
if (condition) state |= mask; else state &= ~mask; if (condition) state |= mask; else state &= ~mask;
*/ */
static inline void burning_setbit(size_t &state, int condition, size_t mask) static inline void burning_setbit(size_t& state, int condition, size_t mask)
{ {
if (condition) state |= mask; if (condition) state |= mask;
else state &= ~mask; else state &= ~mask;
@ -234,7 +261,7 @@ static inline void burning_setbit(size_t &state, int condition, size_t mask)
/* /*
if (condition) state |= m; else state &= ~m; if (condition) state |= m; else state &= ~m;
*/ */
REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsigned int mask) REALINLINE void burning_setbit32(unsigned int& state, int condition, const unsigned int mask)
{ {
// 0, or any positive to mask // 0, or any positive to mask
//s32 conmask = -condition >> 31; //s32 conmask = -condition >> 31;
@ -246,44 +273,37 @@ REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsig
#define burning_create(s) burning_create_indirect(s) #define burning_create(s) burning_create_indirect(s)
#if defined(PATCH_SUPERTUX_8_0_1) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#define getData lock
#define snprintf_irr sprintf_s #define snprintf_irr sprintf_s
#define EVDF_DEPTH_CLAMP 43
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define E_CUBE_SURFACE int
#ifdef SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR #define ECFN_DISABLED 0
#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 { namespace irr {
namespace video {
REALINLINE void memcpy32_small(void * dest, const void *source, size_t bytesize) //! Enum for the flags of clear buffer
enum E_CLEAR_BUFFER_FLAG
{ {
size_t c = bytesize >> 2; ECBF_NONE = 0,
ECBF_COLOR = 1,
ECBF_DEPTH = 2,
ECBF_STENCIL = 4,
ECBF_ALL = ECBF_COLOR | ECBF_DEPTH | ECBF_STENCIL
};
do //! For SMaterial.ZWriteEnable
enum E_ZWRITE
{ {
((unsigned int *)dest)[c - 1] = ((unsigned int *)source)[c - 1]; EZW_OFF = 0,
} while (--c); EZW_AUTO,
EZW_ON
};
} }
}
#endif // PATCH_SUPERTUX_8_0_1_with_1_9_0
} // namespace irr //! Size of a static C-style array.
#endif // #if defined(PATCH_SUPERTUX_8_0_1) #define array_size(_arr) ((sizeof(_arr)/sizeof(*_arr)))
#endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__ #endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__

@ -22,7 +22,7 @@ namespace irr
// supporting different packed pixel needs many defines... // supporting different packed pixel needs many defines...
#ifdef SOFTWARE_DRIVER_2_32BIT #if defined(SOFTWARE_DRIVER_2_32BIT)
typedef u32 tVideoSample; typedef u32 tVideoSample;
typedef u32 tStencilSample; typedef u32 tStencilSample;
@ -40,8 +40,8 @@ namespace irr
#define COLOR_MAX_LOG2 8 #define COLOR_MAX_LOG2 8
#define COLOR_BRIGHT_WHITE 0xFFFFFFFF #define COLOR_BRIGHT_WHITE 0xFFFFFFFF
#define VIDEO_SAMPLE_GRANULARITY (unsigned)2 #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)2
#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)2
#else #else
typedef u16 tVideoSample; typedef u16 tVideoSample;
typedef u8 tStencilSample; typedef u8 tStencilSample;
@ -59,7 +59,8 @@ namespace irr
#define COLOR_MAX 0x1F #define COLOR_MAX 0x1F
#define COLOR_MAX_LOG2 5 #define COLOR_MAX_LOG2 5
#define COLOR_BRIGHT_WHITE 0xFFFF #define COLOR_BRIGHT_WHITE 0xFFFF
#define VIDEO_SAMPLE_GRANULARITY (unsigned)1 #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)1
#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)1
#endif #endif
@ -140,6 +141,19 @@ inline void memset16(void * dest, const u16 value, size_t bytesize)
} }
} }
//! memset interleaved
inline void memset32_interlaced(void* dest, const u32 value, size_t pitch,u32 height,const interlaced_control Interlaced)
{
if (Interlaced.bypass) return memset32(dest, value, pitch * height);
u8* dst = (u8*)dest;
interlace_scanline_data line;
for (line.y = 0; line.y < height; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{
interlace_scanline_enabled memset32(dst, value, pitch);
dst += pitch;
}
}
// byte-align structures // byte-align structures
#include "irrpack.h" #include "irrpack.h"
@ -577,7 +591,7 @@ REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y)
*/ */
REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y) REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)
{ {
#ifdef SOFTWARE_DRIVER_2_32BIT #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8
return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4); return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4);
#else #else
return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5); return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5);
@ -598,7 +612,7 @@ REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y)
REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y) REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)
{ {
#ifdef SOFTWARE_DRIVER_2_32BIT #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8
tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2); tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2);
#else #else
tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3); tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3);
@ -608,17 +622,6 @@ REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)
} }
#if 0
#define imulFix_tex1(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 4))
#define imulFix_tex2(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 3))
#ifdef SOFTWARE_DRIVER_2_32BIT
#define imulFix_tex4(x,y) ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 )
#else
#define imulFix_tex4(x,y) ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) )
#endif
#endif
/*! /*!
clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX) clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX)
*/ */
@ -831,7 +834,7 @@ static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFi
size_t ofs; size_t ofs;
ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
// texel // texel
return *((tVideoSample*)( (u8*) t->data + ofs )); return *((tVideoSample*)( (u8*) t->data + ofs ));
@ -845,7 +848,7 @@ inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
size_t ofs; size_t ofs;
ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -865,7 +868,7 @@ inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,
size_t ofs; size_t ofs;
ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -886,7 +889,7 @@ static REALINLINE void getTexel_fix ( tFixPoint &a,
size_t ofs; size_t ofs;
ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;
ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY ); ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY );
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -913,7 +916,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
tVideoSample t00; tVideoSample t00;
@ -937,8 +940,8 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
//wraps positive (ignoring negative) //wraps positive (ignoring negative)
o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2))); t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2)));
r00 = (t00 & MASK_R) >> SHIFT_R; r00 = (t00 & MASK_R) >> SHIFT_R;
@ -1001,7 +1004,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
//nearest neighbor //nearest neighbor
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
tVideoSample t00; tVideoSample t00;
t00 = *((tVideoSample*)((u8*)tex->data + ofs)); t00 = *((tVideoSample*)((u8*)tex->data + ofs));
@ -1029,8 +1032,8 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
size_t o0, o1, o2, o3; size_t o0, o1, o2, o3;
o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2))); t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3))); t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));
@ -1072,8 +1075,8 @@ static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &
o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;
o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2))); t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));
a00 = (t00 & MASK_A) >> SHIFT_A; a00 = (t00 & MASK_A) >> SHIFT_A;
@ -1144,7 +1147,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &
{ {
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs)); const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
@ -1160,7 +1163,7 @@ static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &
{ {
size_t ofs; size_t ofs;
ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;
ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY); ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY);
// texel // texel
const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs)); const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));
@ -1233,8 +1236,6 @@ static inline int tiny_isequal(const char *s1, const char *s2, size_t n)
} }
#define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0 #define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0
//! Size of a static C-style array.
#define array_size(_arr) ((sizeof(_arr)/sizeof(*_arr)))
} // end namespace irr } // end namespace irr

@ -40,7 +40,7 @@ void burning_shader_class::burning_shader_fragment()
return; return;
// slopes // slopes
const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]); const f32 invDeltaX = fill_step_x(line.x[1] - line.x[0]);
#ifdef IPOL_Z #ifdef IPOL_Z
slopeZ = (line.z[1] - line.z[0]) * invDeltaX; slopeZ = (line.z[1] - line.z[0]) * invDeltaX;
@ -96,9 +96,9 @@ void burning_shader_class::burning_shader_fragment()
tFixPoint r1, g1, b1; tFixPoint r1, g1, b1;
#endif #endif
for (s32 i = 0; i <= dx; ++i) for (s32 i = 0; i <= dx; i+= SOFTWARE_DRIVER_2_STEP_X)
{ {
if ((0 == EdgeTestPass) & i) break; if ((0 == EdgeTestPass) & (i > line.x_edgetest)) break;
#ifdef CMP_Z #ifdef CMP_Z
if (line.z[0] < z[i]) if (line.z[0] < z[i])

@ -139,8 +139,10 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for (line.y = yStart; line.y <= yEnd; ++line.y) for (line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -171,6 +173,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline
(this->*fragmentShader) (); (this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break; if (EdgeTestPass & edge_test_first_line) break;
@ -265,7 +268,6 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
yEnd = fill_convention_right(c->Pos.y); yEnd = fill_convention_right(c->Pos.y);
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ((f32)yStart) - b->Pos.y; subPixel = ((f32)yStart) - b->Pos.y;
// correct to pixel center // correct to pixel center
@ -299,8 +301,10 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines // rasterize the edge scanlines
for (line.y = yStart; line.y <= yEnd; ++line.y) for (line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
line.x[scan.left] = scan.x[0]; line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1]; line.x[scan.right] = scan.x[1];
@ -331,6 +335,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline
(this->*fragmentShader) (); (this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break; if (EdgeTestPass & edge_test_first_line) break;

@ -48,7 +48,7 @@ bool flyCircleAnimator(void)
{ {
smgr->drawAll(); smgr->drawAll();
driver->endScene(); driver->endScene();
result = takeScreenshotAndCompareAgainstReference(driver, "-flyCircleAnimator.png", 100); result = takeScreenshotAndCompareAgainstReference(driver, "-flyCircleAnimator.png");
} }
device->closeDevice(); device->closeDevice();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 740 B

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

@ -1,4 +1,4 @@
Tests finished. 72 tests of 72 passed. Tests finished. 72 tests of 72 passed.
Compiled as RELEASE Compiled as RELEASE
Test suite pass at GMT Sun Oct 25 15:03:26 2020 Test suite pass at GMT Tue Nov 10 18:42:40 2020