burning v0.53

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6364 dfc29bdd-3216-0410-991c-e03cc46cb475
This commit is contained in:
engineer_apple 2022-04-30 22:57:17 +00:00
parent 2d5673a1d4
commit 4fe6a16165
113 changed files with 4567 additions and 2853 deletions

@ -228,6 +228,12 @@ int main()
vsFileName = mediaPath + "opengl.vsh"; vsFileName = mediaPath + "opengl.vsh";
} }
break; break;
case video::EDT_BURNINGSVIDEO:
UseHighLevelShaders = true;
psFileName = mediaPath + "opengl.frag";
vsFileName = mediaPath + "opengl.vert";
break;
default: default:
break; break;
} }

@ -356,6 +356,7 @@ int main(int argc, char* argv[])
// Add the mesh to the scene graph // Add the mesh to the scene graph
IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(mesh.Mesh); IMeshSceneNode* meshnode = smgr -> addMeshSceneNode(mesh.Mesh);
meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false); meshnode->setMaterialFlag(video::EMF_BACK_FACE_CULLING, false);
meshnode->getMaterial(0).Shininess = 80.f;
// light is just for nice effects // light is just for nice effects
ILightSceneNode *node = smgr->addLightSceneNode(0, vector3df(0,100,0), ILightSceneNode *node = smgr->addLightSceneNode(0, vector3df(0,100,0),

@ -218,6 +218,7 @@ int main()
break; break;
case video::EDT_OPENGL: case video::EDT_OPENGL:
case video::EDT_BURNINGSVIDEO:
psFileName = mediaPath + "pp_opengl.frag"; psFileName = mediaPath + "pp_opengl.frag";
vsFileName = mediaPath + "pp_opengl.vert"; vsFileName = mediaPath + "pp_opengl.vert";
break; break;

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio Version 16
VisualStudioVersion = 14.0.25420.1 VisualStudioVersion = 16.0.32413.511
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "01.HelloWorld", "01.HelloWorld\HelloWorld_vc14.vcxproj", "{5AD4C95C-BA38-4692-BA4B-8C25A86208F9}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "01.HelloWorld", "01.HelloWorld\HelloWorld_vc14.vcxproj", "{5AD4C95C-BA38-4692-BA4B-8C25A86208F9}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
@ -147,8 +147,14 @@ EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "..\source\Irrlicht\Irrlicht14.0.vcxproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Irrlicht", "..\source\Irrlicht\Irrlicht14.0.vcxproj", "{E08E042A-6C45-411B-92BE-3CC31331019F}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "27.PostProcessing", "27.PostProcessing\PostProcessing_vc14.vcxproj", "{F25F2AC4-AEDA-4A95-9769-01A2652B54A2}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "27.PostProcessing", "27.PostProcessing\PostProcessing_vc14.vcxproj", "{F25F2AC4-AEDA-4A95-9769-01A2652B54A2}"
ProjectSection(ProjectDependencies) = postProject
{E08E042A-6C45-411B-92BE-3CC31331019F} = {E08E042A-6C45-411B-92BE-3CC31331019F}
EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "28.CubeMapping", "28.CubeMapping\CubeMapping_vc14.vcxproj", "{DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "28.CubeMapping", "28.CubeMapping\CubeMapping_vc14.vcxproj", "{DEE0160F-8FBD-43EC-BB96-1B9C0ED1B51A}"
ProjectSection(ProjectDependencies) = postProject
{E08E042A-6C45-411B-92BE-3CC31331019F} = {E08E042A-6C45-411B-92BE-3CC31331019F}
EndProjectSection
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -1096,4 +1102,7 @@ Global
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2722D524-E069-40BF-B51A-2BD81342E7D7}
EndGlobalSection
EndGlobal EndGlobal

@ -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.52"); box->addItem(L"Burning's Video 0.53");
box->addItem(L"Irrlicht Software Renderer 1.0"); box->addItem(L"Irrlicht Software Renderer 1.0");
switch (driverType ) switch (driverType )
{ {

@ -1473,7 +1473,7 @@ static s32 StretchBlit(eBlitter operation,
// Methods for Software drivers // Methods for Software drivers
//! draws a rectangle //! draws a rectangle
static void drawRectangle(video::IImage* img, const core::rect<s32>& rect, const video::SColor &color) static inline void drawRectangle(video::IImage* img, const core::rect<s32>& rect, const video::SColor &color)
{ {
Blit(color.getAlpha() == 0xFF ? BLITTER_COLOR : BLITTER_COLOR_ALPHA, Blit(color.getAlpha() == 0xFF ? BLITTER_COLOR : BLITTER_COLOR_ALPHA,
img, 0, &rect.UpperLeftCorner, 0, &rect, color.color); img, 0, &rect.UpperLeftCorner, 0, &rect, color.color);
@ -1481,7 +1481,7 @@ static void drawRectangle(video::IImage* img, const core::rect<s32>& rect, const
//! draws a line from to with color //! draws a line from to with color
static void drawLine(video::IImage* img, const core::position2d<s32>& from, static inline void drawLine(video::IImage* img, const core::position2d<s32>& from,
const core::position2d<s32>& to, const video::SColor &color) const core::position2d<s32>& to, const video::SColor &color)
{ {
AbsRectangle clip; AbsRectangle clip;

@ -40,7 +40,7 @@ CDepthBuffer::~CDepthBuffer()
//! clears the zbuffer //! clears the zbuffer
void CDepthBuffer::clear(f32 value, interlaced_control interlaced) void CDepthBuffer::clear(f32 value, const interlaced_control interlaced)
{ {
ieee754 zMaxValue; ieee754 zMaxValue;
@ -69,7 +69,7 @@ void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
size_t 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( 1.f, interlace_disabled()); clear( 1.f, interlaced_disabled());
} }
@ -135,7 +135,7 @@ void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
size_t 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(0, interlace_disabled()); clear(0, interlaced_disabled());
} }

@ -284,8 +284,8 @@ void CImage::copyToScalingBoxFilter(IImage* target, s32 bias, bool blend)
target->getData(); target->getData();
s32 fx = core::ceil32( sourceXStep ); const s32 fx = core::ceil32( sourceXStep );
s32 fy = core::ceil32( sourceYStep ); const s32 fy = core::ceil32( sourceYStep );
f32 sx; f32 sx;
f32 sy; f32 sy;
@ -403,14 +403,15 @@ void CImage::flip(bool topBottom, bool leftRight)
} }
//! get a filtered pixel //! get a filtered pixel
inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const inline SColor CImage::getPixelBox( const s32 x, const s32 y, const s32 fx, const s32 fy, const s32 bias ) const
{ {
/*
if (IImage::isCompressedFormat(Format)) if (IImage::isCompressedFormat(Format))
{ {
os::Printer::log("IImage::getPixelBox method doesn't work with compressed images.", ELL_WARNING); os::Printer::log("IImage::getPixelBox method doesn't work with compressed images.", ELL_WARNING);
return SColor(0); return SColor(0);
} }
*/
SColor c; SColor c;
s32 a = 0, r = 0, g = 0, b = 0; s32 a = 0, r = 0, g = 0, b = 0;
@ -430,12 +431,12 @@ inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) cons
} }
s32 sdiv = s32_log2_s32(fx * fy); const s32 sdiv = fx * fy; // s32_log2_s32(fx * fy);
a = core::s32_clamp( ( a >> sdiv ) + bias, 0, 255 ); a = core::s32_clamp( ( a / sdiv ) + bias, 0, 255 );
r = core::s32_clamp( ( r >> sdiv ) + bias, 0, 255 ); r = core::s32_clamp( ( r / sdiv ) + bias, 0, 255 );
g = core::s32_clamp( ( g >> sdiv ) + bias, 0, 255 ); g = core::s32_clamp( ( g / sdiv ) + bias, 0, 255 );
b = core::s32_clamp( ( b >> sdiv ) + bias, 0, 255 ); b = core::s32_clamp( ( b / sdiv ) + bias, 0, 255 );
c.set( a, r, g, b ); c.set( a, r, g, b );
return c; return c;

@ -62,7 +62,7 @@ public:
virtual void fill(const SColor &color) IRR_OVERRIDE; virtual void fill(const SColor &color) IRR_OVERRIDE;
private: private:
inline SColor getPixelBox ( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) const; inline SColor getPixelBox ( const s32 x, const s32 y, const s32 fx, const s32 fy, s32 bias ) const;
}; };
} // end namespace video } // end namespace video

@ -30,7 +30,7 @@ public:
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE
{ {
if (Driver) if (Driver)
Driver->setFallback_Material(material.MaterialType); Driver->setFallback_Material(material.MaterialType, BVT_Fix);
} }
protected: protected:

File diff suppressed because it is too large Load Diff

@ -34,6 +34,22 @@ namespace video
//! Create render target. //! Create render target.
virtual IRenderTarget* addRenderTarget() IRR_OVERRIDE; virtual IRenderTarget* addRenderTarget() IRR_OVERRIDE;
//! Run occlusion query. Draws mesh stored in query.
/** If the mesh shall not be rendered visible, use
overrideMaterial to disable the color and depth buffer. */
virtual void runOcclusionQuery(scene::ISceneNode* node, bool visible = false) IRR_OVERRIDE;
//! Update occlusion query. Retrieves results from GPU.
/** If the query shall not block, set the flag to false.
Update might not occur in this case, though */
virtual void updateOcclusionQuery(scene::ISceneNode* node, bool block = true) IRR_OVERRIDE;
//! Return query result.
/** Return value is the number of visible pixels/fragments.
The value is a safe approximation, i.e. can be larger then the
actual value of pixels. */
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const IRR_OVERRIDE;
//! sets transformation //! sets transformation
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) IRR_OVERRIDE; virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) IRR_OVERRIDE;
@ -253,7 +269,8 @@ namespace video
bool resetAllRenderstates) IRR_OVERRIDE; bool resetAllRenderstates) IRR_OVERRIDE;
//pass BaseMaterialID //pass BaseMaterialID
void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType); void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType
, eBurningVertexShader vertexShader);
//! Return an index constant for the vertex shader based on a name. //! Return an index constant for the vertex shader based on a name.
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE; virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
@ -328,6 +345,9 @@ namespace video
IBurningShader* CurrentShader; IBurningShader* CurrentShader;
IBurningShader* BurningShader[ETR2_COUNT]; IBurningShader* BurningShader[ETR2_COUNT];
PushShaderData PushShader;
void pushShader(scene::E_PRIMITIVE_TYPE pType, int testCurrent);
IDepthBuffer* DepthBuffer; IDepthBuffer* DepthBuffer;
IStencilBuffer* StencilBuffer; IStencilBuffer* StencilBuffer;
@ -341,9 +361,9 @@ namespace video
enum E_TRANSFORMATION_STATE_BURNING_VIDEO enum E_TRANSFORMATION_STATE_BURNING_VIDEO
{ {
ETS_VIEW_PROJECTION = ETS_COUNT, ETS_VIEW_PROJECTION = ETS_COUNT,
ETS_PROJ_MODEL_VIEW, ETS_MODEL_VIEW_PROJ,
ETS_MODEL_VIEW, ETS_MODEL_VIEW,
ETS_NORMAL, //3x3 ModelView Tansposed Inverse ETS_NORMAL, //3x3 ModelView Transposed Inverse
ETS_COUNT_BURNING = 16 ETS_COUNT_BURNING = 16
}; };
@ -354,12 +374,18 @@ namespace video
{ {
ETF_VALID = 1, ETF_VALID = 1,
ETF_IDENTITY = 2, ETF_IDENTITY = 2,
ETF_TEXGEN_CAMERA_SPHERE = 4, ETF_TEXGEN_MATRIX = 4, // or !ETF_IDENTITY
ETF_TEXGEN_CAMERA_REFLECTION = 8, ETF_TEXGEN_CAMERA_SPHERE = 8,
ETF_TEXGEN_WRAP = 16, ETF_TEXGEN_CAMERA_REFLECTION = 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_MATRIX
}; };
size_t TransformationStack; // 0 .. 3D , 1 .. 2D enum E_TRANSFORMATION_STACK
{
ETF_STACK_3D = 0,
ETF_STACK_2D = 1,
};
size_t TransformationStack; // 0 .. 3D , 1 .. 2D, 2.. Geometric Clipper
core::matrix4 ALIGN(16) Transformation[2][ETS_COUNT_BURNING]; core::matrix4 ALIGN(16) 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
@ -375,34 +401,33 @@ namespace video
AbsRectangle Scissor; AbsRectangle Scissor;
// Vertex Cache // Vertex Cache
SVertexCache VertexCache; SVertexShader VertexShader;
int VertexCache_reset (const void* vertices, u32 vertexCount, int VertexCache_reset (const void* vertices, u32 vertexCount,
const void* indices, u32 indexCount, const void* indices, u32 indexCount,
E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType, E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType); E_INDEX_TYPE iType);
void VertexCache_get (s4DVertexPair* face[4] ); //void VertexCache_get (s4DVertexPair* face[4] );
void VertexCache_map_source_format(); void VertexCache_map_source_format();
void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex ); //s4DVertexPair* VertexCache_getVertex ( const u32 sourceIndex ) const;
s4DVertexPair* VertexCache_getVertex ( const u32 sourceIndex ) const;
// culling & clipping // culling & clipping
//size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane ); //size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane );
//size_t inline clipToFrustumTest ( const s4DVertex * v ) const; //size_t inline clipToFrustumTest ( const s4DVertex * v ) const;
public: public:
size_t clipToFrustum( const size_t vIn /*, const size_t clipmask_for_face*/ ); void VertexCache_fill(const u32 sourceIndex, const u32 destIndex);
u32 clipToFrustum( const u32 vIn /*, const size_t clipmask_for_face*/ );
protected: protected:
// holds transformed, clipped vertices for a triangle. triangle expands on clipping // holds transformed, clipped vertices for a triangle. triangle expands on clipping
// Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected) // Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected)
SAligned4DVertex Clipper; SAligned4DVertex Clipper;
SAligned4DVertex Clipper_temp; SAligned4DVertex Clipper_disjoint; // __restrict helper
#ifdef SOFTWARE_DRIVER_2_LIGHTING #ifdef SOFTWARE_DRIVER_2_LIGHTING
void lightVertex_eye ( s4DVertex *dest, u32 vertexargb ); void lightVertex_eye ( s4DVertex *dest, const u32 vertexargb );
#endif #endif
//! Sets the fog mode. //! Sets the fog mode.
@ -410,22 +435,29 @@ namespace video
f32 end, f32 density, bool pixelFog, bool rangeFog) IRR_OVERRIDE; f32 end, f32 density, bool pixelFog, bool rangeFog) IRR_OVERRIDE;
void ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair* source, const size_t vIn ) const; //void ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair* source, const size_t vIn ) const;
//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, const f32 dc_area, const 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 (s4DVertexPair* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;
void getCameraPosWorldSpace(); //void getCameraPosWorldSpace();
void assignHardwareLight(SBurningShaderLight& l, const SLight& dl);
SBurningShaderEyeSpace EyeSpace; SBurningShaderEyeSpace EyeSpace;
SBurningShaderMaterial Material; SBurningShaderMaterial Material;
static const sVec4 NDCPlane[6+2]; //static const sVec4 NDCPlane[6+2];
//! Built-in 2D quad for 2D rendering. //! Built-in 2D quad for 2D rendering.
S3DVertex Quad2DVertices[4]; S3DVertex Quad2DVertices[4];
interlaced_control Interlaced; interlaced_control Interlaced;
f32 TexBias[2];
public:
const interlaced_control& getInterlace() { return Interlaced; }
protected:
u32 samples_passed;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
core::array<IRenderTarget*> RenderTargets; core::array<IRenderTarget*> RenderTargets;

@ -12,16 +12,15 @@
#include "CBlit.h" #include "CBlit.h"
#include "os.h" #include "os.h"
namespace irr burning_namespace_start
{
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 ) //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) static inline core::dimension2d<u32> getOptimalSize(const core::dimension2d<u32>& original,
const u32 allowNonPowerOfTwo, const u32 maxSize
, const interlaced_control& interlace)
{ {
u32 w, h; u32 w, h;
if (allowNonPowerOfTwo) if (allowNonPowerOfTwo)
@ -29,7 +28,17 @@ static inline core::dimension2d<u32> getOptimalSize(const core::dimension2d<u32>
w = original.Width; w = original.Width;
h = original.Height; h = original.Height;
} }
else /*
else
{
w = 1;
while (w < original.Width) w *= 2;
h = 1;
while (h < original.Height) h *= 2;
}
*/
else if (interlace.bypass)
{ {
w = 1; w = 1;
while (w * 2 < original.Width) w *= 2; while (w * 2 < original.Width) w *= 2;
@ -39,18 +48,33 @@ static inline core::dimension2d<u32> getOptimalSize(const core::dimension2d<u32>
while (h * 2 < original.Height) h *= 2; while (h * 2 < original.Height) h *= 2;
if (h * 2 - original.Height < original.Height - h) h *= 2; if (h * 2 - original.Height < original.Height - h) h *= 2;
} }
else
{
u32 dw = original.Width / (interlace.tex_scalex + 1);
u32 dh = original.Height / (interlace.tex_scaley + 1);
w = 1;
while (w < dw) w *= 2;
h = 1;
while (h < dh) h *= 2;
}
if (maxSize && w > maxSize) w = maxSize; if (maxSize && w > maxSize) w = maxSize;
if (maxSize && h > maxSize) h = maxSize; if (maxSize && h > maxSize) h = maxSize;
return core::dimension2d<u32>(w, h); return core::dimension2d<u32>(w, h);
} }
//Helper pointer (do not store per texture)
const IImage* CSoftwareTexture2::original_mip0 = 0;
//! 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 #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) : ITexture(name),Type(ETT_2D)
, ETT_2D #else
: ITexture(name, ETT_2D)
#endif #endif
)
, MipMapLOD(0), Flags(flags), Driver(driver) , MipMapLOD(0), Flags(flags), Driver(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
@ -65,11 +89,13 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
ColorFormat = (Flags & IS_RENDERTARGET) ? SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT : SOFTWARE_DRIVER_2_TEXTURE_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[1] = 1;
LodBIAS = 1.f;
for (size_t i = 0; i < array_size(MipMap); ++i) MipMap[i] = 0; for (size_t i = 0; i < array_size(MipMap); ++i) MipMap[i] = 0;
if (!image) return; if (!image)
{
calcDerivative();
return;
}
OriginalSize = image->getDimension(); OriginalSize = image->getDimension();
OriginalColorFormat = image->getColorFormat(); OriginalColorFormat = image->getColorFormat();
@ -78,14 +104,21 @@ 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
//compatible means all texture are linear
//Flags |= TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR;
//guessing linear image, everything else degamma
if (name.find("light") >= 0 || if (name.find("light") >= 0 ||
name.find("bump") >= 0 || name.find("bump") >= 0 ||
name.find("height") >= 0 name.find("height") >= 0
|| name.find("detail") >= 0 // demo detailmap3.jpg. do some s-shaping on degamma for equal center?
) )
{ {
Flags |= TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR; Flags |= TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR;
} }
#endif #endif
bool isCompressed = IImage::isCompressedFormat(OriginalColorFormat); bool isCompressed = IImage::isCompressedFormat(OriginalColorFormat);
@ -103,16 +136,12 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
maxTexSize = 0; maxTexSize = 0;
} }
#endif #endif
/*
core::dimension2d<u32> optSize(OriginalSize.getOptimalSize( //thread-local storage if needed
(Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo original_mip0 = 0;
false, // requireSquare
(Flags & ALLOW_NPOT) ? 1 : maxTexSize == SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, // larger const interlaced_control& interlaced = Driver->getInterlace();
(Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue core::dimension2d<u32> optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize, interlaced));
)
);
*/
core::dimension2d<u32> optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize));
if (OriginalSize == optSize) if (OriginalSize == optSize)
{ {
MipMap[0] = new CImage(ColorFormat, image->getDimension()); MipMap[0] = new CImage(ColorFormat, image->getDimension());
@ -132,17 +161,18 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
{ {
//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);
original_mip0 = image;
} }
// 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 // Show Information about resizing
if (OriginalSize != optSize || if ((OriginalSize != optSize && interlaced.tex_scalex == 0) ||
( OriginalColorFormat != ColorFormat && (OriginalColorFormat != ColorFormat &&
!((OriginalColorFormat == ECF_R8G8B8 || OriginalColorFormat == ECF_A1R5G5B5) && ColorFormat == ECF_A8R8G8B8) !((OriginalColorFormat == ECF_R8G8B8 || OriginalColorFormat == ECF_A1R5G5B5) && ColorFormat == ECF_A8R8G8B8)
)
) )
)
{ {
char buf[256]; char buf[256];
core::stringw showName(name); core::stringw showName(name);
@ -157,6 +187,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
//select highest mipmap 0 //select highest mipmap 0
regenerateMipMapLevels(image->getMipMapsData()); regenerateMipMapLevels(image->getMipMapsData());
original_mip0 = 0;
} }
@ -198,6 +229,8 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
if (HasMipMaps && ((Flags & GEN_MIPMAP_AUTO) || 0 == data)) if (HasMipMaps && ((Flags & GEN_MIPMAP_AUTO) || 0 == data))
{ {
const IImage* mip0 = original_mip0 ? original_mip0 : MipMap[0];
//need memory also if autogen mipmap disabled //need memory also if autogen mipmap disabled
for (i = 1; i < array_size(MipMap); ++i) for (i = 1; i < array_size(MipMap); ++i)
{ {
@ -214,7 +247,7 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
#endif #endif
//MipMap[i]->fill ( 0xFFFF4040 ); //MipMap[i]->fill ( 0xFFFF4040 );
//MipMap[i-1]->copyToScalingBoxFilter( MipMap[i], 0, false ); //MipMap[i-1]->copyToScalingBoxFilter( MipMap[i], 0, false );
Resample_subSampling(BLITTER_TEXTURE, MipMap[i], 0, MipMap[0], 0, Flags); Resample_subSampling(BLITTER_TEXTURE, MipMap[i], 0, mip0, 0, Flags);
} }
} }
else if (HasMipMaps && data) else if (HasMipMaps && data)
@ -235,9 +268,6 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
i += 1; i += 1;
} while ((origSize.Width != 1 || origSize.Height != 1) && i < array_size(MipMap)); } while ((origSize.Width != 1 || origSize.Height != 1) && i < array_size(MipMap));
//TODO: this is not true
LodBIAS = i * 2.f;
origSize = OriginalSize; origSize = OriginalSize;
for (i = 1; i < array_size(MipMap) && mip_current < mip_end; ++i) for (i = 1; i < array_size(MipMap) && mip_current < mip_end; ++i)
{ {
@ -279,10 +309,11 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
#if 0 #if 0
//visualize mipmap //visualize mipmap
for (i = 1; i < 0 && i < array_size(MipMap); ++i) //if ( Flags & ( TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR))
for (i = 1; i < array_size(MipMap); ++i)
{ {
static u32 color[] = { static u32 color[] = {
0xFFFF0000, 0xFFFFFFFF,
0xFFFF0000,0xFF00FF00,0xFF0000FF, 0xFFFF0000,0xFF00FF00,0xFF0000FF,
0xFFFFFF00,0xFF00FFFF,0xFFFF00FF, 0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,
0xFFff6600,0xFF00ff66,0xFF6600FF, 0xFFff6600,0xFF00ff66,0xFF6600FF,
@ -296,14 +327,16 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
int border = 0; int border = 0;
const core::dimension2du& d = MipMap[i]->getDimension(); const core::dimension2du& d = MipMap[i]->getDimension();
core::rect<s32> p(0, 0, d.Width, d.Height); core::rect<s32> p(0, 0, d.Width, d.Height);
SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000); SColor c((color[i & 15] & 0x00FFFFFF) | 0x7F000000);
core::rect<s32> dclip(border, border, d.Width - border, d.Height - border); 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); Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], &dclip, 0, MipMap[i], &p, c.color);
} }
} }
#endif
#if 1
//save mipmap chain //save mipmap chain
if (0) if (0)
{ {
@ -318,14 +351,20 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
//if (name[i] == '.') ext = i; //if (name[i] == '.') ext = i;
i += 1; i += 1;
} }
for (i = 0; i < array_size(MipMap); ++i) if (original_mip0)
{ {
if (MipMap[i]) snprintf_irr(buf, sizeof(buf), "mip/%s_org.png", name + filename);
{ Driver->writeImageToFile((IImage*)original_mip0, buf);
snprintf_irr(buf, sizeof(buf), "mip/%s_%02d.png", name + filename, (s32)i);
Driver->writeImageToFile(MipMap[i], buf);
}
} }
if (array_size(MipMap) >= 1 && MipMap[1])
for (i = 0; i < array_size(MipMap); ++i)
{
if (MipMap[i])
{
snprintf_irr(buf, sizeof(buf), "mip/%s_%02d.png", name + filename, (s32)i);
Driver->writeImageToFile(MipMap[i], buf);
}
}
} }
#endif #endif
calcDerivative(); calcDerivative();
@ -337,39 +376,48 @@ void CSoftwareTexture2::calcDerivative()
MipMapLOD = 0; MipMapLOD = 0;
if (MipMap[0]) if (MipMap[0])
{ {
const core::dimension2du& dim = MipMap[0]->getDimension(); Size = MipMap[MipMapLOD]->getDimension();
MipMap0_Area[0] = dim.Width;
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();
Pitch = MipMap[MipMapLOD]->getPitch(); Pitch = MipMap[MipMapLOD]->getPitch();
} }
//preCalc mipmap texel center boundaries //preCalc mipmap texel center boundaries
for (size_t i = 0; i < array_size(MipMap); ++i) for (size_t i = 0; i < array_size(MipMap); ++i)
{ {
CSoftwareTexture2_Bound& b = TexBound[i]; CSoftwareTexture2_Bound& b = TexBound[i];
if (MipMap[i])
{
const core::dimension2du& dim = MipMap[i]->getDimension();
//f32 u = 1.f / dim.Width;
//f32 v = 1.f / dim.Height;
b.w = dim.Width - 1.f; core::dimension2du dim(0, 0);
b.h = dim.Height - 1.f; if (MipMap[i] && MipMap[i]->getData()) dim = MipMap[i]->getDimension();
b.cx = 0.f; //u*0.005f;
b.cy = 0.f; //v*0.005f; b.area = dim.Width * dim.Height;
if (b.area < 1)
{
b.mat[0] = 0.f;
b.mat[1] = 0.f;
b.mat[2] = 0.f;
b.mat[3] = 0.f;
} }
else else
{ {
b.w = 0.f; #if 0
b.h = 0.f; const f32 nu = 0.5f / dim.Width;
b.cx = 0.f; const f32 nv = 0.5f / dim.Height;
b.cy = 0.f;
//texture sampler! u,v repeat > 1 is wrong
// should be [0.5/width,1-0.5/width] ,but currently can't step outside last pixel...
// https://bartwronski.com/2021/02/15/bilinear-down-upsampling-pixel-grids-and-that-half-pixel-offset/
b.mat[0] = 1.f - 2 * nu;
b.mat[1] = nu;
b.mat[2] = 1.f - 2 * nv;
b.mat[3] = nv;
#endif
//texture sampler doesn't filter from center, sub-pixel shifts sub-texel
//wrong place here to go to pixel-dim
b.mat[0] = dim.Width - 1.f;
b.mat[1] = 0.f;
b.mat[2] = dim.Height - 1.f;
b.mat[3] = 0.f;
} }
} }
@ -380,7 +428,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), DepthStencil(0)
#endif #endif
{ {
DriverType = EDT_BURNINGSVIDEO; DriverType = EDT_BURNINGSVIDEO;
@ -393,9 +441,13 @@ CSoftwareRenderTarget2::~CSoftwareRenderTarget2()
{ {
if (Textures[0]) if (Textures[0])
Textures[0]->drop(); Textures[0]->drop();
if (DepthStencil)
DepthStencil->drop();
} }
void CSoftwareRenderTarget2::setTextures(ITexture* const * textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces) void CSoftwareRenderTarget2::setTextures(ITexture* const* textures, u32 numTextures, ITexture* depthStencil, const E_CUBE_SURFACE* cubeSurfaces, u32 numCubeSurfaces)
{ {
if (!Textures.equals(textures, numTextures)) if (!Textures.equals(textures, numTextures))
{ {
@ -421,8 +473,41 @@ void CSoftwareRenderTarget2::setTextures(ITexture* const * textures, u32 numText
if (!textureDetected) if (!textureDetected)
Textures[0] = 0; Textures[0] = 0;
} }
}
// Set depth and stencil attachments.
if (DepthStencil != depthStencil)
{
if (DepthStencil)
{
DepthStencil->drop();
DepthStencil = 0;
}
CSoftwareTexture2* currentTexture = (depthStencil && depthStencil->getDriverType() == DriverType) ? static_cast<CSoftwareTexture2*>(depthStencil) : 0;
if (currentTexture)
{
if (currentTexture->getType() == ETT_2D)
{
const ECOLOR_FORMAT textureFormat = currentTexture->getOriginalColorFormat();
if (IImage::isDepthFormat(textureFormat))
{
DepthStencil = depthStencil;
DepthStencil->grab();
}
else
{
os::Printer::log("Ignoring depth/stencil texture without depth color format.", ELL_WARNING);
}
}
else
{
os::Printer::log("This driver doesn't support depth/stencil to cubemaps.", ELL_WARNING);
}
}
}
}
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,
@ -490,11 +575,28 @@ static const float srgb_8bit_to_linear_float[1 << 8] = {
0.9386857f, 0.9473065f, 0.9559733f, 0.9646863f, 0.9386857f, 0.9473065f, 0.9559733f, 0.9646863f,
0.9734453f, 0.9822506f, 0.9911021f, 1.0f, 0.9734453f, 0.9822506f, 0.9911021f, 1.0f,
}; };
/*
#if 0
static void buildtable()
{
//sRGB x <= 0.0031308 ? x * 12.92 : (1.055 * pow(x, 1/2.4)) - 0.055
//Rec709 x < 0.018 ? (x * 4.5) : 1.099 * pow( x, (0.45) ) - 0.099
printf("static const float srgb_8bit_to_linear_float[1 << 8] = {");
for (int i = 0; i <= 255; ++i)
{
double x = i / 255.0;
double linear = x < 0.04045 ? x / 12.92 : pow((x + 0.055) / 1.055, 2.4);
linear = pow(x, 2.2);
printf("%s%0.10lff", i & 7 ? "," : ",\n\t", linear);
}
printf("\n};");
}
int linear_to_srgb_8bit(const float x) { int linear_to_srgb_8bit(const float x) {
if (x <= 0.f) return 0; if (x <= 0.f) return 0;
if (x >= 1.f) return 255; if (x >= 1.f) return 255;
const float *table = SRGB_8BIT_TO_LINEAR_FLOAT; const float* table = SRGB_8BIT_TO_LINEAR_FLOAT;
int y = 0; int y = 0;
for (int i = 128; i != 0; i >>= 1) { for (int i = 128; i != 0; i >>= 1) {
if (table[y + i] <= x) if (table[y + i] <= x)
@ -505,24 +607,28 @@ int linear_to_srgb_8bit(const float x) {
else else
return y + 1; return y + 1;
} }
*/ #endif
u32 linear_to_srgb_8bit(const float v) u32 linear_to_srgb_8bit(const float v)
{ {
if (v <= 0.f) return 0;
else if (v >= 1.f) return 255;
ieee754 c; ieee754 c;
c.f = v; c.f = v;
const size_t x = c.u; const u32 x = c.u;
const u32* table = (u32*)srgb_8bit_to_linear_float; const u32* table = (const 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;
y += table[y + 32] <= x ? 32 : 0; y |= table[y | 32] <= x ? 32 : 0;
y += table[y + 16] <= x ? 16 : 0; y |= table[y | 16] <= x ? 16 : 0;
y += table[y + 8] <= x ? 8 : 0; y |= table[y | 8] <= x ? 8 : 0;
y += table[y + 4] <= x ? 4 : 0; y |= table[y | 4] <= x ? 4 : 0;
y += table[y + 2] <= x ? 2 : 0; y |= table[y | 2] <= x ? 2 : 0;
y += table[y + 1] <= x ? 1 : 0; y |= table[y | 1] <= x ? 1 : 0;
if (srgb_8bit_to_linear_float[y + 1] - x < v - srgb_8bit_to_linear_float[y])
y += 1;
return y; return y;
} }
@ -579,41 +685,47 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
const int dst_sRGB = dst->get_sRGB(); const int dst_sRGB = dst->get_sRGB();
const int src_sRGB = src->get_sRGB(); const int src_sRGB = src->get_sRGB();
#else #else
//assuming sRGB as default
const int dst_sRGB = (flags & CSoftwareTexture2::TEXTURE_IS_LINEAR) ? 0 : 1; const int dst_sRGB = (flags & CSoftwareTexture2::TEXTURE_IS_LINEAR) ? 0 : 1;
const int src_sRGB = (flags & CSoftwareTexture2::IMAGE_IS_LINEAR) ? 0 : 1; const int src_sRGB = (flags & CSoftwareTexture2::IMAGE_IS_LINEAR) ? 0 : 1;
#endif #endif
#define ft float
ft scale[2];
scale[0] = (ft)(sc.x1 - sc.x0) / (ft)(dc.x1 - dc.x0);
scale[1] = (ft)(sc.y1 - sc.y0) / (ft)(dc.y1 - dc.y0);
if (scale[0] < (ft)1 && scale[1] < (ft)1)
{
//magnify
}
//unweighted box filter
const ft rs = (ft)1.0 / (scale[0] * scale[1]);
float scale[2]; ft sum[4];
scale[0] = (float)(sc.x1 - sc.x0) / (float)(dc.x1 - dc.x0);
scale[1] = (float)(sc.y1 - sc.y0) / (float)(dc.y1 - dc.y0);
const float rs = 1.f / (scale[0] * scale[1]);
float sum[4];
u32 sbgra = 0; u32 sbgra = 0;
float f[4]; ft f[4];
int fi[4]; int fi[4];
f[3] = (float)sc.y0; f[3] = (ft)sc.y0;
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 - (ft)0.001; //todo:1.f/dim should be enough
f[2] = (float)sc.x0; f[2] = (ft)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 - (ft)0.001;
//accumulate linear color //accumulate linear color
sum[0] = 0.f; sum[0] = (ft)0;
sum[1] = 0.f; sum[1] = (ft)0;
sum[2] = 0.f; sum[2] = (ft)0;
sum[3] = 0.f; sum[3] = (ft)0;
//sample border //sample border
fi[0] = (int)(f[0]); fi[0] = (int)(f[0]);
@ -621,20 +733,20 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
fi[2] = (int)(f[2]); fi[2] = (int)(f[2]);
fi[3] = (int)(f[3]); fi[3] = (int)(f[3]);
float w[2]; ft w[2];
for (int fy = fi[1]; fy <= fi[3]; ++fy) for (int fy = fi[1]; fy <= fi[3]; ++fy)
{ {
w[1] = 1.f; w[1] = (ft)1;
if (fy == fi[1]) w[1] -= f[1] - fy; if (fy == fi[1]) w[1] -= f[1] - fy;
if (fy == fi[3]) w[1] -= fy + 1 - f[3]; if (fy == fi[3]) w[1] -= fy + 1 - f[3];
for (int fx = fi[0]; fx <= fi[2]; ++fx) for (int fx = fi[0]; fx <= fi[2]; ++fx)
{ {
w[0] = 1.f; w[0] = (ft)1;
if (fx == fi[0]) w[0] -= f[0] - fx; if (fx == fi[0]) w[0] -= f[0] - fx;
if (fx == fi[2]) w[0] -= fx + 1 - f[2]; if (fx == fi[2]) w[0] -= fx + 1 - f[2];
const float ws = w[1] * w[0] * rs; const ft ws = w[1] * w[0] * rs;
switch (srcFormat) switch (srcFormat)
{ {
@ -675,17 +787,25 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
} }
if (dst_sRGB) if (dst_sRGB)
{ {
sbgra = linear_to_srgb_8bit(sum[0]) | sbgra = linear_to_srgb_8bit((float)sum[0]) |
linear_to_srgb_8bit(sum[1]) << 8 | linear_to_srgb_8bit((float)sum[1]) << 8 |
linear_to_srgb_8bit(sum[2]) << 16 | linear_to_srgb_8bit((float)sum[2]) << 16 |
(u32)(sum[3]) << 24; (u32)(sum[3]) << 24;
} }
else else
{ {
u32 b = core::s32_clamp((int)floor(sum[0] + (ft)0.5), 0, 255);
u32 g = core::s32_clamp((int)floor(sum[1] + (ft)0.5), 0, 255);
u32 r = core::s32_clamp((int)floor(sum[2] + (ft)0.5), 0, 255);
u32 a = core::s32_clamp((int)floor(sum[3] + (ft)0.5), 0, 255);
sbgra = b | (g << 8) | (r << 16) | (a << 24);
/*
sbgra = (u32)(sum[0]) | sbgra = (u32)(sum[0]) |
(u32)(sum[1]) << 8 | (u32)(sum[1]) << 8 |
(u32)(sum[2]) << 16 | (u32)(sum[2]) << 16 |
(u32)(sum[3]) << 24; (u32)(sum[3]) << 24;
*/
} }
switch (dstFormat) switch (dstFormat)
{ {
@ -704,10 +824,9 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
} }
} }
} }
#undef ft
} }
} // end namespace video burning_namespace_end
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

@ -27,12 +27,25 @@ class CBurningVideoDriver;
*/ */
struct CSoftwareTexture2_Bound struct CSoftwareTexture2_Bound
{ {
f32 w; // width - 0.5f; //[0.5 / width, 1 - 0.5 / width]
f32 h; // height- 0.5f; //int dim[2];
f32 cx; // texelcenter x 1.f/width*0.5f f32 mat[4];
f32 cy; // texelcenter y 1.f/height*0.5f
u32 area; // width * height
}; };
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
//! Enumeration describing the type of ITexture.
enum E_TEXTURE_TYPE
{
//! 2D texture.
ETT_2D,
//! Cubemap texture.
ETT_CUBEMAP
};
#endif
class CSoftwareTexture2 : public ITexture class CSoftwareTexture2 : public ITexture
{ {
public: public:
@ -57,7 +70,8 @@ public:
if ( newLevel < 0 ) newLevel = 0; if ( newLevel < 0 ) newLevel = 0;
else if ( newLevel >= (s32)array_size(MipMap)) newLevel = array_size(MipMap) - 1; else if ( newLevel >= (s32)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;
} }
@ -83,20 +97,6 @@ public:
virtual void unlock() IRR_OVERRIDE virtual void unlock() IRR_OVERRIDE
{ {
} }
/*
//! compare the area drawn with the area of the texture
f32 getLODFactor( const f32 texArea ) const
{
return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;
//return MipMap[0]->getImageDataSizeInPixels () * texArea;
}
*/
const u32* getMipMap0_Area() const
{
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
@ -115,6 +115,10 @@ public:
{ {
return TexBound[MipMapLOD]; return TexBound[MipMapLOD];
} }
const CSoftwareTexture2_Bound* getTexBound_index() const
{
return TexBound;
}
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #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;
@ -124,15 +128,17 @@ public:
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; }; const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; }
const core::dimension2d<u32>& getSize() const { return Size; }; const core::dimension2d<u32>& getSize() const { return Size; }
E_DRIVER_TYPE getDriverType() const { return DriverType; }; E_DRIVER_TYPE getDriverType() const { return DriverType; }
ECOLOR_FORMAT getColorFormat() const { return ColorFormat; }; ECOLOR_FORMAT getColorFormat() const { return ColorFormat; }
ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; }; ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; }
u32 getPitch() const { return Pitch; }; u32 getPitch() const { return Pitch; };
bool hasMipMaps() const { return HasMipMaps; } bool hasMipMaps() const { return HasMipMaps; }
bool isRenderTarget() const { return IsRenderTarget; } bool isRenderTarget() const { return IsRenderTarget; }
E_TEXTURE_TYPE getType() const { return Type; }
core::dimension2d<u32> OriginalSize; core::dimension2d<u32> OriginalSize;
core::dimension2d<u32> Size; core::dimension2d<u32> Size;
E_DRIVER_TYPE DriverType; E_DRIVER_TYPE DriverType;
@ -141,6 +147,7 @@ public:
u32 Pitch; u32 Pitch;
bool HasMipMaps; bool HasMipMaps;
bool IsRenderTarget; bool IsRenderTarget;
E_TEXTURE_TYPE Type;
#endif #endif
private: private:
@ -153,8 +160,10 @@ 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];
f32 LodBIAS; // Tweak mipmap selection //Helper pointer for regenerateMipMapLevels (do not store per texture)
static const IImage* original_mip0;
}; };
/*! /*!
@ -170,7 +179,8 @@ public:
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
E_DRIVER_TYPE DriverType; E_DRIVER_TYPE DriverType;
core::array<ITexture*> Texture; core::array<ITexture*> Textures;
ITexture* DepthStencil;
#endif #endif
protected: protected:

@ -274,7 +274,7 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -348,8 +348,8 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -418,7 +418,7 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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,8 +509,8 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -579,7 +579,7 @@ void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVer
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -216,7 +216,7 @@ void CTRGouraudAlpha2::fragmentShader()
{ {
#ifdef IPOL_C0 #ifdef IPOL_C0
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = reciprocal_zero_no ( line.w[0] ); inversew = reciprocal_zero( line.w[0] );
#endif #endif
vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew ); vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );
@ -227,7 +227,7 @@ void CTRGouraudAlpha2::fragmentShader()
g2 = g1 + imulFix ( a0, g0 - g1 ); g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 ); b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_sample( a0,r2, g2, b2 ); dst[i] = fix_to_sample( r2, g2, b2 );
#else #else
dst[i] = PrimitiveColor; dst[i] = PrimitiveColor;
#endif #endif
@ -285,7 +285,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -359,8 +359,8 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -428,7 +428,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -518,8 +518,8 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -587,7 +587,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -286,7 +286,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -359,8 +359,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -428,7 +428,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -518,8 +518,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
@ -588,7 +588,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -636,7 +636,7 @@ namespace video
//! creates a flat triangle renderer //! creates a flat triangle renderer
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver) IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
{ {
//ETR_GOURAUD_ALPHA_NOZ - draw2DRectangle Gradient // ETR_GOURAUD_ALPHA_NOZ - draw2DRectangle Gradient
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlphaNoZ2(driver); return new CTRGouraudAlphaNoZ2(driver);
#else #else

@ -272,7 +272,7 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -346,8 +346,8 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -417,7 +417,7 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -507,8 +507,8 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -577,7 +577,7 @@ void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4D
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -44,49 +44,45 @@
// apply global override // apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W #undef INVERSE_W
#endif #endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL #ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL #undef SUBTEXEL
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS < 1 #if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0 #undef IPOL_C0
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS < 2 #if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1 #undef IPOL_C1
#endif #endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1 #if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
#undef IPOL_L0 #undef IPOL_L0
#endif #endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W #undef IPOL_W
#endif #endif
#define IPOL_Z #define IPOL_Z
#ifdef CMP_W #ifdef CMP_W
#undef CMP_W #undef CMP_W
#define CMP_Z #define CMP_Z
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
#undef WRITE_W #undef WRITE_W
#define WRITE_Z #define WRITE_Z
#endif #endif
#endif #endif
namespace irr burning_namespace_start
{
namespace video
{
class CTRNormalMap : public IBurningShader class CTRNormalMap : public IBurningShader
@ -107,11 +103,11 @@ private:
//! constructor //! constructor
CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver) CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver)
: IBurningShader(driver) : IBurningShader(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTRNormalMap"); setDebugName("CTRNormalMap");
#endif #endif
} }
@ -123,10 +119,10 @@ void CTRNormalMap::OnSetMaterial(const SBurningShaderMaterial& material)
*/ */
void CTRNormalMap::fragmentShader() void CTRNormalMap::fragmentShader()
{ {
tVideoSample *dst; tVideoSample* dst;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
fp24 *z; fp24* z;
#endif #endif
s32 xStart; s32 xStart;
@ -155,16 +151,16 @@ void CTRNormalMap::fragmentShader()
#endif #endif
// apply top-left fill-convention, left // apply top-left fill-convention, left
xStart = fill_convention_left( line.x[0] ); xStart = fill_convention_left(line.x[0]);
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 = fill_step_x( 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;
@ -192,7 +188,7 @@ void CTRNormalMap::fragmentShader()
#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
@ -220,10 +216,10 @@ void CTRNormalMap::fragmentShader()
#endif #endif
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart; dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif #endif
@ -246,7 +242,7 @@ void CTRNormalMap::fragmentShader()
#ifdef IPOL_C0 #ifdef IPOL_C0
tFixPoint a3,r3, g3, b3; tFixPoint a3, r3, g3, b3;
#endif #endif
#ifdef IPOL_C1 #ifdef IPOL_C1
@ -254,112 +250,112 @@ void CTRNormalMap::fragmentShader()
#endif #endif
for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X) 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
{ {
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] ); inversew = fix_inverse32(line.w[0]);
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
//vertex alpha blend ( and omit depthwrite ,hacky..) //vertex alpha blend ( and omit depthwrite ,hacky..)
a3 = tofix(line.c[0][0].x, inversew); a3 = tofix(line.c[0][0].a, inversew);
if (a3 + 2 >= FIX_POINT_ONE) if (a3 + 2 >= FIX_POINT_ONE)
{ {
#ifdef WRITE_Z #ifdef WRITE_Z
z[i] = line.z[0]; z[i] = line.z[0];
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
z[i] = line.w[0]; z[i] = line.w[0];
#endif #endif
} }
#endif #endif
#ifdef IPOL_C1 #ifdef IPOL_C1
//complete inside fog //complete inside fog
if (TL_Flag & TL_FOG) if (TL_Flag & TL_FOG)
{
aFog = tofix(line.c[1][0].a, inversew);
if (aFog <= 0)
{ {
dst[i] = fog_color_sample; aFog = tofix(line.c[1][0].a, inversew);
continue; if (aFog <= 0)
{
dst[i] = fog_color_sample;
continue;
}
} }
}
#endif #endif
tx0 = tofix ( line.t[0][0].x,inversew); tx0 = tofix(line.t[0][0].x, inversew);
ty0 = tofix ( line.t[0][0].y,inversew); ty0 = tofix(line.t[0][0].y, inversew);
tx1 = tofix ( line.t[1][0].x,inversew); tx1 = tofix(line.t[1][0].x, inversew);
ty1 = tofix ( line.t[1][0].y,inversew); ty1 = tofix(line.t[1][0].y, inversew);
// diffuse map // diffuse map
getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 ); getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);
// normal map ( same texcoord0 but different mipmapping) // normal map ( same texcoord0 but different mipmapping)
getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 ); getSample_texture(r1, g1, b1, &IT[1], tx1, ty1);
r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1); r1 = (r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2 - 1);
g1 = ( g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1); g1 = (g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2 - 1);
b1 = ( b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1); b1 = (b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2 - 1);
#ifdef IPOL_L0 #ifdef IPOL_L0
lx = tofix ( line.l[0][0].x, inversew ); lx = tofix(line.l[0][0].x, inversew);
ly = tofix ( line.l[0][0].y, inversew ); ly = tofix(line.l[0][0].y, inversew);
lz = tofix ( line.l[0][0].z, inversew ); lz = tofix(line.l[0][0].z, inversew);
// DOT 3 Normal Map light in tangent space // DOT 3 Normal Map light in tangent space
//max(dot(LightVector, Normal), 0.0); //max(dot(LightVector, Normal), 0.0);
ndotl = clampfix_mincolor( (imulFix_simple(r1,lx) + imulFix_simple(g1,ly) + imulFix_simple(b1,lz) ) ); ndotl = clampfix_mincolor((imulFix_simple(r1, lx) + imulFix_simple(g1, ly) + imulFix_simple(b1, lz)));
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
//LightColor[0] //LightColor[0]
r3 = tofix(line.c[0][0].y, inversew); r3 = tofix(line.c[0][0].r, inversew);
g3 = tofix(line.c[0][0].z, inversew); g3 = tofix(line.c[0][0].g, inversew);
b3 = tofix(line.c[0][0].w, inversew); b3 = tofix(line.c[0][0].b, inversew);
// Lambert * LightColor[0] * Diffuse Texture; // Lambert * LightColor[0] * Diffuse Texture;
r2 = imulFix (imulFix_simple( r3, ndotl ), r0 ); r2 = imulFix(imulFix_simple(r3, ndotl), r0);
g2 = imulFix (imulFix_simple( g3, ndotl ), g0 ); g2 = imulFix(imulFix_simple(g3, ndotl), g0);
b2 = imulFix (imulFix_simple( b3, ndotl ), b0 ); b2 = imulFix(imulFix_simple(b3, ndotl), b0);
//vertex alpha blend ( and omit depthwrite ,hacky..) //vertex alpha blend ( and omit depthwrite ,hacky..)
if (a3 + 2 < FIX_POINT_ONE) if (a3 + 2 < FIX_POINT_ONE)
{ {
color_to_fix(r1, g1, b1, dst[i]); color_to_fix(r1, g1, b1, dst[i]);
r2 = r1 + imulFix(a3, r2 - r1); r2 = r1 + imulFix(a3, r2 - r1);
g2 = g1 + imulFix(a3, g2 - g1); g2 = g1 + imulFix(a3, g2 - g1);
b2 = b1 + imulFix(a3, b2 - b1); b2 = b1 + imulFix(a3, b2 - b1);
} }
#ifdef IPOL_C1 #ifdef IPOL_C1
//mix with distance //mix with distance
if (aFog < FIX_POINT_ONE) if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)
{ {
r2 = fog_color[1] + imulFix(aFog, r2 - fog_color[1]); r2 = fog_color[1] + imulFix(aFog, r2 - fog_color[1]);
g2 = fog_color[2] + imulFix(aFog, g2 - fog_color[2]); g2 = fog_color[2] + imulFix(aFog, g2 - fog_color[2]);
b2 = fog_color[3] + imulFix(aFog, b2 - fog_color[3]); b2 = fog_color[3] + imulFix(aFog, b2 - fog_color[3]);
} }
#endif #endif
dst[i] = fix_to_sample(r2, g2, b2); dst[i] = fix_to_sample(r2, g2, b2);
#else #else
r2 = imulFix_tex4 ( r0, r1 ); r2 = imulFix_tex4(r0, r1);
g2 = imulFix_tex4 ( g0, g1 ); g2 = imulFix_tex4(g0, g1);
b2 = imulFix_tex4 ( b0, b1 ); b2 = imulFix_tex4(b0, b1);
dst[i] = fix_to_sample(r2, g2, b2); dst[i] = fix_to_sample(r2, g2, b2);
#endif #endif
} }
#ifdef IPOL_Z #ifdef IPOL_Z
line.z[0] += slopeZ; line.z[0] += slopeZ;
@ -392,19 +388,19 @@ void CTRNormalMap::fragmentShader()
void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{ {
// sort on height, y // sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); if (F32_A_GREATER_B(b->Pos.y, c->Pos.y)) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y; const f32 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] = fill_step_y( ca ); scan.invDeltaY[0] = fill_step_y(ca);
scan.invDeltaY[1] = fill_step_y( ba ); scan.invDeltaY[1] = fill_step_y(ba);
scan.invDeltaY[2] = fill_step_y( 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;
// find if the major edge is left or right aligned // find if the major edge is left or right aligned
@ -415,7 +411,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -472,7 +468,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
// rasterize upper sub-triangle // rasterize upper sub-triangle
if ( F32_GREATER_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];
@ -519,11 +515,11 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top(a->Pos.y);
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down(b->Pos.y);
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ((f32)yStart) - a->Pos.y;
// correct to pixel center // correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel; scan.x[0] += scan.slopeX[0] * subPixel;
@ -572,7 +568,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 += SOFTWARE_DRIVER_2_STEP_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 +614,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader (); if_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];
@ -667,10 +663,10 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) ) if (F32_GREATER_0(scan.invDeltaY[2]))
{ {
// advance to middle point // advance to middle point
if ( F32_GREATER_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
@ -747,11 +743,11 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top(b->Pos.y);
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down(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
scan.x[0] += scan.slopeX[0] * subPixel; scan.x[0] += scan.slopeX[0] * subPixel;
@ -800,7 +796,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 += SOFTWARE_DRIVER_2_STEP_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];
@ -846,7 +842,7 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -895,31 +891,20 @@ void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVe
} }
burning_namespace_end
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr burning_namespace_start
{
namespace video
{
//! creates a triangle renderer //! creates a triangle renderer
IBurningShader* createTRNormalMap(CBurningVideoDriver* driver) IBurningShader* createTRNormalMap(CBurningVideoDriver* driver)
{ {
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRNormalMap(driver); return new CTRNormalMap(driver);
#else #else
return 0; return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
} }
burning_namespace_end
} // end namespace video
} // end namespace irr

@ -241,7 +241,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -334,8 +334,8 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -423,7 +423,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader (); if_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];
@ -541,8 +541,8 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -630,7 +630,7 @@ void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader (); if_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];

@ -125,7 +125,7 @@ void CTRTextureBlend::OnSetMaterial(const SBurningShaderMaterial& material)
int showname = 0; int showname = 0;
depth_func = (E_COMPARISON_FUNC)material.org.ZBuffer; depth_func = (E_COMPARISON_FUNC)material.org.ZBuffer;
AlphaRef = 0; // tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX); AlphaRef = 0; // tofix(material.org.MaterialTypeParam, FIX_POINT_COLOR_MAX);
E_BLEND_FACTOR srcFact,dstFact; E_BLEND_FACTOR srcFact,dstFact;
E_MODULATE_FUNC modulate; E_MODULATE_FUNC modulate;
@ -2201,7 +2201,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -2274,8 +2274,8 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -2343,7 +2343,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// render a scanline // render a scanline
interlace_scanline (this->*fragmentShader) (); if_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];
@ -2433,8 +2433,8 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -2502,7 +2502,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif #endif
// render a scanline // render a scanline
interlace_scanline (this->*fragmentShader) (); if_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];

@ -85,7 +85,7 @@ 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 bool canWireFrame () IRR_OVERRIDE { return true; } virtual bool canWireFrame () IRR_OVERRIDE { return false; } // not that ready
protected: protected:
virtual void fragmentShader(); virtual void fragmentShader();
@ -284,7 +284,7 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -357,8 +357,8 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -427,7 +427,7 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -461,6 +461,7 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
} }
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if (F32_GREATER_0(scan.invDeltaY[2]) ) if (F32_GREATER_0(scan.invDeltaY[2]) )
{ {
@ -518,8 +519,8 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -589,7 +590,7 @@ void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -313,7 +313,7 @@ void CTRTextureGouraud2::fragmentShader ()
b0 = clampfix_maxcolor(b1 + b0); b0 = clampfix_maxcolor(b1 + b0);
} }
//mix with distance //mix with distance
if (aFog < FIX_POINT_ONE) if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)
{ {
r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]); r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);
g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]); g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);
@ -397,7 +397,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -500,8 +500,8 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -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
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_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];
@ -600,7 +601,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader (); if_interlace_scanline fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
@ -731,8 +732,8 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -782,9 +783,9 @@ 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
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_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];
@ -831,7 +832,7 @@ void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader (); if_interlace_scanline fragmentShader ();
if ( EdgeTestPass & edge_test_first_line ) break; if ( EdgeTestPass & edge_test_first_line ) break;
@ -908,5 +909,3 @@ IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* drive
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr

@ -128,7 +128,7 @@ void CTRTextureGouraudAdd2::fragmentShader()
fp24 slopeW; fp24 slopeW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
sVec4 slopeC; sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
@ -153,7 +153,7 @@ void CTRTextureGouraudAdd2::fragmentShader()
slopeW = (line.w[1] - line.w[0]) * invDeltaX; slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
slopeC = (line.c[1] - line.c[0]) * invDeltaX; slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@ -171,7 +171,7 @@ void CTRTextureGouraudAdd2::fragmentShader()
line.w[0] += slopeW * subPixel; line.w[0] += slopeW * subPixel;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0] += slopeC * subPixel; line.c[0][0] += slopeC[0] * subPixel;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel; line.t[0][0] += slopeT[0] * subPixel;
@ -257,7 +257,7 @@ void CTRTextureGouraudAdd2::fragmentShader()
line.w[0] += slopeW; line.w[0] += slopeW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0] += slopeC; line.c[0][0] += slopeC[0];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0]; line.t[0][0] += slopeT[0];
@ -292,7 +292,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -310,8 +310,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0]; scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0]; scan.c[0][0] = a->Color[0];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -350,8 +350,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1]; scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0]; scan.c[0][1] = a->Color[0];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -365,8 +365,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -386,8 +386,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel; scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -419,8 +419,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[scan.left] = scan.c[0]; line.c[0][scan.left] = scan.c[0][0];
line.c[scan.right] = scan.c[1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -434,7 +434,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -450,8 +450,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0] += scan.slopeC[0]; scan.c[0][0] += scan.slopeC[0][0];
scan.c[1] += scan.slopeC[1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -483,7 +483,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
@ -509,8 +509,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0]; scan.c[0][1] = b->Color[0];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -524,8 +524,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
@ -546,8 +546,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel; scan.c[0][0] += scan.slopeC[0][0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -579,8 +579,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[scan.left] = scan.c[0]; line.c[0][scan.left] = scan.c[0][0];
line.c[scan.right] = scan.c[1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
@ -594,7 +594,7 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -610,8 +610,8 @@ void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0] += scan.slopeC[0]; scan.c[0][0] += scan.slopeC[0][0];
scan.c[1] += scan.slopeC[1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0

@ -228,9 +228,9 @@ void CTRTextureGouraudAddNoZ2::fragmentShader()
if (r0 | g0 | b0) if (r0 | g0 | b0)
{ {
color_to_fix(r1, g1, b1, dst[i]); color_to_fix(r1, g1, b1, dst[i]);
r1 = imulFix_tex1(r1, FIXPOINT_COLOR_MAX - r0); r1 = imulFix_tex1(r1, FIX_POINT_COLOR_MAX - r0);
g1 = imulFix_tex1(g1, FIXPOINT_COLOR_MAX - g0); g1 = imulFix_tex1(g1, FIX_POINT_COLOR_MAX - g0);
b1 = imulFix_tex1(b1, FIXPOINT_COLOR_MAX - b0); b1 = imulFix_tex1(b1, FIX_POINT_COLOR_MAX - b0);
dst[i] = fix_to_sample(r0+r1, g0+g1, b0+b1); dst[i] = fix_to_sample(r0+r1, g0+g1, b0+b1);
} }
@ -290,7 +290,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -363,8 +363,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -432,7 +432,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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,8 +522,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -591,7 +591,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -21,6 +21,7 @@
#undef INVERSE_W #undef INVERSE_W
#undef IPOL_C0 #undef IPOL_C0
#undef IPOL_C1
#undef IPOL_T0 #undef IPOL_T0
#undef IPOL_T1 #undef IPOL_T1
@ -34,6 +35,7 @@
#define WRITE_W #define WRITE_W
#define IPOL_C0 #define IPOL_C0
#define IPOL_C1
#define IPOL_T0 #define IPOL_T0
//#define IPOL_T1 //#define IPOL_T1
@ -50,6 +52,10 @@
#undef IPOL_C0 #undef IPOL_C0
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W #undef IPOL_W
@ -109,7 +115,7 @@ void CTRTextureGouraudAlpha2::OnSetMaterial(const SBurningShaderMaterial& materi
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f); AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);
#else #else
AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX); AlphaRef = tofix(material.org.MaterialTypeParam, FIX_POINT_COLOR_MAX);
#endif #endif
} }
@ -166,6 +172,9 @@ void CTRTextureGouraudAlpha2::fragmentShader()
#ifdef IPOL_C0 #ifdef IPOL_C0
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX; slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif #endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
#endif #endif
@ -184,6 +193,9 @@ void CTRTextureGouraudAlpha2::fragmentShader()
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0][0] += slopeC[0] * subPixel; line.c[0][0] += slopeC[0] * subPixel;
#endif #endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel; line.t[0][0] += slopeT[0] * subPixel;
#endif #endif
@ -211,6 +223,11 @@ void CTRTextureGouraudAlpha2::fragmentShader()
tFixPoint r1, g1, b1; tFixPoint r1, g1, b1;
tFixPoint r2, g2, b2; tFixPoint r2, g2, b2;
#endif #endif
#ifdef IPOL_C1
tFixPoint aFog = FIX_POINT_ONE;
#endif
#endif #endif
for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X) for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
@ -255,6 +272,22 @@ void CTRTextureGouraudAlpha2::fragmentShader()
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] ); inversew = fix_inverse32 ( line.w[0] );
#endif #endif
#ifdef IPOL_C1
#if 0
//complete inside fog
if (TL_Flag & TL_FOG)
{
aFog = tofix(line.c[1][0].a, inversew);
if (aFog <= 0)
{
dst[i] = fog_color_sample;
continue;
}
}
#endif
#endif
getSample_texture ( a0,r0,g0,b0, getSample_texture ( a0,r0,g0,b0,
&IT[0], &IT[0],
tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].x,inversew),
@ -278,6 +311,26 @@ void CTRTextureGouraudAlpha2::fragmentShader()
g0 = imulFix_simple( g0, g2 ); g0 = imulFix_simple( g0, g2 );
b0 = imulFix_simple( b0, b2 ); b0 = imulFix_simple( b0, b2 );
#ifdef IPOL_C1
//specular highlight
if (TL_Flag & TL_SPECULAR)
{
vec4_to_fix(r1, g1, b1, line.c[1][0], inversew * COLOR_MAX);
r0 = clampfix_maxcolor(r1 + r0);
g0 = clampfix_maxcolor(g1 + g0);
b0 = clampfix_maxcolor(b1 + b0);
}
#if 0
//mix with distance
if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)
{
r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);
g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);
b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);
}
#endif
#endif
color_to_fix ( r1, g1, b1, dst[i] ); color_to_fix ( r1, g1, b1, dst[i] );
fix_color_norm(a0); fix_color_norm(a0);
@ -285,7 +338,7 @@ void CTRTextureGouraudAlpha2::fragmentShader()
r2 = r1 + imulFix ( a0, r0 - r1 ); r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 ); g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 ); b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_sample( a0, r2, g2, b2 ); dst[i] = fix_to_sample( r2, g2, b2 );
/* /*
getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX ); getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );
@ -316,6 +369,9 @@ void CTRTextureGouraudAlpha2::fragmentShader()
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0][0] += slopeC[0]; line.c[0][0] += slopeC[0];
#endif #endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0]; line.t[0][0] += slopeT[0];
#endif #endif
@ -352,7 +408,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -374,6 +430,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
scan.c[0][0] = a->Color[0]; scan.c[0][0] = a->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0]; scan.t[0][0] = a->Tex[0];
@ -414,6 +475,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
scan.c[0][1] = a->Color[0]; scan.c[0][1] = a->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0]; scan.t[0][1] = a->Tex[0];
@ -425,8 +491,8 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -450,6 +516,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
scan.c[0][1] += scan.slopeC[0][1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -483,6 +554,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
line.c[0][scan.right] = scan.c[0][1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1]; line.t[0][scan.right] = scan.t[0][1];
@ -494,7 +570,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -514,6 +590,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
scan.c[0][1] += scan.slopeC[0][1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1]; scan.t[0][1] += scan.slopeT[0][1];
@ -545,6 +626,9 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif #endif
@ -573,6 +657,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
scan.c[0][1] = b->Color[0]; scan.c[0][1] = b->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0]; scan.t[0][1] = b->Tex[0];
@ -584,8 +673,8 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -609,6 +698,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
scan.c[0][1] += scan.slopeC[0][1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -642,6 +736,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
line.c[0][scan.right] = scan.c[0][1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1]; line.t[0][scan.right] = scan.t[0][1];
@ -653,7 +752,7 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -673,6 +772,11 @@ void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a,
scan.c[0][1] += scan.slopeC[0][1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1]; scan.t[0][1] += scan.slopeT[0][1];

@ -75,12 +75,7 @@
#endif #endif
burning_namespace_start
namespace irr
{
namespace video
{
class CTRTextureGouraudAlphaNoZ : public IBurningShader class CTRTextureGouraudAlphaNoZ : public IBurningShader
{ {
@ -98,7 +93,7 @@ private:
// fragment shader // fragment shader
typedef void (CTRTextureGouraudAlphaNoZ::*tFragmentShader) (); typedef void (CTRTextureGouraudAlphaNoZ::*tFragmentShader) ();
void fragment_linear(); void fragment_linear();
void fragment_linear_test(); void fragment_linear_alpharef();
void fragment_point_noz(); void fragment_point_noz();
tFragmentShader fragmentShader; tFragmentShader fragmentShader;
@ -125,13 +120,13 @@ void CTRTextureGouraudAlphaNoZ::OnSetMaterial(const SBurningShaderMaterial& mate
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f); AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);
#else #else
AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX); AlphaRef = tofix(material.org.MaterialTypeParam, FIX_POINT_COLOR_MAX);
#endif #endif
//check triangle on w = 1.f instead.. //check triangle on w = 1.f instead..
#ifdef SOFTWARE_DRIVER_2_BILINEAR #ifdef SOFTWARE_DRIVER_2_BILINEAR
if (material.Fallback_MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL_REF) if (material.Fallback_MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)
fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear_test; fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear_alpharef;
else else
if ( material.org.TextureLayer[0].BilinearFilter ) if ( material.org.TextureLayer[0].BilinearFilter )
fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear; fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;
@ -262,7 +257,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_scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -326,7 +321,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
r2 = r1 + imulFix ( a0, r0 - r1 ); r2 = r1 + imulFix ( a0, r0 - r1 );
g2 = g1 + imulFix ( a0, g0 - g1 ); g2 = g1 + imulFix ( a0, g0 - g1 );
b2 = b1 + imulFix ( a0, b0 - b1 ); b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_sample( a0, r2, g2, b2 ); dst[i] = fix_to_sample( r2, g2, b2 );
#else #else
dst[i] = PixelBlend32 ( dst[i], dst[i] = PixelBlend32 ( dst[i],
@ -364,7 +359,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear()
/*! /*!
*/ */
void CTRTextureGouraudAlphaNoZ::fragment_linear_test() void CTRTextureGouraudAlphaNoZ::fragment_linear_alpharef()
{ {
tVideoSample *dst; tVideoSample *dst;
@ -482,7 +477,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_scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -546,7 +541,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_linear_test()
r2 = r1 + imulFix(a0, r0 - r1); r2 = r1 + imulFix(a0, r0 - r1);
g2 = g1 + imulFix(a0, g0 - g1); g2 = g1 + imulFix(a0, g0 - g1);
b2 = b1 + imulFix(a0, b0 - b1); b2 = b1 + imulFix(a0, b0 - b1);
dst[i] = fix4_to_sample(a0, r2, g2, b2); dst[i] = fix_to_sample(r2, g2, b2);
#else #else
dst[i] = PixelBlend32(dst[i], dst[i] = PixelBlend32(dst[i],
@ -702,7 +697,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
#ifdef CMP_W #ifdef CMP_W
// if (line.w[0] >= z[i]) // if (line.w[0] >= z[i])
#endif #endif
scissor_test_x if_scissor_test_x
{ {
#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff #if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff
@ -766,7 +761,7 @@ void CTRTextureGouraudAlphaNoZ::fragment_point_noz()
r2 = r1 + imulFix(a0, r0 - r1); r2 = r1 + imulFix(a0, r0 - r1);
g2 = g1 + imulFix(a0, g0 - g1); g2 = g1 + imulFix(a0, g0 - g1);
b2 = b1 + imulFix(a0, b0 - b1); b2 = b1 + imulFix(a0, b0 - b1);
dst[i] = fix4_to_sample(a0, r2, g2, b2); dst[i] = fix_to_sample(r2, g2, b2);
#else #else
dst[i] = PixelBlend32(dst[i], dst[i] = PixelBlend32(dst[i],
@ -911,8 +906,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -990,8 +985,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
scissor_test_y if_scissor_test_y
(this->*fragmentShader) (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -1096,8 +1091,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y; subPixel = ( (f32) yStart ) - b->Pos.y;
@ -1175,8 +1170,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
#endif #endif
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
scissor_test_y if_scissor_test_y
(this->*fragmentShader) (); (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0]; scan.x[0] += scan.slopeX[0];
@ -1219,16 +1214,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a
} }
} // end namespace video burning_namespace_end
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr burning_namespace_start
{
namespace video
{
//! creates a flat triangle renderer //! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver) IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
@ -1241,9 +1231,6 @@ IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
} }
burning_namespace_end
} // end namespace video
} // end namespace irr

@ -26,11 +26,11 @@
// define render case // define render case
#ifdef BURNINGVIDEO_RENDERER_FAST #ifdef BURNINGVIDEO_RENDERER_FAST
#define SUBTEXEL #define SUBTEXEL
#define INVERSE_W #define INVERSE_W
#else #else
#define SUBTEXEL #define SUBTEXEL
#define INVERSE_W #define INVERSE_W
#endif #endif
//#define USE_ZBUFFER //#define USE_ZBUFFER
@ -43,42 +43,37 @@
//#define IPOL_T1 //#define IPOL_T1
#if BURNING_MATERIAL_MAX_COLORS < 1 #if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0 #undef IPOL_C0
#endif #endif
// apply global override // apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W #undef INVERSE_W
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W #undef IPOL_W
#endif #endif
#endif #endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL #ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL #undef SUBTEXEL
#endif #endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#define IPOL_Z #define IPOL_Z
#ifdef CMP_W #ifdef CMP_W
#undef CMP_W #undef CMP_W
#define CMP_Z #define CMP_Z
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
#undef WRITE_W #undef WRITE_W
#define WRITE_Z #define WRITE_Z
#endif #endif
#endif #endif
burning_namespace_start
namespace irr
{
namespace video
{
class CTRTextureGouraudNoZ2 : public IBurningShader class CTRTextureGouraudNoZ2 : public IBurningShader
{ {
@ -91,25 +86,27 @@ 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;
virtual bool canWireFrame() IRR_OVERRIDE { return true; }
private: private:
// fragment shader // fragment shader
typedef void (CTRTextureGouraudNoZ2::* tFragmentShader) (); typedef void (CTRTextureGouraudNoZ2::* tFragmentShader) ();
void fragment_bilinear(); void fragment_linear();
void fragment_no_filter(); void fragment_nearest();
tFragmentShader fragmentShader; tFragmentShader fragmentShader;
}; };
//! constructor //! constructor
CTRTextureGouraudNoZ2::CTRTextureGouraudNoZ2(CBurningVideoDriver* driver) CTRTextureGouraudNoZ2::CTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
: IBurningShader(driver) : IBurningShader(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTRTextureGouraudNoZ2"); setDebugName("CTRTextureGouraudNoZ2");
#endif #endif
fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear; fragmentShader = &CTRTextureGouraudNoZ2::fragment_linear;
} }
/*! /*!
@ -122,23 +119,23 @@ void CTRTextureGouraudNoZ2::OnSetMaterial(const SBurningShaderMaterial& material
material.org.TextureLayer[0].AnisotropicFilter material.org.TextureLayer[0].AnisotropicFilter
) )
{ {
fragmentShader = &CTRTextureGouraudNoZ2::fragment_bilinear; fragmentShader = &CTRTextureGouraudNoZ2::fragment_linear;
} }
else else
{ {
fragmentShader = &CTRTextureGouraudNoZ2::fragment_no_filter; fragmentShader = &CTRTextureGouraudNoZ2::fragment_nearest;
} }
} }
/*! /*!
*/ */
void CTRTextureGouraudNoZ2::fragment_bilinear() void CTRTextureGouraudNoZ2::fragment_linear()
{ {
tVideoSample *dst; tVideoSample* dst;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
fp24 *z; fp24* z;
#endif #endif
s32 xStart; s32 xStart;
@ -164,16 +161,15 @@ void CTRTextureGouraudNoZ2::fragment_bilinear()
#endif #endif
// apply top-left fill-convention, left // apply top-left fill-convention, left
xStart = fill_convention_left( line.x[0] ); xStart = fill_convention_left(line.x[0]);
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 = fill_step_x( 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;
@ -211,10 +207,10 @@ void CTRTextureGouraudNoZ2::fragment_bilinear()
#endif #endif
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart; dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif #endif
@ -224,34 +220,37 @@ void CTRTextureGouraudNoZ2::fragment_bilinear()
tFixPoint ty0; tFixPoint ty0;
tFixPoint r0, g0, b0; tFixPoint r0, g0, b0;
for ( s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X) for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X)
{ {
//if test active only first pixel
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
#ifdef CMP_W #ifdef CMP_W
if ( line.w[0] >= z[i] ) if (line.w[0] >= z[i])
#endif #endif
scissor_test_x if_scissor_test_x
{ {
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32 ( line.w[0] ); inversew = fix_inverse32(line.w[0]);
#endif #endif
tx0 = tofix ( line.t[0][0].x,inversew); tx0 = tofix(line.t[0][0].x,inversew);
ty0 = tofix ( line.t[0][0].y,inversew); ty0 = tofix(line.t[0][0].y,inversew);
//skybox //skybox
//dst[i] = getTexel_plain ( &IT[0], tx0, ty0 ); //dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );
getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 ); getSample_texture(r0, g0, b0, IT + 0, tx0, ty0);
dst[i] = fix_to_sample( r0, g0, b0 ); dst[i] = fix_to_sample(r0, g0, b0);
#ifdef WRITE_Z #ifdef WRITE_Z
z[i] = line.z[0]; z[i] = line.z[0];
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
z[i] = line.w[0]; z[i] = line.w[0];
#endif #endif
} }
#ifdef IPOL_Z #ifdef IPOL_Z
line.z[0] += slopeZ; line.z[0] += slopeZ;
@ -274,7 +273,7 @@ void CTRTextureGouraudNoZ2::fragment_bilinear()
/*! /*!
*/ */
void CTRTextureGouraudNoZ2::fragment_no_filter() void CTRTextureGouraudNoZ2::fragment_nearest()
{ {
tVideoSample* dst; tVideoSample* dst;
@ -372,25 +371,25 @@ void CTRTextureGouraudNoZ2::fragment_no_filter()
#ifdef CMP_W #ifdef CMP_W
if (line.w[0] >= z[i]) if (line.w[0] >= z[i])
#endif #endif
//scissor_test_x //scissor_test_x
{ {
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]); inversew = fix_inverse32(line.w[0]);
#endif #endif
tx0 = tofix(line.t[0][0].x,inversew); tx0 = tofix(line.t[0][0].x, inversew);
ty0 = tofix(line.t[0][0].y,inversew); ty0 = tofix(line.t[0][0].y, inversew);
//skybox //skybox
dst[i] = getTexel_plain(&IT[0], tx0, ty0); dst[i] = getTexel_plain(&IT[0], tx0, ty0);
//getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 ); //getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 );
//dst[i] = fix_to_sample( r0, g0, b0 ); //dst[i] = fix_to_sample( r0, g0, b0 );
#ifdef WRITE_Z #ifdef WRITE_Z
z[i] = line.z[0]; z[i] = line.z[0];
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
z[i] = line.w[0]; z[i] = line.w[0];
#endif #endif
} }
#ifdef IPOL_Z #ifdef IPOL_Z
@ -415,20 +414,20 @@ void CTRTextureGouraudNoZ2::fragment_no_filter()
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
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); if (F32_A_GREATER_B(b->Pos.y, c->Pos.y)) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y; const f32 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] = fill_step_y( ca ); scan.invDeltaY[0] = fill_step_y(ca);
scan.invDeltaY[1] = fill_step_y( ba ); scan.invDeltaY[1] = fill_step_y(ba);
scan.invDeltaY[2] = fill_step_y( 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;
// find if the major edge is left or right aligned // find if the major edge is left or right aligned
@ -439,7 +438,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -480,7 +479,7 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// rasterize upper sub-triangle // rasterize upper sub-triangle
if (F32_GREATER_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];
@ -512,11 +511,11 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top(a->Pos.y);
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down(b->Pos.y);
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ((f32)yStart) - a->Pos.y;
// correct to pixel center // correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel; scan.x[0] += scan.slopeX[0] * subPixel;
@ -550,7 +549,9 @@ 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 += SOFTWARE_DRIVER_2_STEP_Y) line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
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];
@ -582,9 +583,10 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
scissor_test_y if_scissor_test_y
(this->*fragmentShader) (); (this->*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];
@ -618,10 +620,10 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if (F32_GREATER_0(scan.invDeltaY[2]) ) if (F32_GREATER_0(scan.invDeltaY[2]))
{ {
// advance to middle point // advance to middle point
if(F32_GREATER_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
@ -674,12 +676,12 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top(b->Pos.y);
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down(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
scan.x[0] += scan.slopeX[0] * subPixel; scan.x[0] += scan.slopeX[0] * subPixel;
@ -713,7 +715,9 @@ 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 += SOFTWARE_DRIVER_2_STEP_Y) line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
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];
@ -744,9 +748,10 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
#endif #endif
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
scissor_test_y if_scissor_test_y
(this->*fragmentShader) (); (this->*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];
@ -782,30 +787,21 @@ void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, co
} }
} // end namespace video burning_namespace_end
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr burning_namespace_start
{
namespace video
{
//! creates a flat triangle renderer //! creates a flat triangle renderer
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver) IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver)
{ {
// ETR_TEXTURE_GOURAUD_NOZ // ETR_TEXTURE_GOURAUD_NOZ
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureGouraudNoZ2( driver ); return new CTRTextureGouraudNoZ2(driver);
#else #else
return 0; return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
} }
burning_namespace_end
} // end namespace video
} // end namespace irr

@ -347,7 +347,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -430,8 +430,8 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -509,7 +509,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -612,8 +612,8 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
@ -692,7 +692,7 @@ void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -289,7 +289,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -362,8 +362,8 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -431,7 +431,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -521,8 +521,8 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
@ -591,7 +591,7 @@ void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -270,7 +270,7 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -343,8 +343,8 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -503,8 +503,8 @@ void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL

@ -269,7 +269,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -342,8 +342,8 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -411,7 +411,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
interlace_scanline scanline_bilinear2 (); if_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];
@ -502,8 +502,8 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
@ -572,7 +572,7 @@ void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, c
#endif #endif
// render a scanline // render a scanline
interlace_scanline scanline_bilinear2 (); if_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];

@ -68,11 +68,7 @@
#endif #endif
namespace irr burning_namespace_start
{
namespace video
{
class CTRTextureLightMap2_M4 : public IBurningShader class CTRTextureLightMap2_M4 : public IBurningShader
{ {
@ -84,19 +80,14 @@ 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;
private: private:
#if defined(SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN) // fragment shader
void drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c ); typedef void (CTRTextureLightMap2_M4::* tFragmentShader) ();
void drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c ); void fragment_linear_mag();
void scanline_bilinear2_mag (); void fragment_nearest_min();
void scanline_bilinear2_min ();
#else
#define scanline_bilinear2_mag fragmentShader
#endif
void fragmentShader(); tFragmentShader fragmentShader;
}; };
@ -107,11 +98,13 @@ CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(CBurningVideoDriver* driver)
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTRTextureLightMap2_M4"); setDebugName("CTRTextureLightMap2_M4");
#endif #endif
fragmentShader = &CTRTextureLightMap2_M4::fragment_linear_mag;
} }
/*! /*!
*/ */
void CTRTextureLightMap2_M4::scanline_bilinear2_mag () void CTRTextureLightMap2_M4::fragment_linear_mag()
{ {
tVideoSample *dst; tVideoSample *dst;
fp24 *z; fp24 *z;
@ -138,11 +131,17 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
dst = (tVideoSample*)RenderTarget->getData() + i; dst = (tVideoSample*)RenderTarget->getData() + i;
// subTexel // subTexel
#ifdef SUBTEXEL
const f32 subPixel = ( (f32) xStart ) - line.x[0]; const f32 subPixel = ( (f32) xStart ) - line.x[0];
#endif
#ifdef IPOL_W #ifdef IPOL_W
const fp24 b = (line.w[1] - line.w[0]) * invDeltaX; const fp24 b = (line.w[1] - line.w[0]) * invDeltaX;
fp24 a = line.w[0] + ( b * subPixel ); fp24 a = line.w[0]
#ifdef SUBTEXEL
+ ( b * subPixel )
#endif
;
i = 0; i = 0;
@ -161,7 +160,11 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
line.w[1] = b; line.w[1] = b;
#else #else
const f32 b = (line.z[1] - line.z[0]) * invDeltaX; const f32 b = (line.z[1] - line.z[0]) * invDeltaX;
f32 a = line.z[0] + ( b * subPixel ); fp24 a = line.z[0]
#ifdef SUBTEXEL
+ (b * subPixel)
#endif
;
i = 0; i = 0;
@ -180,8 +183,11 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
line.z[1] = b; line.z[1] = b;
#endif #endif
a = (f32) i + subPixel; a = (f32)i
#ifdef SUBTEXEL
+ subPixel
#endif
;
line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX; line.t[0][1] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX; line.t[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
@ -221,7 +227,6 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
#endif #endif
#ifdef BURNINGVIDEO_RENDERER_FAST #ifdef BURNINGVIDEO_RENDERER_FAST
const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ]; const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];
@ -248,8 +253,7 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
} }
#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN) void CTRTextureLightMap2_M4::fragment_nearest_min()
void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
{ {
tVideoSample *dst; tVideoSample *dst;
fp24 *z; fp24 *z;
@ -352,7 +356,6 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
f32 inversew = FIX_POINT_F32_MUL; f32 inversew = FIX_POINT_F32_MUL;
#endif #endif
getTexel_fix ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) ); getTexel_fix ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );
getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) ); getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );
@ -370,20 +373,19 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
} }
void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
{ {
if (IT[0].lodFactor < 4) /*
if ( IT[0].lodFactor < 4)
{ {
drawTriangle_Mag(a, b, c); fragmentShader = &CTRTextureLightMap2_M4::fragment_linear_mag;
} }
else else
{ {
drawTriangle_Min(a, b, c); fragmentShader = &CTRTextureLightMap2_M4::fragment_nearest_min;
} }
} */
void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
{
// sort on height, y // sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
@ -392,6 +394,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
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] = fill_step_y( ca ); scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = fill_step_y( ba ); scan.invDeltaY[1] = fill_step_y( ba );
@ -401,14 +404,16 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
return; return;
// 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];
temp[0] = a->Pos.x - c->Pos.x; temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca; temp[1] = ca;
temp[2] = b->Pos.x - a->Pos.x; temp[2] = a->Pos.x - b->Pos.x;
temp[3] = ba; temp[3] = ba;
*/
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; //scan.left = ((a->Pos.x - c->Pos.x) * ba - ca * (a->Pos.x - b->Pos.x)) < 0.f ? 1 : 0;
scan.left = (ca * (b->Pos.x - a->Pos.x) - ba *(c->Pos.x-a->Pos.x ) ) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -481,8 +486,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -518,6 +523,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#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 += SOFTWARE_DRIVER_2_STEP_Y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
@ -550,7 +557,9 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// render a scanline // render a scanline
interlace_scanline scanline_bilinear2_min (); if_interlace_scanline
(this->*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];
@ -590,23 +599,23 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
// advance to middle point // advance to middle point
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) ) if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{ {
temp[0] = b->Pos.y - a->Pos.y; // dy const f32 dy = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0]; scan.x[0] = a->Pos.x + scan.slopeX[0] * dy;
#ifdef IPOL_Z #ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0]; scan.z[0] = a->Pos.z + scan.slopeZ[0] * dy;
#endif #endif
#ifdef IPOL_W #ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0]; scan.w[0] = a->Pos.w + scan.slopeW[0] * dy;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0]; scan.c[0] = a->Color[0] + scan.slopeC[0] * dy;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * dy;
#endif #endif
#ifdef IPOL_T1 #ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0]; scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * dy;
#endif #endif
} }
@ -641,8 +650,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
@ -679,6 +688,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#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 += SOFTWARE_DRIVER_2_STEP_Y) for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{ {
@ -711,7 +722,9 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif #endif
// render a scanline // render a scanline
interlace_scanline scanline_bilinear2_min (); if_interlace_scanline
(this->*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];
@ -746,394 +759,12 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
} }
void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )
#else //#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN) burning_namespace_end
void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
#endif
{
// sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
if ( F32_LOWER_EQUAL_0 ( ca ) )
return;
// calculate delta y of the edges
scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = fill_step_y( cb );
//if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )
// return;
// find if the major edge is left or right aligned
f32 temp[4];
temp[0] = a->Pos.x - c->Pos.x;
temp[1] = -ca;
temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];
scan.x[0] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];
scan.z[0] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];
scan.w[0] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];
scan.c[0] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];
scan.t[1][0] = a->Tex[1];
#endif
// top left fill convention y run
s32 yStart;
s32 yEnd;
#ifdef SUBTEXEL
f32 subPixel;
#endif
// rasterize upper sub-triangle
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
scan.x[1] = a->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];
scan.z[1] = a->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];
scan.w[1] = a->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];
scan.c[1] = a->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];
scan.t[1][1] = a->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
interlace_scanline scanline_bilinear2_mag ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
// rasterize lower sub-triangle
//if ( (f32) 0.0 != scan.invDeltaY[2] )
if ( F32_GREATER_0 ( scan.invDeltaY[2] ) )
{
// advance to middle point
if ( F32_GREATER_0 ( scan.invDeltaY[1] ) )
{
temp[0] = b->Pos.y - a->Pos.y; // dy
scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];
#ifdef IPOL_Z
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
#endif
#ifdef IPOL_W
scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];
#endif
#ifdef IPOL_C0
scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
#ifdef IPOL_T1
scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];
#endif
}
// calculate slopes for bottom edge
scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];
scan.x[1] = b->Pos.x;
#ifdef IPOL_Z
scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];
scan.z[1] = b->Pos.z;
#endif
#ifdef IPOL_W
scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];
scan.w[1] = b->Pos.w;
#endif
#ifdef IPOL_C0
scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[1] = b->Color[0];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
#endif
#ifdef IPOL_T1
scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];
scan.t[1][1] = b->Tex[1];
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
// correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel;
scan.x[1] += scan.slopeX[1] * subPixel;
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0] * subPixel;
scan.z[1] += scan.slopeZ[1] * subPixel;
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0] * subPixel;
scan.w[1] += scan.slopeW[1] * subPixel;
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0] * subPixel;
scan.c[1] += scan.slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0] * subPixel;
scan.t[1][1] += scan.slopeT[1][1] * subPixel;
#endif
#endif
// rasterize the edge scanlines
for( line.y = yStart; line.y <= yEnd; line.y += SOFTWARE_DRIVER_2_STEP_Y)
{
line.x[scan.left] = scan.x[0];
line.x[scan.right] = scan.x[1];
#ifdef IPOL_Z
line.z[scan.left] = scan.z[0];
line.z[scan.right] = scan.z[1];
#endif
#ifdef IPOL_W
line.w[scan.left] = scan.w[0];
line.w[scan.right] = scan.w[1];
#endif
#ifdef IPOL_C0
line.c[scan.left] = scan.c[0];
line.c[scan.right] = scan.c[1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
#endif
#ifdef IPOL_T1
line.t[1][scan.left] = scan.t[1][0];
line.t[1][scan.right] = scan.t[1][1];
#endif
// render a scanline
interlace_scanline scanline_bilinear2_mag ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
#ifdef IPOL_Z
scan.z[0] += scan.slopeZ[0];
scan.z[1] += scan.slopeZ[1];
#endif
#ifdef IPOL_W
scan.w[0] += scan.slopeW[0];
scan.w[1] += scan.slopeW[1];
#endif
#ifdef IPOL_C0
scan.c[0] += scan.slopeC[0];
scan.c[1] += scan.slopeC[1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
#endif
#ifdef IPOL_T1
scan.t[1][0] += scan.slopeT[1][0];
scan.t[1][1] += scan.slopeT[1][1];
#endif
}
}
}
#undef scanline_bilinear2_mag
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr burning_namespace_start
{
namespace video
{
//! creates a flat triangle renderer //! creates a flat triangle renderer
@ -1147,8 +778,4 @@ IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* d
} }
} // end namespace video burning_namespace_end
} // end namespace irr

@ -298,7 +298,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -373,8 +373,8 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ( (f32) yStart ) - a->Pos.y;
@ -442,7 +442,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];
@ -534,8 +534,8 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL #ifdef SUBTEXEL
@ -604,7 +604,7 @@ void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a,
#endif #endif
// render a scanline // render a scanline
interlace_scanline fragmentShader(); if_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];

@ -28,10 +28,10 @@
#define SUBTEXEL #define SUBTEXEL
#define INVERSE_W #define INVERSE_W
//#define USE_ZBUFFER #define USE_ZBUFFER
#define IPOL_W #define IPOL_W
//#define CMP_W #define CMP_W
//#define WRITE_W #define WRITE_W
#define IPOL_C0 #define IPOL_C0
@ -40,41 +40,36 @@
// apply global override // apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W #undef INVERSE_W
#endif #endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL #ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL #undef SUBTEXEL
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS < 1 #if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0 #undef IPOL_C0
#endif #endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W #undef IPOL_W
#endif #endif
#define IPOL_Z #define IPOL_Z
#ifdef CMP_W #ifdef CMP_W
#undef CMP_W #undef CMP_W
#define CMP_Z #define CMP_Z
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
#undef WRITE_W #undef WRITE_W
#define WRITE_Z #define WRITE_Z
#endif #endif
#endif #endif
burning_namespace_start
namespace irr
{
namespace video
{
class CTRTextureWire2 : public IBurningShader class CTRTextureWire2 : public IBurningShader
{ {
@ -83,43 +78,54 @@ public:
//! constructor //! constructor
CTRTextureWire2(CBurningVideoDriver* driver); CTRTextureWire2(CBurningVideoDriver* driver);
virtual void OnSetMaterial(const SBurningShaderMaterial& material) IRR_OVERRIDE;
//! 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 drawLine ( const s4DVertex *a,const s4DVertex *b) IRR_OVERRIDE; virtual void drawLine(const s4DVertex* a, const s4DVertex* b) IRR_OVERRIDE;
virtual void drawPoint( const s4DVertex *a) IRR_OVERRIDE; virtual void drawPoint(const s4DVertex* a) IRR_OVERRIDE;
virtual bool canWireFrame () IRR_OVERRIDE { return true; } virtual bool canWireFrame() IRR_OVERRIDE { return true; }
virtual bool canPointCloud() IRR_OVERRIDE { return true; } virtual bool canPointCloud() IRR_OVERRIDE { return true; }
protected: protected:
virtual void fragmentShader();
void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const; void renderLine(const s4DVertex* a, const s4DVertex* b) const;
void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const;
int renderZero;
int depth_pass;
int depth_write;
}; };
//! constructor //! constructor
CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver) CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
: IBurningShader(driver) : IBurningShader(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTRTextureWire2"); setDebugName("CTRTextureWire2");
#endif #endif
renderZero = 0;
depth_pass = 1;
depth_write = 0;
} }
void CTRTextureWire2::OnSetMaterial(const SBurningShaderMaterial& material)
{
depth_pass = material.depth_test == 0;
depth_write = material.depth_write;
}
/*! /*!
2d line 2d line
*/ */
void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const void CTRTextureWire2::renderLine(const s4DVertex* a, const s4DVertex* b) const
{ {
int pitch0 = RenderTarget->getDimension().Width << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY; const int pitch0 = RenderTarget->getDimension().Width << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
int pitch1 = RenderTarget->getDimension().Width << 2; const int pitch1 = RenderTarget->getDimension().Width * sizeof(fp24);
#endif #endif
//todo:! //todo: fill_convention_none!
int aposx = fill_convention_none(a->Pos.x); int aposx = fill_convention_none(a->Pos.x);
int aposy = fill_convention_none(a->Pos.y); int aposy = fill_convention_none(a->Pos.y);
int bposx = fill_convention_none(b->Pos.x); int bposx = fill_convention_none(b->Pos.x);
@ -133,36 +139,36 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
int d = 0; int d = 0;
int run; int run;
tVideoSample *dst; tVideoSample* dst;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
fp24 *z; fp24* z;
#endif #endif
int xInc0 = 1 << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY; int xInc0 = 1 << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY;
int yInc0 = pitch0; int yInc0 = pitch0;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
int xInc1 = 4; int xInc1 = sizeof(fp24);
int yInc1 = pitch1; int yInc1 = pitch1;
#endif #endif
if ( dx < 0 ) if (dx < 0)
{ {
xInc0 = - ( 1 << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY); xInc0 = -xInc0;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
xInc1 = -4; xInc1 = -4;
#endif #endif
dx = -dx; dx = -dx;
} }
if ( dy > dx ) if (dy > dx)
{ {
//swap //swap
s32 t; s32 t;
t = dx;dx=dy;dy=t; t = dx; dx = dy; dy = t;
t = xInc0;xInc0=yInc0;yInc0=t; t = xInc0; xInc0 = yInc0; yInc0 = t;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
t = xInc1;xInc1=yInc1;yInc1=t; t = xInc1; xInc1 = yInc1; yInc1 = t;
#endif #endif
} }
@ -173,16 +179,17 @@ 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<< SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY) ) ); dst = (tVideoSample*)((u8*)RenderTarget->getData() + (aposy * pitch0) + (aposx << SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY));
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) ); z = (fp24*)((u8*)DepthBuffer->lock() + (aposy * pitch1) + (aposx << 2));
#endif #endif
c = dx << 1; c = dx << 1;
m = dy << 1; m = dy << 1;
// slopes // slopes
const f32 invDeltaX = fill_step_x( (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;
@ -210,59 +217,59 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
inversew = fix_inverse32_color(dataW); inversew = fix_inverse32_color(dataW);
#endif #endif
vec4_to_fix( r0, g0, b0, a->Color[0], inversew); vec4_to_fix(r0, g0, b0, a->Color[0], inversew);
color = fix_to_sample( r0, g0, b0 ); color = fix_to_sample(r0, g0, b0);
#else #else
color = (tVideoSample) 0xFFFFFFFF; color = (tVideoSample)0xFFFFFFFF;
#endif #endif
run = dx; run = dx;
while ( run ) while (run)
{ {
#ifdef CMP_Z #ifdef CMP_Z
if ( *z >= dataZ ) if (*z >= dataZ)
#endif #endif
#ifdef CMP_W #ifdef CMP_W
if ( dataW >= *z ) if (depth_pass || dataW >= *z)
#endif #endif
{ {
#ifdef WRITE_Z #ifdef WRITE_Z
*z = dataZ; *z = dataZ;
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
*z = dataW; if (depth_write) *z = dataW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32_color(dataW); inversew = fix_inverse32_color(dataW);
#endif #endif
vec4_to_fix(r0, g0, b0, C,inversew); vec4_to_fix(r0, g0, b0, C, inversew);
color = fix_to_sample( r0, g0, b0 ); color = fix_to_sample(r0, g0, b0);
#endif #endif
*dst = color; * dst = color;
} }
dst = (tVideoSample*) ( (u8*) dst + xInc0 ); // x += xInc dst = (tVideoSample*)((u8*)dst + xInc0); // x += xInc
#ifdef CMP_Z #ifdef CMP_Z
z = (fp24*) ( (u8*) z + xInc1 ); z = (fp24*)((u8*)z + xInc1);
#endif #endif
#ifdef CMP_W #ifdef CMP_W
z = (fp24*) ( (u8*) z + xInc1 ); z = (fp24*)((u8*)z + xInc1);
#endif #endif
d += m; d += m;
if ( d > dx ) if (d > dx)
{ {
dst = (tVideoSample*) ( (u8*) dst + yInc0 ); // y += yInc dst = (tVideoSample*)((u8*)dst + yInc0); // y += yInc
#ifdef CMP_Z #ifdef CMP_Z
z = (fp24*) ( (u8*) z + yInc1 ); z = (fp24*)((u8*)z + yInc1);
#endif #endif
#ifdef CMP_W #ifdef CMP_W
z = (fp24*) ( (u8*) z + yInc1 ); z = (fp24*)((u8*)z + yInc1);
#endif #endif
d -= c; d -= c;
@ -278,69 +285,61 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int re
C += slopeC; C += slopeC;
#endif #endif
} }
} }
void CTRTextureWire2::fragmentShader()
{
}
void CTRTextureWire2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) void CTRTextureWire2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{ {
// sort on height, y // sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); if (F32_A_GREATER_B(b->Pos.y, c->Pos.y)) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
renderLine ( a, b ); renderLine(a, b);
renderLine ( b, c ); renderLine(b, c);
renderLine ( a, c ); renderLine(a, c);
} }
void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b) void CTRTextureWire2::drawLine(const s4DVertex* a, const s4DVertex* b)
{ {
// query access to TexMaps // query access to TexMaps
// sort on height, y // sort on height, y
if (F32_A_GREATER_B(a->Pos.y,b->Pos.y )) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
renderLine ( a, b ); renderLine(a, b);
} }
void CTRTextureWire2::drawPoint(const s4DVertex *a) void CTRTextureWire2::drawPoint(const s4DVertex* a)
{ {
if ( (a->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) renderLine(a, a,1); if ((a->flag & VERTEX4D_CLIPMASK) == VERTEX4D_INSIDE)
{
renderZero = 1;
renderLine(a, a);
renderZero = 0;
}
} }
burning_namespace_end
} // end namespace video
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr burning_namespace_start
{
namespace video
{
//! creates a flat triangle renderer //! creates a flat triangle renderer
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver) IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver)
{ {
//ETR_TEXTURE_GOURAUD_WIRE //ETR_TEXTURE_GOURAUD_WIRE
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRTextureWire2(driver); return new CTRTextureWire2(driver);
#else #else
return 0; return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
} }
} // end namespace video burning_namespace_end
} // end namespace irr

@ -21,6 +21,8 @@
#undef INVERSE_W #undef INVERSE_W
#undef IPOL_C0 #undef IPOL_C0
#undef IPOL_C1
#undef IPOL_C1_FOG
#undef IPOL_T0 #undef IPOL_T0
#undef IPOL_T1 #undef IPOL_T1
@ -34,45 +36,47 @@
#define WRITE_W #define WRITE_W
#define IPOL_C0 #define IPOL_C0
#define IPOL_C1
#define IPOL_T0 #define IPOL_T0
#define IPOL_T1 #define IPOL_T1
// apply global override // apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W #undef INVERSE_W
#endif #endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL #ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL #undef SUBTEXEL
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS < 1 #if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0 #undef IPOL_C0
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER ) #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W #undef IPOL_W
#endif #endif
#define IPOL_Z #define IPOL_Z
#ifdef CMP_W #ifdef CMP_W
#undef CMP_W #undef CMP_W
#define CMP_Z #define CMP_Z
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
#undef WRITE_W #undef WRITE_W
#define WRITE_Z #define WRITE_Z
#endif #endif
#endif #endif
namespace irr burning_namespace_start
{
namespace video
{
class CTR_transparent_reflection_2_layer : public IBurningShader class CTR_transparent_reflection_2_layer : public IBurningShader
{ {
@ -94,11 +98,11 @@ private:
//! constructor //! constructor
CTR_transparent_reflection_2_layer::CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver) CTR_transparent_reflection_2_layer::CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver)
: IBurningShader(driver) : IBurningShader(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CTR_transparent_reflection_2_layer"); setDebugName("CTR_transparent_reflection_2_layer");
#endif #endif
} }
void CTR_transparent_reflection_2_layer::OnSetMaterial(const SBurningShaderMaterial& material) void CTR_transparent_reflection_2_layer::OnSetMaterial(const SBurningShaderMaterial& material)
@ -111,10 +115,10 @@ void CTR_transparent_reflection_2_layer::OnSetMaterial(const SBurningShaderMater
*/ */
void CTR_transparent_reflection_2_layer::fragmentShader() void CTR_transparent_reflection_2_layer::fragmentShader()
{ {
tVideoSample *dst; tVideoSample* dst;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
fp24 *z; fp24* z;
#endif #endif
s32 xStart; s32 xStart;
@ -133,23 +137,23 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
fp24 slopeW; fp24 slopeW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
sVec4 slopeC; sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif #endif
// apply top-left fill-convention, left // apply top-left fill-convention, left
xStart = fill_convention_left( line.x[0] ); xStart = fill_convention_left(line.x[0]);
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 = fill_step_x( 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;
@ -158,7 +162,10 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
slopeW = (line.w[1] - line.w[0]) * invDeltaX; slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@ -168,7 +175,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
#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
@ -176,7 +183,10 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
line.w[0] += slopeW * subPixel; line.w[0] += slopeW * subPixel;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel; line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel; line.t[0][0] += slopeT[0] * subPixel;
@ -187,10 +197,10 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
#endif #endif
SOFTWARE_DRIVER_2_CLIPCHECK; SOFTWARE_DRIVER_2_CLIPCHECK;
dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart; dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;
#ifdef USE_ZBUFFER #ifdef USE_ZBUFFER
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart; z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif #endif
@ -203,152 +213,197 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
tFixPoint a1; tFixPoint a1;
#endif #endif
switch(MaterialType) { #ifdef IPOL_C1_FOG
tFixPoint aFog = FIX_POINT_ONE;
#endif
switch (MaterialType) {
default: default:
case EMT_REFLECTION_2_LAYER: case EMT_REFLECTION_2_LAYER:
for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X) 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
{ {
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]); inversew = fix_inverse32(line.w[0]);
#endif #endif
getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew)); #ifdef IPOL_C1_FOG
getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew)); //complete inside fog
if (TL_Flag & TL_FOG)
{
aFog = tofix(line.c[1][0].a, inversew);
if (aFog <= 0)
{
dst[i] = fog_color_sample;
continue;
}
}
#endif
r0 = imulFix_tex1(r0, r1); getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
g0 = imulFix_tex1(g0, g1); getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
b0 = imulFix_tex1(b0, b1);
r0 = imulFix_tex1(r0, r1);
g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1);
#ifdef IPOL_C0 #ifdef IPOL_C0
vec4_to_fix(r1, g1, b1, line.c[0][0], inversew); vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0); r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0); g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0); b0 = imulFix_simple(b1, b0);
#endif #endif
dst[i] = fix_to_sample(r0, g0, b0); #ifdef IPOL_C1
//specular highlight
if (TL_Flag & TL_SPECULAR)
{
vec4_to_fix(r1, g1, b1, line.c[1][0], inversew * COLOR_MAX);
r0 = clampfix_maxcolor(r1 + r0);
g0 = clampfix_maxcolor(g1 + g0);
b0 = clampfix_maxcolor(b1 + b0);
}
#endif
#ifdef IPOL_C1_FOG
//mix with distance
if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)
{
r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);
g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);
b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);
}
#endif
dst[i] = fix_to_sample(r0, g0, b0);
#ifdef WRITE_Z #ifdef WRITE_Z
z[i] = line.z[0]; z[i] = line.z[0];
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
z[i] = line.w[0]; z[i] = line.w[0];
#endif #endif
} }
#ifdef IPOL_Z #ifdef IPOL_Z
line.z[0] += slopeZ; line.z[0] += slopeZ;
#endif #endif
#ifdef IPOL_W #ifdef IPOL_W
line.w[0] += slopeW; line.w[0] += slopeW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0][0] += slopeC; line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0]; line.t[0][0] += slopeT[0];
#endif #endif
#ifdef IPOL_T1 #ifdef IPOL_T1
line.t[1][0] += slopeT[1]; line.t[1][0] += slopeT[1];
#endif #endif
} }
break; break;
case EMT_TRANSPARENT_REFLECTION_2_LAYER: case EMT_TRANSPARENT_REFLECTION_2_LAYER:
for (s32 i = 0; i <= dx; i += SOFTWARE_DRIVER_2_STEP_X) 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
{ {
#ifdef INVERSE_W #ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]); inversew = fix_inverse32(line.w[0]);
#endif #endif
getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew)); getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew)); getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
r0 = imulFix_tex1(r0, r1); r0 = imulFix_tex1(r0, r1);
g0 = imulFix_tex1(g0, g1); g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1); b0 = imulFix_tex1(b0, b1);
#ifdef IPOL_C0 #ifdef IPOL_C0
vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew); vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0); r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0); g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0); b0 = imulFix_simple(b1, b0);
//vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER //vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER
if (a1 + 2 < FIX_POINT_ONE) if (a1 + 2 < FIX_POINT_ONE)
{ {
color_to_fix(r1, g1, b1, dst[i]); color_to_fix(r1, g1, b1, dst[i]);
r0 = r1 + imulFix(a1, r0 - r1); r0 = r1 + imulFix(a1, r0 - r1);
g0 = g1 + imulFix(a1, g0 - g1); g0 = g1 + imulFix(a1, g0 - g1);
b0 = b1 + imulFix(a1, b0 - b1); b0 = b1 + imulFix(a1, b0 - b1);
} }
#endif #endif
dst[i] = fix_to_sample(r0, g0, b0); dst[i] = fix_to_sample(r0, g0, b0);
#ifdef WRITE_Z #ifdef WRITE_Z
//z[i] = line.z[0]; //z[i] = line.z[0];
#endif #endif
#ifdef WRITE_W #ifdef WRITE_W
//z[i] = line.w[0]; //z[i] = line.w[0];
#endif #endif
} }
#ifdef IPOL_Z #ifdef IPOL_Z
line.z[0] += slopeZ; line.z[0] += slopeZ;
#endif #endif
#ifdef IPOL_W #ifdef IPOL_W
line.w[0] += slopeW; line.w[0] += slopeW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0][0] += slopeC; line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0]; line.t[0][0] += slopeT[0];
#endif #endif
#ifdef IPOL_T1 #ifdef IPOL_T1
line.t[1][0] += slopeT[1]; line.t[1][0] += slopeT[1];
#endif #endif
} }
break; break;
} }
} }
void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c ) void CTR_transparent_reflection_2_layer::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)
{ {
// sort on height, y // sort on height, y
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c); if (F32_A_GREATER_B(b->Pos.y, c->Pos.y)) swapVertexPointer(&b, &c);
if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b); if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y; const f32 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] = fill_step_y( ca ); scan.invDeltaY[0] = fill_step_y(ca);
scan.invDeltaY[1] = fill_step_y( ba ); scan.invDeltaY[1] = fill_step_y(ba);
scan.invDeltaY[2] = fill_step_y( 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;
// find if the major edge is left or right aligned // find if the major edge is left or right aligned
@ -359,7 +414,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -381,6 +436,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][0] = a->Color[0]; scan.c[0][0] = a->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0]; scan.t[0][0] = a->Tex[0];
@ -400,7 +460,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// rasterize upper sub-triangle // rasterize upper sub-triangle
if ( F32_GREATER_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];
@ -421,6 +481,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] = a->Color[0]; scan.c[0][1] = a->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0]; scan.t[0][1] = a->Tex[0];
@ -432,11 +497,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y ); yStart = fill_convention_top(a->Pos.y);
yEnd = fill_convention_right( b->Pos.y ); yEnd = fill_convention_down(b->Pos.y);
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y; subPixel = ((f32)yStart) - a->Pos.y;
// correct to pixel center // correct to pixel center
scan.x[0] += scan.slopeX[0] * subPixel; scan.x[0] += scan.slopeX[0] * subPixel;
@ -457,6 +522,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] += scan.slopeC[0][1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -470,7 +540,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 += SOFTWARE_DRIVER_2_STEP_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];
@ -490,6 +560,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
line.c[0][scan.right] = scan.c[0][1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1]; line.t[0][scan.right] = scan.t[0][1];
@ -501,8 +576,8 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
fragmentShader(); 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,6 +597,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] += scan.slopeC[0][1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1]; scan.t[0][1] += scan.slopeT[0][1];
@ -536,10 +616,10 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
} }
// rasterize lower sub-triangle // rasterize lower sub-triangle
if ( F32_GREATER_0(scan.invDeltaY[2]) ) if (F32_GREATER_0(scan.invDeltaY[2]))
{ {
// advance to middle point // advance to middle point
if( F32_GREATER_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
@ -553,6 +633,9 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif #endif
@ -581,6 +664,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] = b->Color[0]; scan.c[0][1] = b->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0]; scan.t[0][1] = b->Tex[0];
@ -592,12 +680,12 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y ); yStart = fill_convention_top(b->Pos.y);
yEnd = fill_convention_right( c->Pos.y ); yEnd = fill_convention_down(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
scan.x[0] += scan.slopeX[0] * subPixel; scan.x[0] += scan.slopeX[0] * subPixel;
@ -618,6 +706,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] += scan.slopeC[0][1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -631,7 +724,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 += SOFTWARE_DRIVER_2_STEP_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];
@ -651,6 +744,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
line.c[0][scan.right] = scan.c[0][1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1]; line.t[0][scan.right] = scan.t[0][1];
@ -662,8 +760,8 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif #endif
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
fragmentShader(); 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];
@ -683,6 +781,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] += scan.slopeC[0][1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1]; scan.t[0][1] += scan.slopeT[0][1];
@ -699,33 +802,27 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
} }
} // end namespace video burning_namespace_end
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr burning_namespace_start
{
namespace video
{
//! creates a flat triangle renderer //! creates a flat triangle renderer
IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver) IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver)
{ {
/* /*
ETR_TRANSPARENT_REFLECTION_2_LAYER ETR_TRANSPARENT_REFLECTION_2_LAYER
Irrlicht EMT_REFLECTION_2_LAYER,EMT_TRANSPARENT_REFLECTION_2_LAYER Irrlicht EMT_REFLECTION_2_LAYER,EMT_TRANSPARENT_REFLECTION_2_LAYER
*/ */
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_ #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTR_transparent_reflection_2_layer(driver); return new CTR_transparent_reflection_2_layer(driver);
#else #else
return 0; return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
} }
} // end namespace video burning_namespace_end
} // end namespace irr

@ -10,10 +10,7 @@
#include "CSoftwareDriver2.h" #include "CSoftwareDriver2.h"
#include "IShaderConstantSetCallBack.h" #include "IShaderConstantSetCallBack.h"
namespace irr burning_namespace_start
{
namespace video
{
const tFixPointu IBurningShader::dithermask[] = const tFixPointu IBurningShader::dithermask[] =
{ {
@ -30,7 +27,7 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
#endif #endif
#if defined(ENV64BIT) #if defined(ENV64BIT)
if (((unsigned long long)&scan & 15) || ((unsigned long long)&line & 15)) if (((unsigned long long) & scan & 15) || ((unsigned long long) & line & 15))
{ {
os::Printer::log("BurningVideo Shader not 16 byte aligned", ELL_ERROR); os::Printer::log("BurningVideo Shader not 16 byte aligned", ELL_ERROR);
IRR_DEBUG_BREAK_IF(1); IRR_DEBUG_BREAK_IF(1);
@ -42,7 +39,6 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
Interlaced.nr = 0; Interlaced.nr = 0;
EdgeTestPass = edge_test_pass; EdgeTestPass = 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)
{ {
@ -69,6 +65,8 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
RenderPass_ShaderIsTransparent = 0; RenderPass_ShaderIsTransparent = 0;
PrimitiveColor = COLOR_BRIGHT_WHITE; PrimitiveColor = COLOR_BRIGHT_WHITE;
TL_Flag = 0; TL_Flag = 0;
fragment_draw_count = 0;
VertexShaderProgram_buildin = BVT_Fix;
} }
IBurningShader::IBurningShader(CBurningVideoDriver* driver) IBurningShader::IBurningShader(CBurningVideoDriver* driver)
@ -103,8 +101,66 @@ IBurningShader::IBurningShader(
if (CallBack) if (CallBack)
CallBack->grab(); CallBack->grab();
//set default Transparent/Solid
switch (BaseMaterial)
{
case EMT_TRANSPARENT_ADD_COLOR:
case EMT_TRANSPARENT_ALPHA_CHANNEL:
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
case EMT_TRANSPARENT_VERTEX_ALPHA:
case EMT_TRANSPARENT_REFLECTION_2_LAYER:
case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:
case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:
case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_ONETEXTURE_BLEND:
RenderPass_ShaderIsTransparent = 1;
break;
default:
RenderPass_ShaderIsTransparent = 0;
break;
}
//v0.53 compile. only buildin
const c8* ip = vertexShaderProgram;
unsigned hash = 0;
unsigned len = 0;
if (ip)
{
while (ip[len])
{
hash = ip[len] + (hash << 6) + (hash << 16) - hash;
len += 1;
}
}
if (len == 815 && hash == 0x1f847599) VertexShaderProgram_buildin = BVT_815_0x1f847599; /* pp_opengl.vert */
else if (len == 1100 && hash == 0x12c79d1c) VertexShaderProgram_buildin = BVT_opengl_vsh_shaderexample; /*opengl.vert */
else if (len == 1259 && hash == 0xc8226e1a) VertexShaderProgram_buildin = STK_1259_0xc8226e1a; /* supertuxkart bubble.vert */
else if (len == 958 && hash == 0xa048973b) VertexShaderProgram_buildin = STK_958_0xa048973b; /* supertuxkart motion_blur.vert */
else if (len == 1309 && hash == 0x1fd689c2) VertexShaderProgram_buildin = STK_1309_0x1fd689c2; /* supertuxkart normalmap.vert */
else if (len == 1204 && hash == 0x072a4094) VertexShaderProgram_buildin = STK_1204_0x072a4094; /* supertuxkart splatting.vert */
//VertexShaderProgram = vertexShaderProgram;
//PixelShaderProgram = pixelShaderProgram;
// register myself as new material // register myself as new material
outMaterialTypeNr = Driver->addMaterialRenderer(this); outMaterialTypeNr = Driver->addMaterialRenderer(this);
//save info
#if 0
static int run = 0;
FILE* f = fopen("shader_id.txt", run ? "a" : "wb");
if (f)
{
fprintf(f, "--- start outMaterialTypeNr:%d len:%d hash: 0x%08x\n", outMaterialTypeNr, len, hash);
fprintf(f, "%s", vertexShaderProgram);
fprintf(f, "\n-------------- end ---------------------------\n");
fclose(f);
}
run += 1;
#endif
} }
@ -139,7 +195,7 @@ void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s3
if (RenderTarget) if (RenderTarget)
RenderTarget->drop(); RenderTarget->drop();
RenderTarget = (video::CImage*) surface; RenderTarget = (video::CImage*)surface;
if (RenderTarget) if (RenderTarget)
{ {
@ -156,7 +212,9 @@ void IBurningShader::setTextureParam(const size_t stage, video::CSoftwareTexture
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;
@ -212,9 +270,12 @@ void IBurningShader::drawPoint(const s4DVertex* a)
{ {
} }
void IBurningShader::drawWireFrameTriangle(const s4DVertex* a, const s4DVertex* b, const s4DVertex* c) void IBurningShader::drawWireFrameTriangle(s4DVertex* a, s4DVertex* b, 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);
@ -234,7 +295,7 @@ void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& l
bool resetAllRenderstates, IMaterialRendererServices* services) bool resetAllRenderstates, IMaterialRendererServices* services)
{ {
if (Driver) if (Driver)
Driver->setFallback_Material(BaseMaterial); Driver->setFallback_Material(BaseMaterial, VertexShaderProgram_buildin);
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (CallBack) if (CallBack)
CallBack->OnSetMaterial(material); CallBack->OnSetMaterial(material);
@ -243,6 +304,7 @@ void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& l
void IBurningShader::OnUnsetMaterial() void IBurningShader::OnUnsetMaterial()
{ {
//restore previous state
} }
bool IBurningShader::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) bool IBurningShader::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)
@ -273,6 +335,59 @@ void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMate
Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates); Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
} }
#if 0
const core::matrix4& IBurningShader::uniform_mat4(const c8* name)
{
return (const core::matrix4&)*getUniform(name, BL_VERTEX_FLOAT);
}
video::sVec4 IBurningShader::uniform_vec4(const c8* name)
{
const f32* v = getUniform(name, BL_VERTEX_FLOAT);
return video::sVec4(v[0], v[1], v[2], v[3]);
}
video::sVec4 IBurningShader::uniform_vec3(const c8* name)
{
const f32* v = getUniform(name, BL_VERTEX_FLOAT);
return video::sVec4(v[0], v[1], v[2], 0.f);
}
core::matrix4& IBurningShader::varying_mat4(const c8* name)
{
return (core::matrix4&)*getUniform(name, BL_FRAGMENT_FLOAT);
}
video::sVec4 IBurningShader::varying_vec4(const c8* name)
{
const f32* v = getUniform(name, BL_FRAGMENT_FLOAT);
return video::sVec4(v[0], v[1], v[2], v[3]);
}
video::sVec4 IBurningShader::varying_vec3(const c8* name)
{
const f32* v = getUniform(name, BL_FRAGMENT_FLOAT);
return video::sVec4(v[0], v[1], v[2], 0.f);
}
#endif
static BurningUniform _empty = { "null",BL_VERTEX_FLOAT,{0.f,0.f,0.f,0.f} };
const f32* IBurningShader::getUniform(const c8* name, EBurningUniformFlags flags) const
{
const size_t size = UniformInfo.size();
if (size && name && name[0])
{
const BurningUniform* b = &UniformInfo[0];
for (size_t i = 0; i < size; ++i)
{
if (tiny_istoken(b[i].name, name))
return b[i].data;
}
}
return _empty.data;
}
s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags, const c8* name) s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags, const c8* name)
{ {
if (!name || !name[0]) if (!name || !name[0])
@ -405,6 +520,27 @@ void IBurningShader::setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpf
stencilOp[2] = dppass; stencilOp[2] = dppass;
} }
void PushShaderData::push(IBurningShader* shader)
{
CurrentShader = shader;
if (shader) shader->pushShader(this,1);
}
void PushShaderData::pop()
{
if (CurrentShader) CurrentShader->pushShader(this, 0);
}
void IBurningShader::pushShader(PushShaderData* data, int save)
{
if (save)
{
data->EdgeTestPass = EdgeTestPass;
}
else
{
EdgeTestPass = data->EdgeTestPass;
}
}
IVideoDriver* IBurningShader::getVideoDriver() IVideoDriver* IBurningShader::getVideoDriver()
{ {
@ -412,7 +548,6 @@ IVideoDriver* IBurningShader::getVideoDriver()
} }
} // end namespace video burning_namespace_end
} // end namespace irr
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

@ -8,7 +8,6 @@
#include "SoftwareDriver2_compile_config.h" #include "SoftwareDriver2_compile_config.h"
#include "IReferenceCounted.h" #include "IReferenceCounted.h"
#include "irrMath.h" #include "irrMath.h"
#include "irrMathFastCompat.h"
#include "IImage.h" #include "IImage.h"
#include "S2DVertex.h" #include "S2DVertex.h"
#include "rect.h" #include "rect.h"
@ -22,421 +21,467 @@
#include "IMaterialRendererServices.h" #include "IMaterialRendererServices.h"
#include "IGPUProgrammingServices.h" #include "IGPUProgrammingServices.h"
namespace irr burning_namespace_start
struct SBurningShaderLight
{ {
//SLight org;
//s32 HardwareLightIndex;
sVec4 pos; //light position input
sVec4 pos4; //light position Model*View (Identity*View)
//sVec4 pos4n; //Norm direction to infinite light = Normalize( Position )
//sVec4 halfVector; //Norm( VP_inf_norm + <0,0,1> )
namespace video E_LIGHT_TYPE Type;
f32 linearAttenuation;
f32 constantAttenuation;
f32 quadraticAttenuation;
sVec4 spotDirection;
sVec4 spotDirection4;
f32 spotCosCutoff;
f32 spotCosInnerCutoff;
f32 spotExponent;
bool LightIsOn;
sVec3Color AmbientColor;
sVec3Color DiffuseColor;
sVec3Color SpecularColor;
};
enum eTransformLightFlags
{ {
//ENABLED = 0x01,
TL_SCISSOR = 0x02,
TL_LIGHT = 0x04,
TL_SPECULAR = 0x08,
TL_FOG = 0x10,
TL_NORMALIZE_NORMALS = 0x20,
TL_TEXTURE_TRANSFORM = 0x40, // need eyespace matrices
TL_LIGHT_LOCAL_VIEWER = 0x80,
TL_LIGHT0_IS_NORMAL_MAP = 0x100, // sVec4 Light Vector is used as normal or specular
struct SBurningShaderLight TL_COLORMAT_AMBIENT = 0x200,
TL_COLORMAT_DIFFUSE = 0x400,
TL_COLORMAT_SPECULAR = 0x800,
};
struct SBurningShaderEyeSpace
{
SBurningShaderEyeSpace() {}
virtual ~SBurningShaderEyeSpace() {}
void init()
{ {
//SLight org; Light.set_used(0);
Global_AmbientLight.set(0.2f,0.2f,0.2f,1.f);
sVec4 pos; //light position input fog_scale = 0.f;
sVec4 pos4; //light position Model*View (Identity*View) TL_Flag = TL_LIGHT_LOCAL_VIEWER;
}
E_LIGHT_TYPE Type; void deleteAllDynamicLights()
f32 linearAttenuation;
f32 constantAttenuation;
f32 quadraticAttenuation;
sVec4 spotDirection;
sVec4 spotDirection4;
f32 spotCosCutoff;
f32 spotCosInnerCutoff;
f32 spotExponent;
bool LightIsOn;
sVec3Color AmbientColor;
sVec3Color DiffuseColor;
sVec3Color SpecularColor;
};
enum eTransformLightFlags
{ {
//ENABLED = 0x01, Light.set_used(0);
TL_SCISSOR = 0x02, TL_Flag &= ~(TL_LIGHT | TL_SPECULAR);
TL_LIGHT = 0x04, }
TL_SPECULAR = 0x08,
TL_FOG = 0x10,
TL_NORMALIZE_NORMALS = 0x20,
TL_TEXTURE_TRANSFORM = 0x40,
TL_LIGHT_LOCAL_VIEWER = 0x80,
TL_LIGHT0_IS_NORMAL_MAP = 0x100 //sVec4 Light Vector is used as normal or specular
};
struct SBurningShaderEyeSpace core::array<SBurningShaderLight> Light;
sVec3Color Global_AmbientLight;
//sVec4 cam_eye_pos; //Camera Position in eye Space (0,0,-1)
//sVec4 cam_world_pos; //Camera Position in world Space
//sVec4 vertex4; //eye coordinate position of vertex
sVec4 normal; // normal in eye space,transpose(inverse(mat3(mv_matrix)); gl_NormalMatrix
sVec4 vertex; //eye coordinate position of vertex projected
//derivative of vertex
//f32 cam_distance; // vertex.length();
sVec4 vertexn; //vertex.normalize(); eye = -vertex.normalize()
f32 fog_scale; // 1 / (fog.end-fog.start)
size_t TL_Flag; // eTransformLightFlags
};
enum eBurningCullFlag
{
CULL_FRONT = 1,
CULL_BACK = 2,
CULL_INVISIBLE = 4, //primitive smaller than a pixel (AreaMinDrawSize)
CULL_FRONT_AND_BACK = 8,
CULL_EPSILON_001 = 981668463, /*0.001f*/
CULL_EPSILON_00001 = 925353388, /* 0.00001f*/
CULL_EPSILON_01 = 0x3e000000 /*0.125f*/
};
enum eBurningStencilOp
{
StencilOp_KEEP = 0x1E00,
StencilOp_INCR = 0x1E02,
StencilOp_DECR = 0x1E03
};
enum eBurningVertexShader
{
BVT_Fix = 0,
BVT_815_0x1f847599, /* example 27 pp_opengl.vert */
BVT_opengl_vsh_shaderexample,
STK_1259_0xc8226e1a, /* supertuxkart bubble.vert */
STK_958_0xa048973b, /* supertuxkart motion_blur.vert */
STK_1204_0x072a4094, /* supertuxkart splatting.vert */
STK_1309_0x1fd689c2, /* supertuxkart normalmap.vert */
};
struct SBurningShaderMaterial
{
SMaterial org;
SMaterial lastMaterial;
bool resetRenderStates;
E_MATERIAL_TYPE Fallback_MaterialType;
eBurningVertexShader VertexShader;
SMaterial mat2D;
//SMaterial save3D;
size_t CullFlag; //eCullFlag
u32 depth_write;
u32 depth_test;
sVec4 AmbientColor;
sVec4 DiffuseColor;
sVec4 SpecularColor;
sVec4 EmissiveColor;
};
enum EBurningFFShader
{
ETR_FLAT = 0,
ETR_FLAT_WIRE,
ETR_GOURAUD,
ETR_GOURAUD_WIRE,
ETR_TEXTURE_FLAT,
ETR_TEXTURE_FLAT_WIRE,
ETR_TEXTURE_GOURAUD,
ETR_TEXTURE_GOURAUD_WIRE,
ETR_TEXTURE_GOURAUD_NOZ,
ETR_TEXTURE_GOURAUD_ADD,
ETR_TEXTURE_GOURAUD_ADD_NO_Z,
ETR_TEXTURE_GOURAUD_VERTEX_ALPHA,
ETR_TEXTURE_GOURAUD_LIGHTMAP_M1,
ETR_TEXTURE_GOURAUD_LIGHTMAP_M2,
ETR_TEXTURE_GOURAUD_LIGHTMAP_M4,
ETR_TEXTURE_LIGHTMAP_M4,
ETR_TEXTURE_GOURAUD_DETAIL_MAP,
ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD,
ETR_GOURAUD_NOZ,
//ETR_GOURAUD_ALPHA,
ETR_GOURAUD_ALPHA_NOZ,
ETR_TEXTURE_GOURAUD_ALPHA,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ_NOPERSPECTIVE_CORRECT,
ETR_NORMAL_MAP_SOLID,
ETR_STENCIL_SHADOW,
ETR_TEXTURE_BLEND,
ETR_TRANSPARENT_REFLECTION_2_LAYER,
ETR_COLOR,
//ETR_REFERENCE,
ETR_INVALID,
ETR2_COUNT
};
typedef enum
{
BL_VERTEX_PROGRAM = 1,
BL_FRAGMENT_PROGRAM = 2,
BL_TYPE_FLOAT = 4,
BL_TYPE_INT = 8,
BL_TYPE_UINT = 16,
BL_VERTEX_FLOAT = (BL_VERTEX_PROGRAM | BL_TYPE_FLOAT),
BL_VERTEX_INT = (BL_VERTEX_PROGRAM | BL_TYPE_INT),
BL_VERTEX_UINT = (BL_VERTEX_PROGRAM | BL_TYPE_UINT),
BL_FRAGMENT_FLOAT = (BL_FRAGMENT_PROGRAM | BL_TYPE_FLOAT),
BL_FRAGMENT_INT = (BL_FRAGMENT_PROGRAM | BL_TYPE_INT),
BL_FRAGMENT_UINT = (BL_FRAGMENT_PROGRAM | BL_TYPE_UINT),
BL_ACTIVE_UNIFORM_MAX_LENGTH = 28
} EBurningUniformFlags;
struct BurningUniform
{
c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
u32 type; //EBurningUniformFlags
//int location; // UniformLocation is index
f32 data[16]; // simple LocalParameter
bool operator==(const BurningUniform& other) const
{ {
SBurningShaderEyeSpace() {} return tiny_istoken(name, other.name);
virtual ~SBurningShaderEyeSpace() {} }
void reset ()
{
Light.set_used ( 0 );
Global_AmbientLight.set ( 0.f );
TL_Flag = TL_LIGHT_LOCAL_VIEWER; };
}
void resetFog()
{
fog_scale = 0.f;
//cam_distance = 0.f;
}
core::array<SBurningShaderLight> Light; class IBurningShader;
sVec3Color Global_AmbientLight; struct PushShaderData
{
IBurningShader* CurrentShader;
size_t EdgeTestPass; /* edge_test_flag*/
void push(IBurningShader* shader);
void pop();
};
//sVec4 cam_eye_pos; //Camera Position in eye Space (0,0,-1) class CBurningVideoDriver;
//sVec4 cam_world_pos; //Camera Position in world Space class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices
//sVec4 vertex4; //eye coordinate position of vertex {
sVec4 normal; //transformed normal public:
sVec4 vertex; //eye coordinate position of vertex projected //! Constructor
IBurningShader(CBurningVideoDriver* driver);
//derivative of vertex //! Constructor
//f32 cam_distance; // vertex.length(); IBurningShader(
sVec4 cam_dir; //vertex.normalize(); CBurningVideoDriver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram = 0,
const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
f32 fog_scale; // 1 / (fog.end-fog.start) //! destructor
virtual ~IBurningShader();
size_t TL_Flag; // eTransformLightFlags //! sets a render target
}; virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort, const interlaced_control interlaced);
enum eBurningCullFlag //! sets the Texture
virtual void setTextureParam(const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) {};
virtual void drawLine(const s4DVertex* a, const s4DVertex* b);
virtual void drawPoint(const s4DVertex* a);
void drawWireFrameTriangle(s4DVertex* a, s4DVertex* b, s4DVertex* c);
virtual void OnSetMaterial(const SBurningShaderMaterial& material) {};
void setEdgeTest(const int wireFrame, const int pointCloud)
{ {
CULL_FRONT = 1, EdgeTestPass = pointCloud ? edge_test_point : wireFrame ? edge_test_left : edge_test_pass;
CULL_BACK = 2, }
CULL_INVISIBLE = 4, //primitive smaller than a pixel (AreaMinDrawSize)
CULL_FRONT_AND_BACK = 8,
};
enum eBurningStencilOp void pushShader(PushShaderData* data, int save);
{ virtual bool canWireFrame() { return false; }
StencilOp_KEEP = 0x1E00, virtual bool canPointCloud() { return false; }
StencilOp_INCR = 0x1E02,
StencilOp_DECR = 0x1E03
};
struct SBurningShaderMaterial void setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass);
{
SMaterial org;
SMaterial lastMaterial;
bool resetRenderStates;
E_MATERIAL_TYPE Fallback_MaterialType; //IMaterialRenderer
SMaterial mat2D; virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
//SMaterial save3D; bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE;
size_t CullFlag; //eCullFlag virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) IRR_OVERRIDE;
u32 depth_write;
u32 depth_test;
sVec3Color AmbientColor; virtual void OnUnsetMaterial() IRR_OVERRIDE;
sVec3Color DiffuseColor;
sVec3Color SpecularColor;
sVec3Color EmissiveColor;
}; //! Returns if the material is transparent.
virtual bool isTransparent() const IRR_OVERRIDE;
enum EBurningFFShader //! Access the callback provided by the users when creating shader materials
{ virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const IRR_OVERRIDE;
ETR_FLAT = 0,
ETR_FLAT_WIRE,
ETR_GOURAUD,
ETR_GOURAUD_WIRE,
ETR_TEXTURE_FLAT,
ETR_TEXTURE_FLAT_WIRE,
ETR_TEXTURE_GOURAUD,
ETR_TEXTURE_GOURAUD_WIRE,
ETR_TEXTURE_GOURAUD_NOZ,
ETR_TEXTURE_GOURAUD_ADD,
ETR_TEXTURE_GOURAUD_ADD_NO_Z,
ETR_TEXTURE_GOURAUD_VERTEX_ALPHA, // implementations for the render services
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
ETR_TEXTURE_GOURAUD_LIGHTMAP_M1, virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
ETR_TEXTURE_GOURAUD_LIGHTMAP_M2, virtual s32 getPixelShaderConstantID(const c8* name) IRR_OVERRIDE;
ETR_TEXTURE_GOURAUD_LIGHTMAP_M4, virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) IRR_OVERRIDE;
ETR_TEXTURE_LIGHTMAP_M4, virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) IRR_OVERRIDE;
virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) IRR_OVERRIDE;
ETR_TEXTURE_GOURAUD_DETAIL_MAP, virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) IRR_OVERRIDE;
ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD, virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) IRR_OVERRIDE;
virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) IRR_OVERRIDE;
ETR_GOURAUD_NOZ, virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) IRR_OVERRIDE;
//ETR_GOURAUD_ALPHA, virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) IRR_OVERRIDE;
ETR_GOURAUD_ALPHA_NOZ, virtual IVideoDriver* getVideoDriver() IRR_OVERRIDE;
ETR_TEXTURE_GOURAUD_ALPHA,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ,
ETR_TEXTURE_GOURAUD_ALPHA_NOZ_NOPERSPECTIVE_CORRECT,
ETR_NORMAL_MAP_SOLID,
ETR_STENCIL_SHADOW,
ETR_TEXTURE_BLEND,
ETR_TRANSPARENT_REFLECTION_2_LAYER,
ETR_COLOR,
//ETR_REFERENCE,
ETR_INVALID,
ETR2_COUNT
};
typedef enum
{
BL_VERTEX_PROGRAM = 1,
BL_FRAGMENT_PROGRAM = 2,
BL_TYPE_FLOAT = 4,
BL_TYPE_INT = 8,
BL_TYPE_UINT = 16,
BL_VERTEX_FLOAT = (BL_VERTEX_PROGRAM | BL_TYPE_FLOAT),
BL_VERTEX_INT = (BL_VERTEX_PROGRAM | BL_TYPE_INT),
BL_VERTEX_UINT = (BL_VERTEX_PROGRAM | BL_TYPE_UINT),
BL_FRAGMENT_FLOAT = (BL_FRAGMENT_PROGRAM | BL_TYPE_FLOAT),
BL_FRAGMENT_INT = (BL_FRAGMENT_PROGRAM | BL_TYPE_INT),
BL_FRAGMENT_UINT = (BL_FRAGMENT_PROGRAM | BL_TYPE_UINT),
BL_ACTIVE_UNIFORM_MAX_LENGTH = 28
} EBurningUniformFlags;
struct BurningUniform
{
c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];
u32 type; //EBurningUniformFlags
//int location; // UniformLocation is index
f32 data[16]; // simple LocalParameter
bool operator==(const BurningUniform& other) const
{
return tiny_istoken(name, other.name);
}
};
class CBurningVideoDriver;
class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices
{
public:
//! Constructor
IBurningShader(CBurningVideoDriver* driver);
//! Constructor
IBurningShader(
CBurningVideoDriver* driver,
s32& outMaterialTypeNr,
const c8* vertexShaderProgram = 0,
const c8* vertexShaderEntryPointName = 0,
E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1,
const c8* pixelShaderProgram = 0,
const c8* pixelShaderEntryPointName = 0,
E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1,
const c8* geometryShaderProgram = 0,
const c8* geometryShaderEntryPointName = "main",
E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,
scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,
scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,
u32 verticesOut = 0,
IShaderConstantSetCallBack* callback = 0,
E_MATERIAL_TYPE baseMaterial = EMT_SOLID,
s32 userData = 0);
//! destructor
virtual ~IBurningShader();
//! sets a render target
virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort, const interlaced_control interlaced);
//! sets the Texture
virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);
virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) {};
virtual void drawLine ( const s4DVertex *a,const s4DVertex *b);
virtual void drawPoint(const s4DVertex *a);
void drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );
virtual void OnSetMaterial( const SBurningShaderMaterial& material ) {};
void pushEdgeTest(const int wireFrame,const int point,int save)
{
if ( save ) EdgeTestPass_stack = EdgeTestPass;
EdgeTestPass = point ? edge_test_point : wireFrame ? edge_test_left : edge_test_pass;
}
void popEdgeTest() { EdgeTestPass = EdgeTestPass_stack; }
virtual bool canWireFrame () { return false; }
virtual bool canPointCloud() { return false; }
void setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass);
//IMaterialRenderer
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE;
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) IRR_OVERRIDE;
virtual void OnUnsetMaterial() IRR_OVERRIDE;
//! Returns if the material is transparent.
virtual bool isTransparent() const IRR_OVERRIDE;
//! Access the callback provided by the users when creating shader materials
virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const IRR_OVERRIDE;
// implementations for the render services
virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) IRR_OVERRIDE;
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
virtual s32 getPixelShaderConstantID(const c8* name) IRR_OVERRIDE;
virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) IRR_OVERRIDE;
virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) IRR_OVERRIDE;
virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) IRR_OVERRIDE;
virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) IRR_OVERRIDE;
virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) IRR_OVERRIDE;
virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) IRR_OVERRIDE;
virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) IRR_OVERRIDE;
virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) IRR_OVERRIDE;
virtual IVideoDriver* getVideoDriver() IRR_OVERRIDE;
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count) virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{ {
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count); return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
} }
virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count) virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
{ {
return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count); return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
} }
virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count) virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{ {
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count); return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
} }
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count) virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{ {
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count); return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
} }
virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count) virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
{ {
return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count); return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
} }
virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count) virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{ {
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count); return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
} }
#endif #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)
{ {
PrimitiveColor = color_to_sample(color); PrimitiveColor = color_to_sample(color);
} }
void setTLFlag(size_t in /*eTransformLightFlags*/) void setTLFlag(size_t in /*eTransformLightFlags*/)
{ {
TL_Flag = in; TL_Flag = in;
} }
void setFog(SColor color_fog) void setFog(SColor color_fog)
{ {
fog_color_sample = color_to_sample(color_fog); fog_color_sample = color_to_sample(color_fog);
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)
{ {
Scissor = scissor; Scissor = scissor;
} }
protected: u32 fragment_draw_count;
/*
const core::matrix4& uniform_mat4(const c8* name);
video::sVec4 uniform_vec4(const c8* name);
video::sVec4 uniform_vec3(const c8* name);
void constructor_IBurningShader(CBurningVideoDriver* driver); core::matrix4& varying_mat4(const c8* name);
video::sVec4 varying_vec4(const c8* name);
video::sVec4 varying_vec3(const c8* name);
*/
const f32* getUniform(const c8* name, EBurningUniformFlags flags) const;
CBurningVideoDriver *Driver; protected:
IShaderConstantSetCallBack* CallBack; //friend class CBurningVideoDriver;
E_MATERIAL_TYPE BaseMaterial;
s32 UserData;
core::array<BurningUniform> UniformInfo; void constructor_IBurningShader(CBurningVideoDriver* driver);
s32 getShaderConstantID(EBurningUniformFlags program, const c8* name);
bool setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count);
video::CImage* RenderTarget; CBurningVideoDriver* Driver;
CDepthBuffer* DepthBuffer; IShaderConstantSetCallBack* CallBack;
CStencilBuffer* Stencil; E_MATERIAL_TYPE BaseMaterial;
tVideoSample ColorMask; s32 UserData;
sInternalTexture IT[ BURNING_MATERIAL_MAX_TEXTURES ]; core::array<BurningUniform> UniformInfo;
s32 getShaderConstantID(EBurningUniformFlags program, const c8* name);
bool setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count);
static const tFixPointu dithermask[ 4 * 4]; video::CImage* RenderTarget;
CDepthBuffer* DepthBuffer;
CStencilBuffer* Stencil;
tVideoSample ColorMask;
//draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham sInternalTexture IT[BURNING_MATERIAL_MAX_TEXTURES];
size_t EdgeTestPass; //edge_test_flag
size_t EdgeTestPass_stack;
interlaced_control Interlaced; // passed from driver
eBurningStencilOp stencilOp[4]; static const tFixPointu dithermask[4 * 4];
tFixPoint AlphaRef;
int RenderPass_ShaderIsTransparent;
sScanConvertData ALIGN(16) scan; //draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham
sScanLineData line; size_t EdgeTestPass; //edge_test_flag
tVideoSample PrimitiveColor; //used if no color interpolation is defined interlaced_control Interlaced; // passed from driver
size_t /*eTransformLightFlags*/ TL_Flag; eBurningStencilOp stencilOp[4];
tFixPoint fog_color[4]; tFixPoint AlphaRef;
tVideoSample fog_color_sample; int RenderPass_ShaderIsTransparent;
AbsRectangle Scissor; sScanConvertData ALIGN(16) scan;
sScanLineData line;
tVideoSample PrimitiveColor; //used if no color interpolation is defined
inline tVideoSample color_to_sample(const video::SColor& color) const size_t /*eTransformLightFlags*/ TL_Flag;
{ tFixPoint fog_color[4];
//RenderTarget->getColorFormat() tVideoSample fog_color_sample;
AbsRectangle Scissor;
//core::stringc VertexShaderProgram;
//core::stringc PixelShaderProgram;
eBurningVertexShader VertexShaderProgram_buildin;
inline tVideoSample color_to_sample(const video::SColor& color) const
{
//RenderTarget->getColorFormat()
#if SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT == ECF_A8R8G8B8 #if SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT == ECF_A8R8G8B8
return color.color; return color.color;
#else #else
return color.toA1R5G5B5(); return color.toA1R5G5B5();
#endif #endif
} }
}; };
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver); IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlat2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureFlat2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlatWire2(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTextureFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRFlat2(CBurningVideoDriver* driver); IBurningShader* createTRFlat2(CBurningVideoDriver* driver);
IBurningShader* createTRFlatWire2(CBurningVideoDriver* driver); IBurningShader* createTRFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver); IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver); IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver); IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver); IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver); IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);
IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver); IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver);
IBurningShader* createTRTextureInverseAlphaBlend(CBurningVideoDriver* driver); IBurningShader* createTRTextureInverseAlphaBlend(CBurningVideoDriver* driver);
IBurningShader* createTRNormalMap(CBurningVideoDriver* driver); IBurningShader* createTRNormalMap(CBurningVideoDriver* driver);
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver); IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver); IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver);
IBurningShader* create_burning_shader_color(CBurningVideoDriver* driver); IBurningShader* create_burning_shader_color(CBurningVideoDriver* driver);
} // end namespace video burning_namespace_end
} // end namespace irr
#endif #endif

@ -9,26 +9,28 @@
#include "SoftwareDriver2_helper.h" #include "SoftwareDriver2_helper.h"
#include "irrAllocator.h" #include "irrAllocator.h"
#include "EPrimitiveTypes.h" #include "EPrimitiveTypes.h"
#include "SVertexIndex.h"
namespace irr burning_namespace_start
{
namespace video struct sVec4;
{
//! sVec2 used in BurningShader texture coordinates //! sVec2 used in BurningShader texture coordinates
struct sVec2 struct sVec2
{ {
f32 x; union
f32 y; {
struct { f32 x, y; };
struct { f32 s, t; } st;
};
sVec2 () {} sVec2() {}
sVec2 ( f32 s) : x ( s ), y ( s ) {} sVec2(f32 s) : x(s), y(s) {}
sVec2 ( f32 _x, f32 _y ) sVec2(f32 _x, f32 _y)
: x ( _x ), y ( _y ) {} : x(_x), y(_y) {}
void set ( f32 _x, f32 _y ) void set(f32 _x, f32 _y)
{ {
x = _x; x = _x;
y = _y; y = _y;
@ -37,8 +39,8 @@ struct sVec2
// f = a * t + b * ( 1 - t ) // f = a * t + b * ( 1 - t )
void interpolate(const sVec2& burning_restrict a, const sVec2& burning_restrict b, const ipoltype t) void interpolate(const sVec2& burning_restrict a, const sVec2& burning_restrict b, const ipoltype t)
{ {
x = (f32)(b.x + ( ( a.x - b.x ) * t )); x = (f32)(b.x + ((a.x - b.x) * t));
y = (f32)(b.y + ( ( a.y - b.y ) * t )); y = (f32)(b.y + ((a.y - b.y) * t));
} }
sVec2 operator-(const sVec2& other) const sVec2 operator-(const sVec2& other) const
@ -59,10 +61,10 @@ struct sVec2
sVec2 operator*(const f32 s) const sVec2 operator*(const f32 s) const
{ {
return sVec2(x * s , y * s); return sVec2(x * s, y * s);
} }
void operator*=( const f32 s) void operator*=(const f32 s)
{ {
x *= s; x *= s;
y *= s; y *= s;
@ -74,11 +76,29 @@ struct sVec2
y = other.y; y = other.y;
} }
// shader
/*
void operator=(const core::vector2df& other)
{
x = other.X;
y = other.Y;
}
*/
sVec2 st_op() const
{
return sVec2(x,y);
}
sVec2& st_op()
{
return *this;
}
void operator=(const sVec4& other);
}; };
#include "irrpack.h" #include "irrpack.h"
//! sVec2Pack is Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents Texutre Coordinates. //! sVec2Pack is Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents Texture Coordinates.
// Start address is not 4 byte aligned // Start address is not 4 byte aligned
struct sVec2Pack struct sVec2Pack
{ {
@ -137,35 +157,36 @@ struct sVec3Pack
#include "irrunpack.h" #include "irrunpack.h"
//! sVec4 used in Driver,BurningShader, direction/color //! sVec4 used in Driver,BurningShader, direction/color
struct sVec4 struct ALIGN(16) sVec4
{ {
union union
{ {
struct { f32 x, y, z, w; }; struct { f32 x, y, z, w; };
struct { f32 a, r, g, b; }; struct { f32 r, g, b, a; };
struct { f32 s, t, p, q; };
}; };
sVec4 () {} sVec4() {}
sVec4 ( f32 _x, f32 _y, f32 _z, f32 _w ) sVec4(f32 _x, f32 _y, f32 _z, f32 _w)
: x ( _x ), y ( _y ), z( _z ), w ( _w ){} : x(_x), y(_y), z(_z), w(_w) {}
// f = a * t + b * ( 1 - t ) // f = a * t + b * ( 1 - t )
void interpolate(const sVec4& burning_restrict a, const sVec4& burning_restrict b, const ipoltype t) REALINLINE void interpolate(const sVec4& burning_restrict a, const sVec4& burning_restrict b, const ipoltype t)
{ {
x = (f32)(b.x + ( ( a.x - b.x ) * t )); x = (f32)(b.x + ((a.x - b.x) * t));
y = (f32)(b.y + ( ( a.y - b.y ) * t )); y = (f32)(b.y + ((a.y - b.y) * t));
z = (f32)(b.z + ( ( a.z - b.z ) * t )); z = (f32)(b.z + ((a.z - b.z) * t));
w = (f32)(b.w + ( ( a.w - b.w ) * t )); w = (f32)(b.w + ((a.w - b.w) * t));
} }
sVec4 operator-(const sVec4& other) const sVec4 operator-(const sVec4& other) const
{ {
return sVec4(x - other.x, y - other.y, z - other.z,w - other.w); return sVec4(x - other.x, y - other.y, z - other.z, w - other.w);
} }
sVec4 operator+(const sVec4& other) const sVec4 operator+(const sVec4& other) const
{ {
return sVec4(x + other.x, y + other.y, z + other.z,w + other.w); return sVec4(x + other.x, y + other.y, z + other.z, w + other.w);
} }
void operator+=(const sVec4& other) void operator+=(const sVec4& other)
@ -178,15 +199,15 @@ struct sVec4
sVec4 operator*(const f32 s) const sVec4 operator*(const f32 s) const
{ {
return sVec4(x * s , y * s, z * s,w * s); return sVec4(x * s, y * s, z * s, w * s);
} }
sVec4 operator*(const sVec4 &other) const sVec4 operator*(const sVec4& other) const
{ {
return sVec4(x * other.x , y * other.y, z * other.z,w * other.w); return sVec4(x * other.x, y * other.y, z * other.z, w * other.w);
} }
void operator*=(const sVec4 &other) void operator*=(const sVec4& other)
{ {
x *= other.x; x *= other.x;
y *= other.y; y *= other.y;
@ -194,12 +215,13 @@ struct sVec4
w *= other.w; w *= other.w;
} }
void operator=(const sVec4& other) sVec4& operator=(const sVec4& other)
{ {
x = other.x; x = other.x;
y = other.y; y = other.y;
z = other.z; z = other.z;
w = other.w; w = other.w;
return *this;
} }
//outside shader //outside shader
@ -210,13 +232,7 @@ struct sVec4
z = _z; z = _z;
w = _w; w = _w;
} }
void setA8R8G8B8(const u32 argb)
{
a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);
g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);
b = ((argb & 0x000000FF) ) * (1.f / 255.f);
}
REALINLINE ipoltype dot_xyzw(const sVec4& other) const REALINLINE ipoltype dot_xyzw(const sVec4& other) const
{ {
@ -230,7 +246,7 @@ struct sVec4
REALINLINE f32 dot_minus_xyz(const sVec4& other) const REALINLINE f32 dot_minus_xyz(const sVec4& other) const
{ {
return -x * other.x + -y * other.y + -z * other.z; return x * -other.x + y * -other.y + z * -other.z;
} }
void mul_xyz(const f32 s) void mul_xyz(const f32 s)
@ -249,12 +265,41 @@ struct sVec4
{ {
//const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z); //const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z);
f32 l = x * x + y * y + z * z; f32 l = x * x + y * y + z * z;
l = l > 0.0000001f ? 1.f / sqrtf(l) : 1.f; if (l > 0.00000001f)
x *= l; {
y *= l; l = 1.f / sqrtf(l);
z *= l; x *= l;
y *= l;
z *= l;
}
else
{
x = 0.f;
y = -1.f;
z = 0.f;
}
} }
void normalize_dir_xyz_zero()
{
//const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z);
f32 l = x * x + y * y + z * z;
if (l > 0.00000001f)
{
l = 1.f / sqrtf(l);
x *= l;
y *= l;
z *= l;
}
else
{
x = 0.f;
y = 0.f;
z = 0.f;
}
}
//unpack sVec3 to aligned during runtime //unpack sVec3 to aligned during runtime
sVec4(const sVec3Pack& other) sVec4(const sVec3Pack& other)
@ -271,20 +316,36 @@ struct sVec4
f32 l = x * x + y * y + z * z; f32 l = x * x + y * y + z * z;
l = l > 0.0000001f ? len / sqrtf(l) : 0.f; l = l > 0.0000001f ? len / sqrtf(l) : 0.f;
out.x = (x*l) + ofs; out.x = (x * l) + ofs;
out.y = (y*l) + ofs; out.y = (y * l) + ofs;
out.z = (z*l) + ofs; out.z = (z * l) + ofs;
} }
}; //shader suppport
sVec4(const sVec4& a, double w)
{
x = a.x;
y = a.y;
z = a.z;
this->w = (float)w;
}
sVec4 xyz() const
{
return sVec4(x, y, z, 0.f);
}
//!during runtime sVec3Pack //operator f32* () { return &x; }
typedef sVec4 sVec3Pack_unpack;
//!sVec4 is argb. sVec3Color is rgba void clampf01()
struct sVec3Color {
{ if (x < 0.f) x = 0.f; else if (x > 1.f) x = 1.f;
f32 r, g, b,a; if (y < 0.f) y = 0.f; else if (y > 1.f) y = 1.f;
if (z < 0.f) z = 0.f; else if (z > 1.f) z = 1.f;
if (w < 0.f) w = 0.f; else if (w > 1.f) w = 1.f;
}
//Color
void setA8R8G8B8(const u32 argb);
void set(const f32 s) void set(const f32 s)
{ {
@ -294,15 +355,101 @@ struct sVec3Color
a = s; a = s;
} }
void setA8R8G8B8(const u32 argb) void setColorf(const video::SColorf& color)
{ {
r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f); r = color.r;
g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f); g = color.g;
b = ((argb & 0x000000FF) ) * (1.f / 255.f); b = color.b;
a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f); a = color.a;
} }
void setColorf(const video::SColorf & color) void add_rgb(const sVec4& other)
{
r += other.r;
g += other.g;
b += other.b;
}
void mad_rgb(const sVec4& other, const f32 v)
{
r += other.r * v;
g += other.g * v;
b += other.b * v;
}
void mad_rgbv(const sVec4& v0, const sVec4& v1)
{
r += v0.r * v1.r;
g += v0.g * v1.g;
b += v0.b * v1.b;
}
//sVec4 is a,r,g,b, alpha pass
/*
void sat(sVec4& dest, const u32 argb) const
{
dest.a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
dest.r = r <= 1.f ? r : 1.f;
dest.g = g <= 1.f ? g : 1.f;
dest.b = b <= 1.f ? b : 1.f;
}
*/
void sat_alpha_pass(sVec4& dest, const f32 vertex_alpha) const
{
dest.a = vertex_alpha;
dest.r = r <= 1.f ? r : 1.f;
dest.g = g <= 1.f ? g : 1.f;
dest.b = b <= 1.f ? b : 1.f;
}
void sat_mul_xyz(sVec4& dest, const sVec4& v1) const
{
f32 v;
dest.a = 1.f;
v = r * v1.r; dest.r = v < 1.f ? v : 1.f;
v = g * v1.g; dest.g = v < 1.f ? v : 1.f;
v = b * v1.b; dest.b = v < 1.f ? v : 1.f;
}
void sat_mul_xyz(sVec3Pack& dest, const sVec4& v1) const
{
f32 v;
v = r * v1.r; dest.x = v < 1.f ? v : 1.f;
v = g * v1.g; dest.y = v < 1.f ? v : 1.f;
v = b * v1.b; dest.z = v < 1.f ? v : 1.f;
}
};
//shader
inline void irr::video::sVec2::operator=(const sVec4& b)
{
x = b.x;
y = b.y;
}
//!during runtime sVec3Pack
typedef sVec4 sVec3Pack_unpack;
typedef sVec4 sVec3Color;
#if 0
//!sVec4 is argb. sVec3Color is rgba
struct sVec3Color
{
f32 r, g, b, a;
void set(const f32 s)
{
r = s;
g = s;
b = s;
a = s;
}
void setColorf(const video::SColorf& color)
{ {
r = color.r; r = color.r;
g = color.g; g = color.g;
@ -332,7 +479,7 @@ struct sVec3Color
} }
//sVec4 is a,r,g,b, alpha pass //sVec4 is a,r,g,b, alpha pass
void sat(sVec4 &dest, const u32 argb) const void sat(sVec4& dest, const u32 argb) const
{ {
dest.a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f); dest.a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
dest.r = r <= 1.f ? r : 1.f; dest.r = r <= 1.f ? r : 1.f;
@ -340,7 +487,7 @@ struct sVec3Color
dest.b = b <= 1.f ? b : 1.f; dest.b = b <= 1.f ? b : 1.f;
} }
void sat_xyz(sVec3Pack &dest, const sVec3Color& v1) const void sat_xyz(sVec3Pack& dest, const sVec3Color& v1) const
{ {
f32 v; f32 v;
v = r * v1.r; dest.x = v < 1.f ? v : 1.f; v = r * v1.r; dest.x = v < 1.f ? v : 1.f;
@ -348,7 +495,7 @@ struct sVec3Color
v = b * v1.b; dest.z = v < 1.f ? v : 1.f; v = b * v1.b; dest.z = v < 1.f ? v : 1.f;
} }
void sat_xyz(sVec4 &dest, const sVec3Color& v1) const void sat_xyz(sVec4& dest, const sVec3Color& v1) const
{ {
f32 v; f32 v;
dest.a = 1.f; dest.a = 1.f;
@ -357,46 +504,47 @@ struct sVec3Color
v = b * v1.b; dest.b = v < 1.f ? v : 1.f; v = b * v1.b; dest.b = v < 1.f ? v : 1.f;
} }
}; };
#endif
//internal BurningShaderFlag for a Vertex //internal BurningShaderFlag for a Vertex
enum e4DVertexFlag enum e4DVertexFlag
{ {
VERTEX4D_CLIPMASK = 0x0000003F, VERTEX4D_CLIPMASK = 0x0000003F,
VERTEX4D_CLIP_NEAR = 0x00000001, VERTEX4D_CLIP_NEAR = 0x00000001,
VERTEX4D_CLIP_FAR = 0x00000002, VERTEX4D_CLIP_FAR = 0x00000002,
VERTEX4D_CLIP_LEFT = 0x00000004, VERTEX4D_CLIP_LEFT = 0x00000004,
VERTEX4D_CLIP_RIGHT = 0x00000008, VERTEX4D_CLIP_RIGHT = 0x00000008,
VERTEX4D_CLIP_BOTTOM = 0x00000010, VERTEX4D_CLIP_BOTTOM = 0x00000010,
VERTEX4D_CLIP_TOP = 0x00000020, VERTEX4D_CLIP_TOP = 0x00000020,
VERTEX4D_INSIDE = 0x0000003F, VERTEX4D_INSIDE = 0x0000003F,
VERTEX4D_PROJECTED = 0x00000100, VERTEX4D_PROJECTED = 0x00000100,
VERTEX4D_VAL_ZERO = 0x00000200, //VERTEX4D_VAL_ZERO = 0x00000200,
VERTEX4D_VAL_ONE = 0x00000400, //VERTEX4D_VAL_ONE = 0x00000400,
VERTEX4D_FORMAT_MASK = 0xFFFF0000, VERTEX4D_FORMAT_MASK = 0xFFFF0000,
VERTEX4D_FORMAT_MASK_TEXTURE = 0x000F0000, VERTEX4D_FORMAT_MASK_TEXTURE = 0x000F0000,
VERTEX4D_FORMAT_TEXTURE_1 = 0x00010000, VERTEX4D_FORMAT_TEXTURE_1 = 0x00010000,
VERTEX4D_FORMAT_TEXTURE_2 = 0x00020000, VERTEX4D_FORMAT_TEXTURE_2 = 0x00020000,
VERTEX4D_FORMAT_TEXTURE_3 = 0x00030000, VERTEX4D_FORMAT_TEXTURE_3 = 0x00030000,
VERTEX4D_FORMAT_TEXTURE_4 = 0x00040000, VERTEX4D_FORMAT_TEXTURE_4 = 0x00040000,
VERTEX4D_FORMAT_MASK_COLOR = 0x00F00000, VERTEX4D_FORMAT_MASK_COLOR = 0x00F00000,
VERTEX4D_FORMAT_COLOR_1 = 0x00100000, VERTEX4D_FORMAT_COLOR_1 = 0x00100000,
VERTEX4D_FORMAT_COLOR_2_FOG = 0x00200000, VERTEX4D_FORMAT_COLOR_2_FOG = 0x00200000,
VERTEX4D_FORMAT_COLOR_3 = 0x00300000, VERTEX4D_FORMAT_COLOR_3 = 0x00300000,
VERTEX4D_FORMAT_COLOR_4 = 0x00400000, VERTEX4D_FORMAT_COLOR_4 = 0x00400000,
VERTEX4D_FORMAT_MASK_LIGHT = 0x0F000000, VERTEX4D_FORMAT_MASK_LIGHT = 0x0F000000,
VERTEX4D_FORMAT_LIGHT_1 = 0x01000000, VERTEX4D_FORMAT_LIGHT_1 = 0x01000000,
VERTEX4D_FORMAT_LIGHT_2 = 0x02000000, VERTEX4D_FORMAT_LIGHT_2 = 0x02000000,
VERTEX4D_FORMAT_MASK_TANGENT = 0xF0000000, VERTEX4D_FORMAT_MASK_TANGENT = 0xF0000000,
VERTEX4D_FORMAT_BUMP_DOT3 = 0x10000000, VERTEX4D_FORMAT_BUMP_DOT3 = 0x10000000,
VERTEX4D_FORMAT_SPECULAR = 0x20000000, VERTEX4D_FORMAT_SPECULAR = 0x20000000,
}; };
@ -418,28 +566,28 @@ enum e4DIndexType
{ {
E4IT_16BIT = 1, // EIT_16BIT, E4IT_16BIT = 1, // EIT_16BIT,
E4IT_32BIT = 2, // EIT_32BIT, E4IT_32BIT = 2, // EIT_32BIT,
E4IT_NONE = 4, // E4IT_NONE = 4, //
}; };
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL #if defined(BURNINGVIDEO_RENDERER_BEAUTIFUL) || defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#define BURNING_MATERIAL_MAX_TEXTURES 4 #define BURNING_MATERIAL_MAX_TEXTURES 4
#define BURNING_MATERIAL_MAX_COLORS 4 #define BURNING_MATERIAL_MAX_COLORS 4
#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1 #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
//ensure handcrafted sizeof(s4DVertex) //ensure handcrafted sizeof(s4DVertex)
#define sizeof_s4DVertex 128 #define sizeof_s4DVertex 128
#else #else
#define BURNING_MATERIAL_MAX_TEXTURES 2 #define BURNING_MATERIAL_MAX_TEXTURES 2
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define BURNING_MATERIAL_MAX_COLORS 1 #define BURNING_MATERIAL_MAX_COLORS 1
#else #else
#define BURNING_MATERIAL_MAX_COLORS 0 #define BURNING_MATERIAL_MAX_COLORS 0
#endif #endif
#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1 #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
//ensure handcrafted sizeof(s4DVertex) //ensure handcrafted sizeof(s4DVertex)
#define sizeof_s4DVertex 64 #define sizeof_s4DVertex 64
#endif #endif
// dummy Vertex. used for calculation vertex memory size // dummy Vertex. used for calculation vertex memory size
@ -467,10 +615,10 @@ struct s4DVertex
{ {
sVec4 Pos; sVec4 Pos;
#if BURNING_MATERIAL_MAX_TEXTURES > 0 #if BURNING_MATERIAL_MAX_TEXTURES > 0
sVec2 Tex[ BURNING_MATERIAL_MAX_TEXTURES ]; sVec2 Tex[BURNING_MATERIAL_MAX_TEXTURES];
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS > 0 #if BURNING_MATERIAL_MAX_COLORS > 0
sVec4 Color[ BURNING_MATERIAL_MAX_COLORS ]; sVec4 Color[BURNING_MATERIAL_MAX_COLORS];
#endif #endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0 #if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT]; sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];
@ -480,13 +628,13 @@ struct s4DVertex
#if BURNING_MATERIAL_MAX_COLORS < 1 || BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1 #if BURNING_MATERIAL_MAX_COLORS < 1 || BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1
u8 __align [sizeof_s4DVertex - sizeof (s4DVertex_proxy) ]; u8 __align[sizeof_s4DVertex - sizeof(s4DVertex_proxy)];
#endif #endif
// f = a * t + b * ( 1 - t ) // f = a * t + b * ( 1 - t )
void interpolate(const s4DVertex& burning_restrict b, const s4DVertex& burning_restrict a, const ipoltype t) REALINLINE void interpolate(const s4DVertex& burning_restrict b, const s4DVertex& burning_restrict a, const ipoltype t)
{ {
Pos.interpolate ( a.Pos, b.Pos, t ); Pos.interpolate(a.Pos, b.Pos, t);
#if 0 #if 0
Tex[0].interpolate(a.Tex[0], b.Tex[0], t); Tex[0].interpolate(a.Tex[0], b.Tex[0], t);
Tex[1].interpolate(a.Tex[1], b.Tex[1], t); Tex[1].interpolate(a.Tex[1], b.Tex[1], t);
@ -499,45 +647,103 @@ struct s4DVertex
#if BURNING_MATERIAL_MAX_TEXTURES > 0 #if BURNING_MATERIAL_MAX_TEXTURES > 0
size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16; size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;
for ( i = 0; i!= size; ++i ) for (i = 0; i != size; ++i)
{ {
Tex[i].interpolate ( a.Tex[i], b.Tex[i], t ); Tex[i].interpolate(a.Tex[i], b.Tex[i], t);
} }
#endif #endif
#if BURNING_MATERIAL_MAX_COLORS > 0 #if BURNING_MATERIAL_MAX_COLORS > 0
size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20; size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;
for ( i = 0; i!= size; ++i ) for (i = 0; i != size; ++i)
{ {
Color[i].interpolate ( a.Color[i], b.Color[i], t ); Color[i].interpolate(a.Color[i], b.Color[i], t);
} }
#endif #endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0 #if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24; size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;
for ( i = 0; i!= size; ++i ) for (i = 0; i != size; ++i)
{ {
LightTangent[i].interpolate ( a.LightTangent[i], b.LightTangent[i], t ); LightTangent[i].interpolate(a.LightTangent[i], b.LightTangent[i], t);
} }
#endif #endif
} }
REALINLINE void reset_interpolate()
{
#if 1
#if BURNING_MATERIAL_MAX_TEXTURES > 0
Tex[0].x = 0.f;
Tex[0].y = 0.f;
#endif
#if BURNING_MATERIAL_MAX_TEXTURES > 1
Tex[1].x = 0.f;
Tex[1].y = 0.f;
#endif
#if BURNING_MATERIAL_MAX_TEXTURES > 2
Tex[2].x = 0.f;
Tex[2].y = 0.f;
#endif
#if BURNING_MATERIAL_MAX_TEXTURES > 3
Tex[3].x = 0.f;
Tex[3].y = 0.f;
#endif
#endif
#if BURNING_MATERIAL_MAX_COLORS > 0
Color[0].r = 0.f;
Color[0].g = 0.f;
Color[0].b = 0.f;
Color[0].a = 1.f;
#endif
#if BURNING_MATERIAL_MAX_COLORS > 1
//specular
Color[1].r = 0.f;
Color[1].g = 0.f;
Color[1].b = 0.f;
Color[1].a = 1.f;
#endif
#if BURNING_MATERIAL_MAX_COLORS > 2
Color[2].r = 0.f;
Color[2].g = 0.f;
Color[2].b = 0.f;
Color[2].a = 1.f;
#endif
#if BURNING_MATERIAL_MAX_COLORS > 3
Color[3].r = 0.f;
Color[3].g = 0.f;
Color[3].b = 0.f;
Color[3].a = 1.f;
#endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
LightTangent[0].x = 0.f;
LightTangent[0].y = 0.f;
LightTangent[0].z = 0.f;
#endif
}
}; };
// ----------------- Vertex Cache --------------------------- // ----------------- Vertex Cache ---------------------------
// Buffer is used as pairs of S4DVertex (0 ... ndc, 1 .. dc and projected) // Buffer is used as interleaved pairs of S4DVertex (0 ... ndc, 1 .. dc and projected)
typedef s4DVertex s4DVertexPair; typedef s4DVertex s4DVertexPair;
#define sizeof_s4DVertexPairRel 2 #define sizeof_s4DVertexPairRel 2
#define s4DVertex_ofs(index) ((index)*sizeof_s4DVertexPairRel) #define s4DVertex_ofs(index) ((index)*sizeof_s4DVertexPairRel)
#define s4DVertex_proj(index) ((index)*sizeof_s4DVertexPairRel) + 1 #define s4DVertex_pro(index) (((index)*sizeof_s4DVertexPairRel) + 1)
struct SAligned4DVertex struct SAligned4DVertex
{ {
SAligned4DVertex() SAligned4DVertex()
:data(0),ElementSize(0),mem(0) {} :data(0), ElementSize(0), mem(0) {}
virtual ~SAligned4DVertex () virtual ~SAligned4DVertex()
{ {
if (mem) if (mem)
{ {
@ -581,17 +787,17 @@ static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const vo
u64* burning_restrict dst64 = (u64*)dst; u64* burning_restrict dst64 = (u64*)dst;
const u64* burning_restrict src64 = (const u64*)src; const u64* burning_restrict src64 = (const u64*)src;
dst64[0] = src64[0]; dst64[0] = src64[0];
dst64[1] = src64[1]; dst64[1] = src64[1];
dst64[2] = src64[2]; dst64[2] = src64[2];
dst64[3] = src64[3]; dst64[3] = src64[3];
dst64[4] = src64[4]; dst64[4] = src64[4];
dst64[5] = src64[5]; dst64[5] = src64[5];
dst64[6] = src64[6]; dst64[6] = src64[6];
dst64[7] = src64[7]; dst64[7] = src64[7];
dst64[8] = src64[8]; dst64[8] = src64[8];
dst64[9] = src64[9]; dst64[9] = src64[9];
dst64[10] = src64[10]; dst64[10] = src64[10];
dst64[11] = src64[11]; dst64[11] = src64[11];
dst64[12] = src64[12]; dst64[12] = src64[12];
@ -603,17 +809,17 @@ static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const vo
u64* burning_restrict dst64 = (u64*)dst; u64* burning_restrict dst64 = (u64*)dst;
const u64* burning_restrict src64 = (const u64*)src; const u64* burning_restrict src64 = (const u64*)src;
dst64[0] = src64[0]; dst64[0] = src64[0];
dst64[1] = src64[1]; dst64[1] = src64[1];
dst64[2] = src64[2]; dst64[2] = src64[2];
dst64[3] = src64[3]; dst64[3] = src64[3];
dst64[4] = src64[4]; dst64[4] = src64[4];
dst64[5] = src64[5]; dst64[5] = src64[5];
dst64[6] = src64[6]; dst64[6] = src64[6];
dst64[7] = src64[7]; dst64[7] = src64[7];
dst64[8] = src64[8]; dst64[8] = src64[8];
dst64[9] = src64[9]; dst64[9] = src64[9];
dst64[10] = src64[10]; dst64[10] = src64[10];
dst64[11] = src64[11]; dst64[11] = src64[11];
dst64[12] = src64[12]; dst64[12] = src64[12];
@ -656,13 +862,13 @@ static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const vo
*dst32++ = *src32++; *dst32++ = *src32++;
len -= 32; len -= 32;
} }
/* /*
while (len >= 4) while (len >= 4)
{ {
*dst32++ = *src32++; *dst32++ = *src32++;
len -= 4; len -= 4;
} }
*/ */
#endif #endif
} }
@ -670,14 +876,14 @@ static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const vo
//! hold info for different Vertex Types //! hold info for different Vertex Types
struct SVSize struct SVSize
{ {
size_t Format; // e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE u32 Format; // e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE
size_t Pitch; // sizeof Vertex u32 Pitch; // sizeof Vertex
size_t TexSize; // amount Textures u32 TexSize; // amount Textures
size_t TexCooSize; // sizeof TextureCoordinates u32 TexCooSize; // sizeof TextureCoordinates
}; };
// a cache info // index cache info
struct SCacheInfo struct SCacheInfo
{ {
u32 index; u32 index;
@ -687,18 +893,14 @@ struct SCacheInfo
//must at least hold all possible (clipped) vertices of primitive. //must at least hold all possible (clipped) vertices of primitive.
#define VERTEXCACHE_ELEMENT 16 #define VERTEXCACHE_ELEMENT 16
#define VERTEXCACHE_MISS 0xFFFFFFFF #define VERTEXCACHE_MISS 0xFFFFFFFF
struct SVertexCache struct SVertexShader
{ {
SVertexCache () {} SVertexShader() {}
~SVertexCache() {} ~SVertexShader() {}
//VertexType //VertexType
SVSize vSize[E4VT_COUNT]; SVSize vSize[E4VT_COUNT];
SCacheInfo info[VERTEXCACHE_ELEMENT];
SCacheInfo info_temp[VERTEXCACHE_ELEMENT];
// Transformed and lite, clipping state // Transformed and lite, clipping state
// + Clipped, Projected // + Clipped, Projected
SAligned4DVertex mem; SAligned4DVertex mem;
@ -714,12 +916,50 @@ struct SVertexCache
u32 indicesPitch; u32 indicesPitch;
// primitives consist of x vertices // primitives consist of x vertices
size_t primitiveHasVertex; u32 primitiveHasVertex;
u32 primitiveRun;
e4DVertexType vType; //E_VERTEX_TYPE e4DVertexType vType; //E_VERTEX_TYPE
scene::E_PRIMITIVE_TYPE pType; //scene::E_PRIMITIVE_TYPE scene::E_PRIMITIVE_TYPE pType; //scene::E_PRIMITIVE_TYPE
e4DIndexType iType; //E_INDEX_TYPE iType e4DIndexType iType; //E_INDEX_TYPE iType
REALINLINE u32 index(u32 i) const
{
u32 o;
if (i >= indexCount)
i = 0;
switch (iType)
{
case E4IT_16BIT: o = ((u16*)indices)[i]; break;
case E4IT_32BIT: o = ((u32*)indices)[i]; break;
default: case E4IT_NONE: o = i; break;
}
return o;
}
REALINLINE s4DVertexPair* vertex(const u32 sourceIndex) const
{
for (size_t i = 0; i < VERTEXCACHE_ELEMENT; ++i)
{
if (info[i].index == sourceIndex)
{
return mem.data + s4DVertex_ofs(i);
}
}
return mem.data; //error
}
void setPrimitiveType(const scene::E_PRIMITIVE_TYPE pType, const u32 primitiveCount);
void setIndices(const void* indices, const video::E_INDEX_TYPE iType);
SCacheInfo info[VERTEXCACHE_ELEMENT];
SCacheInfo info_temp[VERTEXCACHE_ELEMENT];
void set_info_miss();
u32 fillIndex;
void get_next_index_cacheline();
void getPrimitive(s4DVertexPair* face[4],CBurningVideoDriver* driver);
}; };
@ -804,8 +1044,8 @@ struct sScanLineData
// passed to pixel Shader // passed to pixel Shader
struct sPixelShaderData struct sPixelShaderData
{ {
tVideoSample *dst; tVideoSample* dst;
fp24 *z; fp24* z;
s32 xStart; s32 xStart;
s32 xEnd; s32 xEnd;
@ -816,7 +1056,7 @@ struct sPixelShaderData
/* /*
load a color value load a color value
*/ */
REALINLINE void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v ) REALINLINE void getTexel_plain2(tFixPoint& r, tFixPoint& g, tFixPoint& b, const sVec4& v)
{ {
r = tofix(v.r, FIX_POINT_F32_MUL); r = tofix(v.r, FIX_POINT_F32_MUL);
g = tofix(v.g, FIX_POINT_F32_MUL); g = tofix(v.g, FIX_POINT_F32_MUL);
@ -827,22 +1067,22 @@ REALINLINE void getTexel_plain2 ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const
/* /*
load a color value load a color value
*/ */
REALINLINE void getSample_color ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const sVec4 &v ) REALINLINE void getSample_color(tFixPoint& a, tFixPoint& r, tFixPoint& g, tFixPoint& b, const sVec4& v)
{ {
a = tofix ( v.a, FIX_POINT_F32_MUL); a = tofix(v.a, FIX_POINT_F32_MUL);
r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL); r = tofix(v.r, COLOR_MAX * FIX_POINT_F32_MUL);
g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL); g = tofix(v.g, COLOR_MAX * FIX_POINT_F32_MUL);
b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL); b = tofix(v.b, COLOR_MAX * FIX_POINT_F32_MUL);
} }
/* /*
load a color value load a color value
*/ */
REALINLINE void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v ) REALINLINE void getSample_color(tFixPoint& r, tFixPoint& g, tFixPoint& b, const sVec4& v)
{ {
r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL); r = tofix(v.r, COLOR_MAX * FIX_POINT_F32_MUL);
g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL); g = tofix(v.g, COLOR_MAX * FIX_POINT_F32_MUL);
b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL); b = tofix(v.b, COLOR_MAX * FIX_POINT_F32_MUL);
} }
#endif #endif
@ -850,14 +1090,15 @@ REALINLINE void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const
load a color value. mulby controls [0;1] or [0;ColorMax] load a color value. mulby controls [0;1] or [0;ColorMax]
aka getSample_color aka getSample_color
*/ */
REALINLINE void vec4_to_fix(tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby ) REALINLINE void vec4_to_fix(tFixPoint& r, tFixPoint& g, tFixPoint& b, const sVec4& v, const f32 mulby)
{ {
r = tofix(v.r, mulby); r = tofix(v.r, mulby);
g = tofix(v.g, mulby); g = tofix(v.g, mulby);
b = tofix(v.b, mulby); b = tofix(v.b, mulby);
} }
REALINLINE void vec4_to_fix(tFixPoint &a,tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby)
REALINLINE void vec4_to_fix(tFixPoint& a, tFixPoint& r, tFixPoint& g, tFixPoint& b, const sVec4& v, const f32 mulby)
{ {
a = tofix(v.a, mulby); a = tofix(v.a, mulby);
r = tofix(v.r, mulby); r = tofix(v.r, mulby);
@ -865,9 +1106,5 @@ REALINLINE void vec4_to_fix(tFixPoint &a,tFixPoint &r, tFixPoint &g, tFixPoint &
b = tofix(v.b, mulby); b = tofix(v.b, mulby);
} }
burning_namespace_end
}
}
#endif #endif

@ -10,7 +10,7 @@
// 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 1 && defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if 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_PERSPECTIVE_CORRECT
@ -18,19 +18,19 @@
#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_USE_WBUFFER #define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_32BIT #define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A8R8G8B8 #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_RENDERTARGET_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_MAXSIZE 0x100000
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 8 #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1 #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D #define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED #define SOFTWARE_DRIVER_2_INTERLACED
#define SOFTWARE_DRIVER_2_RENDERTARGET_SCALE
#endif #endif
@ -49,10 +49,10 @@
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16 #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1 #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D #define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED #define SOFTWARE_DRIVER_2_INTERLACED
#define SOFTWARE_DRIVER_2_RENDERTARGET_SCALE
#endif #endif
//! Set Flags for Windows Mobile //! Set Flags for Windows Mobile
@ -70,7 +70,6 @@
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4 #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8 #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING //#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_2D_AS_2D
#endif #endif
@ -88,7 +87,6 @@
#define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5 #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4 #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8 #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING #define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED #define SOFTWARE_DRIVER_2_INTERLACED
@ -104,13 +102,12 @@
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_USE_WBUFFER //#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_16BIT #define SOFTWARE_DRIVER_2_16BIT
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 128 #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5 #define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5 #define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1 #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 1
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1 #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING //#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D #define SOFTWARE_DRIVER_2_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED #define SOFTWARE_DRIVER_2_INTERLACED
@ -126,6 +123,7 @@
#endif #endif
#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f) #define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)
#define reciprocal_zero_pos_underflow(x) ((x) != 0.f ? 1.f / (x):0.f)
#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f) #define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)
//Control Scanline output //Control Scanline output
@ -138,44 +136,72 @@ static inline float fill_step_x(float x) { return x != 0.f ? (float)SOFTWARE_DRI
#define interlace_control_bit 1 #define interlace_control_bit 1
#define interlace_control_mask ((1<<interlace_control_bit)-1) #define interlace_control_mask ((1<<interlace_control_bit)-1)
struct interlaced_control union interlaced_control
{ {
unsigned enable : 1; struct {
unsigned bypass : 1; unsigned enable : 1;
unsigned nr : interlace_control_bit; unsigned bypass : 1;
unsigned nr : interlace_control_bit;
unsigned target_scalex : 2; // 0 means 1
unsigned target_scaley : 2;
unsigned tex_scalex : 2; // 0 means 1
unsigned tex_scaley : 2;
};
unsigned raw;
}; };
struct interlace_scanline_data { unsigned int y; }; struct interlace_scanline_data { unsigned int y; };
static inline interlaced_control interlace_disabled() static inline interlaced_control interlaced_disabled()
{ {
interlaced_control v; interlaced_control v;
v.raw = 0;
v.bypass = 1;
/*
v.enable = 0; v.enable = 0;
v.bypass = 1; v.bypass = 1;
v.nr = 0; v.nr = 0;
v.target_scalex = 0;
v.target_scaley = 0;
v.tex_scalex = 0;
v.tex_scaley = 0;
*/
return v; return v;
} }
#if defined(SOFTWARE_DRIVER_2_INTERLACED) #if defined(SOFTWARE_DRIVER_2_INTERLACED)
#define interlace_scanline if ( Interlaced.bypass | ((line.y & interlace_control_mask) == Interlaced.nr) ) #define interlace_scanline_active ((line.y & interlace_control_mask) == Interlaced.nr)
#define interlace_scanline_enabled if ( (line.y & interlace_control_mask) == Interlaced.nr ) #define if_interlace_scanline_active if (interlace_scanline_active)
//#define interlace_scanline if ( Interlaced.disabled | (((line.y >> (interlace_control_bit-1) ) & 1) == (Interlaced.nr & 1)) ) #define if_interlace_scanline if ( Interlaced.bypass || interlace_scanline_active )
//#define interlace_scanline
#else #else
#define interlace_scanline #define if_interlace_scanline_active
#define interlace_scanline_enabled #define if_interlace_scanline
#endif #endif
#define scissor_test_y if ((~TL_Flag & TL_SCISSOR) || ((line.y >= Scissor.y0) & (line.y <= Scissor.y1))) #define if_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 if_scissor_test_x if ((~TL_Flag & TL_SCISSOR) || ((i+xStart >= Scissor.x0) & (i+xStart <= Scissor.x1)))
// https://inst.eecs.berkeley.edu/~cs184/sp04/as/as2/assgn-02_faqs.html
//#define fill_convention_top_left(x) (s32) ceilf(x)
//#define fill_convention_right(x) (s32) floorf(x)
//#define fill_convention_right(x) (((s32) ceilf(x))-1)
// http://www.chrishecker.com/images/9/97/Gdmtex2.pdf
#define fill_convention_top(y) (s32) ceilf(y)
#define fill_convention_down(y) (((s32) ceilf(y))-1)
#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_edge(x) (s32) floorf(fabsf(x))
//#define fill_convention_left(x) 65536 - int(65536.0f - x)
//fixpoint
//#define fill_convention_top_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)
//Check coordinates are in render target/window space //Check that coordinates are in render target/window space
//#define SOFTWARE_DRIVER_2_DO_CLIPCHECK //#define SOFTWARE_DRIVER_2_DO_CLIPCHECK
#if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32) #if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32)
#define SOFTWARE_DRIVER_2_CLIPCHECK if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak() #define SOFTWARE_DRIVER_2_CLIPCHECK if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
@ -241,6 +267,7 @@ 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_lower_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 )
@ -249,29 +276,20 @@ typedef float ipoltype;
#define burning_restrict #define burning_restrict
#endif #endif
/* #if 0 && defined(_MSC_VER) && (_MSC_VER > 1500) && !defined(_DEBUG)
if (condition) state |= mask; else state &= ~mask; #pragma auto_inline(on)
*/ #pragma inline_depth(255)
static inline void burning_setbit(size_t& state, int condition, size_t mask) #pragma inline_recursion(on)
{ #endif
if (condition) state |= mask;
else state &= ~mask;
}
/*
if (condition) state |= m; else state &= ~m;
*/
REALINLINE void burning_setbit32(unsigned int& state, int condition, const unsigned int mask)
{
// 0, or any positive to mask
//s32 conmask = -condition >> 31;
state ^= ((-condition >> 31) ^ state) & mask;
}
#define burning_stringify(s) #s #define burning_stringify(s) #s
#define burning_create_indirect(s) create_##s #define burning_create_indirect(s) create_##s
#define burning_create(s) burning_create_indirect(s) #define burning_create(s) burning_create_indirect(s)
// don't want intend on namespaces (autoformat)
#define burning_namespace_start namespace irr { namespace video {
#define burning_namespace_end } /* end namespace video*/ } /* end namespace irr */
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) #if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
#define snprintf_irr sprintf_s #define snprintf_irr sprintf_s

File diff suppressed because it is too large Load Diff

@ -41,7 +41,7 @@ void burning_shader_class::OnSetMaterial(const SBurningShaderMaterial& material)
case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA: case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:
case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA: case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
RenderPass_ShaderIsTransparent = 1; RenderPass_ShaderIsTransparent = 1;
AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX); AlphaRef = tofix(material.org.MaterialTypeParam, FIX_POINT_COLOR_MAX);
break; break;
default: default:
RenderPass_ShaderIsTransparent = 0; RenderPass_ShaderIsTransparent = 0;
@ -53,7 +53,9 @@ void burning_shader_class::OnSetMaterial(const SBurningShaderMaterial& material)
{ {
if (material.org.ZBuffer == ECFN_LESSEQUAL) if (material.org.ZBuffer == ECFN_LESSEQUAL)
{ {
if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero; if (material.org.ColorMask == ECP_NONE)
fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_colormask_none;
else if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;
else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_one_zero; else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_one_zero;
} }
else /*if (material.org.ZBuffer == ECFN_DISABLED)*/ else /*if (material.org.ZBuffer == ECFN_DISABLED)*/

@ -1,8 +1,8 @@
// pixelshader // pixelshader
#ifdef IPOL_C0 #ifdef IPOL_C0
#ifdef IPOL_A0
vec4_to_fix(a0, r0, g0, b0, line.c[0][0], inversew); vec4_to_fix(a0, r0, g0, b0, line.c[0][0], inversew);
#ifdef IPOL_A0
if (a0 > AlphaRef) if (a0 > AlphaRef)
{ {
color_to_fix(r1, g1, b1, dst[i]); color_to_fix(r1, g1, b1, dst[i]);
@ -11,14 +11,20 @@ if (a0 > AlphaRef)
r0 = r1 + imulFix(a0, r0 - r1); r0 = r1 + imulFix(a0, r0 - r1);
g0 = g1 + imulFix(a0, g0 - g1); g0 = g1 + imulFix(a0, g0 - g1);
b0 = b1 + imulFix(a0, b0 - b1); b0 = b1 + imulFix(a0, b0 - b1);
dst[i] = fix_to_sample(r0, g0, b0); dst[i] = fix_to_sample_nearest(FIX_POINT_COLOR_MAX,r0, g0, b0);
} }
#else #else // IPOL_A0
vec4_to_fix(r0, g0, b0, line.c[0][0], inversew); #ifdef IPOL_C1
dst[i] = fix_to_sample(r0, g0, b0); vec4_to_fix(r1, g1, b1, line.c[1][0], inversew);
#endif #endif // IPOL_C1
dst[i] = fix_to_sample_nearest(a0,r0, g0, b0);
#endif // IPOL_A0
#else // IPOL_C0
#ifdef burning_shader_colormask
fragment_draw_count += 1;
#else #else
dst[i] = PrimitiveColor; dst[i] = PrimitiveColor;
#endif #endif
#endif

@ -27,6 +27,7 @@ private:
void fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha(); void fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha();
void fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha(); void fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha();
void fragment_depth_less_equal_no_depth_write_colormask_none();
tFragmentShader fragmentShader; tFragmentShader fragmentShader;
@ -67,7 +68,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define burning_shader_fragment fragment_nodepth_noperspective_blend_one_zero #define burning_shader_fragment fragment_nodepth_noperspective_blend_one_zero
#define SUBTEXEL #define SUBTEXEL
#define IPOL_C0 #define IPOL_C0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"
@ -78,7 +79,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define INVERSE_W #define INVERSE_W
#define IPOL_W #define IPOL_W
#define IPOL_C0 #define IPOL_C0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"
@ -91,7 +92,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define IPOL_C0 #define IPOL_C0
#define USE_ZBUFFER #define USE_ZBUFFER
#define CMP_W #define CMP_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"
@ -105,7 +106,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define USE_ZBUFFER #define USE_ZBUFFER
#define CMP_W #define CMP_W
#define WRITE_W #define WRITE_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"
@ -117,7 +118,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define SUBTEXEL #define SUBTEXEL
#define IPOL_C0 #define IPOL_C0
#define IPOL_A0 #define IPOL_A0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"
@ -129,7 +130,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define IPOL_W #define IPOL_W
#define IPOL_C0 #define IPOL_C0
#define IPOL_A0 #define IPOL_A0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"
@ -143,7 +144,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define IPOL_A0 #define IPOL_A0
#define USE_ZBUFFER #define USE_ZBUFFER
#define CMP_W #define CMP_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"
@ -158,7 +159,18 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define USE_ZBUFFER #define USE_ZBUFFER
#define CMP_W #define CMP_W
#define WRITE_W #define WRITE_W
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX #define INVERSE_W_RANGE FIX_POINT_COLOR_MAX_CENTER
#include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag
#include "burning_shader_compile_fragment_end.h"
//occlusion query
#include "burning_shader_compile_start.h"
#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_colormask_none
#define IPOL_W
#define USE_ZBUFFER
#define CMP_W
#define burning_shader_colormask
#include "burning_shader_compile_fragment_start.h" #include "burning_shader_compile_fragment_start.h"
#include burning_shader_frag #include burning_shader_frag
#include "burning_shader_compile_fragment_end.h" #include "burning_shader_compile_fragment_end.h"

@ -7,7 +7,10 @@
line.w[0] += slopeW; line.w[0] += slopeW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0][0] += slopeC; line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0]; line.t[0][0] += slopeT[0];

@ -25,7 +25,7 @@ void burning_shader_class::burning_shader_fragment()
fp24 slopeW; fp24 slopeW;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
sVec4 slopeC; sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES]; sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
@ -49,7 +49,10 @@ void burning_shader_class::burning_shader_fragment()
slopeW = (line.w[1] - line.w[0]) * invDeltaX; slopeW = (line.w[1] - line.w[0]) * invDeltaX;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX; slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX; slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@ -67,7 +70,10 @@ void burning_shader_class::burning_shader_fragment()
line.w[0] += slopeW * subPixel; line.w[0] += slopeW * subPixel;
#endif #endif
#ifdef IPOL_C0 #ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel; line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif #endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel; line.t[0][0] += slopeT[0] * subPixel;
@ -84,15 +90,20 @@ void burning_shader_class::burning_shader_fragment()
z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart; z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif #endif
#ifdef burning_shader_colormask
#else
f32 inversew = INVERSE_W_RANGE; f32 inversew = INVERSE_W_RANGE;
#endif
#ifdef IPOL_C0 #ifdef IPOL_C0
tFixPoint r0, g0, b0; tFixPoint a0,r0, g0, b0;
#endif
#ifdef IPOL_C1
tFixPoint r2, g2, b2;
#endif #endif
#ifdef IPOL_A0 #ifdef IPOL_A0
tFixPoint a0;
tFixPoint r1, g1, b1; tFixPoint r1, g1, b1;
#endif #endif

@ -13,6 +13,7 @@
#undef IPOL_C0 #undef IPOL_C0
#undef IPOL_A0 #undef IPOL_A0
#undef IPOL_C1
#undef IPOL_T0 #undef IPOL_T0
#undef IPOL_T1 #undef IPOL_T1
#undef IPOL_T2 #undef IPOL_T2
@ -22,3 +23,4 @@
#undef ipol_test #undef ipol_test
#undef INVERSE_W_RANGE #undef INVERSE_W_RANGE
#undef burning_shader_colormask

@ -28,7 +28,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
temp[2] = b->Pos.x - a->Pos.x; temp[2] = b->Pos.x - a->Pos.x;
temp[3] = ba; temp[3] = ba;
scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) > 0.f ? 0 : 1; scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) < 0.f ? 1 : 0;
scan.right = 1 - scan.left; scan.right = 1 - scan.left;
// calculate slopes for the major edge // calculate slopes for the major edge
@ -50,6 +50,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.c[0][0] = a->Color[0]; scan.c[0][0] = a->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0]; scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0]; scan.t[0][0] = a->Tex[0];
@ -91,6 +96,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.c[0][1] = a->Color[0]; scan.c[0][1] = a->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1]; scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0]; scan.t[0][1] = a->Tex[0];
@ -102,8 +112,8 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left(a->Pos.y); yStart = fill_convention_top(a->Pos.y);
yEnd = fill_convention_right(b->Pos.y); yEnd = fill_convention_down(b->Pos.y);
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ((f32)yStart) - a->Pos.y; subPixel = ((f32)yStart) - a->Pos.y;
@ -127,6 +137,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.c[0][1] += scan.slopeC[0][1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -162,6 +177,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
line.c[0][scan.right] = scan.c[0][1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1]; line.t[0][scan.right] = scan.t[0][1];
@ -173,7 +193,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
(this->*fragmentShader) (); (this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break; if (EdgeTestPass & edge_test_first_line) break;
@ -195,6 +215,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.c[0][1] += scan.slopeC[0][1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1]; scan.t[0][1] += scan.slopeT[0][1];
@ -225,6 +250,9 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#ifdef IPOL_C0 #ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0]; scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0]; scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif #endif
@ -252,6 +280,10 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2]; scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];
scan.c[0][1] = b->Color[0]; scan.c[0][1] = b->Color[0];
#endif #endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2]; scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
@ -264,8 +296,8 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// apply top-left fill convention, top part // apply top-left fill convention, top part
yStart = fill_convention_left(b->Pos.y); yStart = fill_convention_top(b->Pos.y);
yEnd = fill_convention_right(c->Pos.y); yEnd = fill_convention_down(c->Pos.y);
#ifdef SUBTEXEL #ifdef SUBTEXEL
subPixel = ((f32)yStart) - b->Pos.y; subPixel = ((f32)yStart) - b->Pos.y;
@ -289,6 +321,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.c[0][1] += scan.slopeC[0][1] * subPixel; scan.c[0][1] += scan.slopeC[0][1] * subPixel;
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel; scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel; scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -324,6 +361,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
line.c[0][scan.right] = scan.c[0][1]; line.c[0][scan.right] = scan.c[0][1];
#endif #endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0]; line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1]; line.t[0][scan.right] = scan.t[0][1];
@ -335,7 +377,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif #endif
// render a scanline // render a scanline
interlace_scanline if_interlace_scanline
(this->*fragmentShader) (); (this->*fragmentShader) ();
if (EdgeTestPass & edge_test_first_line) break; if (EdgeTestPass & edge_test_first_line) break;
@ -357,6 +399,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.c[0][1] += scan.slopeC[0][1]; scan.c[0][1] += scan.slopeC[0][1];
#endif #endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0 #ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0]; scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1]; scan.t[0][1] += scan.slopeT[0][1];

@ -173,7 +173,8 @@ bool testExactPlacement(video::E_DRIVER_TYPE driverType)
video::IImage* img = driver->createImage(renderTargetTex, core::vector2di(), renderTargetTex->getSize()); video::IImage* img = driver->createImage(renderTargetTex, core::vector2di(), renderTargetTex->getSize());
driver->writeImageToFile(img, "results/fireball.png"); driver->writeImageToFile(img, "results/fireball.png");
img->drop(); img->drop();
bool result = fuzzyCompareImages(driver, "media/fireball.png", "results/fireball.png")>98.25f; bool result = fuzzyCompareImages(driver,
driverType == video::EDT_BURNINGSVIDEO ? "media/Burning's Video-fireball.png":"media/fireball.png", "results/fireball.png")>98.25f;
device->closeDevice(); device->closeDevice();
device->run(); device->run();

@ -72,8 +72,11 @@ bool testWithDriver(video::E_DRIVER_TYPE driverType)
} }
// TODO: mode is buggy, but required for skybox. So driver supports it, but would core dump here. // TODO: mode is buggy, but required for skybox. So driver supports it, but would core dump here.
//burning v0.53 works
#if 0
if (driverType==video::EDT_BURNINGSVIDEO && Type==scene::EPT_TRIANGLE_FAN) if (driverType==video::EDT_BURNINGSVIDEO && Type==scene::EPT_TRIANGLE_FAN)
continue; continue;
#endif
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer.Material);
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix); driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
driver->drawVertexPrimitiveList(Buffer.getVertices(), driver->drawVertexPrimitiveList(Buffer.getVertices(),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 359 B

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 740 B

After

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 7.3 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: 40 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 814 B

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 814 B

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Some files were not shown because too many files have changed in this diff Show More