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";
}
break;
case video::EDT_BURNINGSVIDEO:
UseHighLevelShaders = true;
psFileName = mediaPath + "opengl.frag";
vsFileName = mediaPath + "opengl.vert";
break;
default:
break;
}

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

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

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.25420.1
# Visual Studio Version 16
VisualStudioVersion = 16.0.32413.511
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "01.HelloWorld", "01.HelloWorld\HelloWorld_vc14.vcxproj", "{5AD4C95C-BA38-4692-BA4B-8C25A86208F9}"
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}"
EndProject
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
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
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -1096,4 +1102,7 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2722D524-E069-40BF-B51A-2BD81342E7D7}
EndGlobalSection
EndGlobal

@ -70,7 +70,7 @@ bool CMainMenu::run()
gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1);
box->addItem(L"OpenGL 1.5");
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");
switch (driverType )
{

@ -1473,7 +1473,7 @@ static s32 StretchBlit(eBlitter operation,
// Methods for Software drivers
//! 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,
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
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)
{
AbsRectangle clip;

@ -40,7 +40,7 @@ CDepthBuffer::~CDepthBuffer()
//! clears the zbuffer
void CDepthBuffer::clear(f32 value, interlaced_control interlaced)
void CDepthBuffer::clear(f32 value, const interlaced_control interlaced)
{
ieee754 zMaxValue;
@ -69,7 +69,7 @@ void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
size_t TotalSize = Pitch * size.Height;
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;
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();
s32 fx = core::ceil32( sourceXStep );
s32 fy = core::ceil32( sourceYStep );
const s32 fx = core::ceil32( sourceXStep );
const s32 fy = core::ceil32( sourceYStep );
f32 sx;
f32 sy;
@ -403,14 +403,15 @@ void CImage::flip(bool topBottom, bool leftRight)
}
//! 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))
{
os::Printer::log("IImage::getPixelBox method doesn't work with compressed images.", ELL_WARNING);
return SColor(0);
}
*/
SColor c;
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 );
r = core::s32_clamp( ( r >> sdiv ) + bias, 0, 255 );
g = core::s32_clamp( ( g >> sdiv ) + bias, 0, 255 );
b = core::s32_clamp( ( b >> sdiv ) + bias, 0, 255 );
a = core::s32_clamp( ( a / sdiv ) + bias, 0, 255 );
r = core::s32_clamp( ( r / sdiv ) + bias, 0, 255 );
g = core::s32_clamp( ( g / sdiv ) + bias, 0, 255 );
b = core::s32_clamp( ( b / sdiv ) + bias, 0, 255 );
c.set( a, r, g, b );
return c;

@ -62,7 +62,7 @@ public:
virtual void fill(const SColor &color) IRR_OVERRIDE;
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

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

File diff suppressed because it is too large Load Diff

@ -34,6 +34,22 @@ namespace video
//! Create render target.
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
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) IRR_OVERRIDE;
@ -253,7 +269,8 @@ namespace video
bool resetAllRenderstates) IRR_OVERRIDE;
//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.
virtual s32 getVertexShaderConstantID(const c8* name) IRR_OVERRIDE;
@ -328,6 +345,9 @@ namespace video
IBurningShader* CurrentShader;
IBurningShader* BurningShader[ETR2_COUNT];
PushShaderData PushShader;
void pushShader(scene::E_PRIMITIVE_TYPE pType, int testCurrent);
IDepthBuffer* DepthBuffer;
IStencilBuffer* StencilBuffer;
@ -341,9 +361,9 @@ namespace video
enum E_TRANSFORMATION_STATE_BURNING_VIDEO
{
ETS_VIEW_PROJECTION = ETS_COUNT,
ETS_PROJ_MODEL_VIEW,
ETS_MODEL_VIEW_PROJ,
ETS_MODEL_VIEW,
ETS_NORMAL, //3x3 ModelView Tansposed Inverse
ETS_NORMAL, //3x3 ModelView Transposed Inverse
ETS_COUNT_BURNING = 16
};
@ -354,12 +374,18 @@ namespace video
{
ETF_VALID = 1,
ETF_IDENTITY = 2,
ETF_TEXGEN_CAMERA_SPHERE = 4,
ETF_TEXGEN_CAMERA_REFLECTION = 8,
ETF_TEXGEN_WRAP = 16,
ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP
ETF_TEXGEN_MATRIX = 4, // or !ETF_IDENTITY
ETF_TEXGEN_CAMERA_SPHERE = 8,
ETF_TEXGEN_CAMERA_REFLECTION = 16,
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];
size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG
@ -375,34 +401,33 @@ namespace video
AbsRectangle Scissor;
// Vertex Cache
SVertexCache VertexCache;
SVertexShader VertexShader;
int VertexCache_reset (const void* vertices, u32 vertexCount,
const void* indices, u32 indexCount,
E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,
E_INDEX_TYPE iType);
void VertexCache_get (s4DVertexPair* face[4] );
//void VertexCache_get (s4DVertexPair* face[4] );
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
//size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane );
//size_t inline clipToFrustumTest ( const s4DVertex * v ) const;
public:
size_t clipToFrustum( const size_t vIn /*, const size_t clipmask_for_face*/ );
void VertexCache_fill(const u32 sourceIndex, const u32 destIndex);
u32 clipToFrustum( const u32 vIn /*, const size_t clipmask_for_face*/ );
protected:
// holds transformed, clipped vertices for a triangle. triangle expands on clipping
// Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected)
SAligned4DVertex Clipper;
SAligned4DVertex Clipper_temp;
SAligned4DVertex Clipper_disjoint; // __restrict helper
#ifdef SOFTWARE_DRIVER_2_LIGHTING
void lightVertex_eye ( s4DVertex *dest, u32 vertexargb );
void lightVertex_eye ( s4DVertex *dest, const u32 vertexargb );
#endif
//! Sets the fog mode.
@ -410,22 +435,29 @@ namespace video
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..
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;
void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) 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;
//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;
SBurningShaderMaterial Material;
static const sVec4 NDCPlane[6+2];
//static const sVec4 NDCPlane[6+2];
//! Built-in 2D quad for 2D rendering.
S3DVertex Quad2DVertices[4];
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)
core::array<IRenderTarget*> RenderTargets;

@ -12,16 +12,15 @@
#include "CBlit.h"
#include "os.h"
namespace irr
{
namespace video
{
burning_namespace_start
//! 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);
//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;
if (allowNonPowerOfTwo)
@ -29,7 +28,17 @@ static inline core::dimension2d<u32> getOptimalSize(const core::dimension2d<u32>
w = original.Width;
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;
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;
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 && h > maxSize) h = maxSize;
return core::dimension2d<u32>(w, h);
}
//Helper pointer (do not store per texture)
const IImage* CSoftwareTexture2::original_mip0 = 0;
//! constructor
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)
, ETT_2D
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
: ITexture(name),Type(ETT_2D)
#else
: ITexture(name, ETT_2D)
#endif
)
, MipMapLOD(0), Flags(flags), Driver(driver)
{
#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;
IsRenderTarget = (Flags & IS_RENDERTARGET) != 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;
if (!image) return;
if (!image)
{
calcDerivative();
return;
}
OriginalSize = image->getDimension();
OriginalColorFormat = image->getColorFormat();
@ -78,14 +104,21 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
#if defined(IRRLICHT_sRGB)
if (Flags & IMAGE_IS_LINEAR) image->set_sRGB(0);
#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 ||
name.find("bump") >= 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;
}
#endif
bool isCompressed = IImage::isCompressedFormat(OriginalColorFormat);
@ -103,16 +136,12 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
maxTexSize = 0;
}
#endif
/*
core::dimension2d<u32> optSize(OriginalSize.getOptimalSize(
(Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo
false, // requireSquare
(Flags & ALLOW_NPOT) ? 1 : maxTexSize == SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, // larger
(Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue
)
);
*/
core::dimension2d<u32> optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize));
//thread-local storage if needed
original_mip0 = 0;
const interlaced_control& interlaced = Driver->getInterlace();
core::dimension2d<u32> optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize, interlaced));
if (OriginalSize == optSize)
{
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 );
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
//OriginalSize = optSize;
}
// Show Information about resizing
if (OriginalSize != optSize ||
( OriginalColorFormat != ColorFormat &&
if ((OriginalSize != optSize && interlaced.tex_scalex == 0) ||
(OriginalColorFormat != ColorFormat &&
!((OriginalColorFormat == ECF_R8G8B8 || OriginalColorFormat == ECF_A1R5G5B5) && ColorFormat == ECF_A8R8G8B8)
)
)
)
{
char buf[256];
core::stringw showName(name);
@ -157,6 +187,7 @@ CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 fl
//select highest mipmap 0
regenerateMipMapLevels(image->getMipMapsData());
original_mip0 = 0;
}
@ -198,6 +229,8 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* 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
for (i = 1; i < array_size(MipMap); ++i)
{
@ -214,7 +247,7 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
#endif
//MipMap[i]->fill ( 0xFFFF4040 );
//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)
@ -235,9 +268,6 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
i += 1;
} while ((origSize.Width != 1 || origSize.Height != 1) && i < array_size(MipMap));
//TODO: this is not true
LodBIAS = i * 2.f;
origSize = OriginalSize;
for (i = 1; i < array_size(MipMap) && mip_current < mip_end; ++i)
{
@ -279,10 +309,11 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
#if 0
//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[] = {
0xFFFF0000,
0xFFFFFFFF,
0xFFFF0000,0xFF00FF00,0xFF0000FF,
0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,
0xFFff6600,0xFF00ff66,0xFF6600FF,
@ -296,14 +327,16 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
int border = 0;
const core::dimension2du& d = MipMap[i]->getDimension();
core::rect<s32> p(0, 0, d.Width, d.Height);
SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);
SColor c((color[i & 15] & 0x00FFFFFF) | 0x7F000000);
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);
}
}
#endif
#if 1
//save mipmap chain
if (0)
{
@ -318,14 +351,20 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data)
//if (name[i] == '.') ext = i;
i += 1;
}
for (i = 0; i < array_size(MipMap); ++i)
if (original_mip0)
{
if (MipMap[i])
{
snprintf_irr(buf, sizeof(buf), "mip/%s_%02d.png", name + filename, (s32)i);
Driver->writeImageToFile(MipMap[i], buf);
}
snprintf_irr(buf, sizeof(buf), "mip/%s_org.png", name + filename);
Driver->writeImageToFile((IImage*)original_mip0, 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
calcDerivative();
@ -337,39 +376,48 @@ void CSoftwareTexture2::calcDerivative()
MipMapLOD = 0;
if (MipMap[0])
{
const core::dimension2du& dim = MipMap[0]->getDimension();
MipMap0_Area[0] = dim.Width;
MipMap0_Area[1] = dim.Height; // screensize of a triangle
//TA: try to mimic openGL mipmap. ( don't do this!)
//if (MipMap0_Area[0] < 32) MipMap0_Area[0] = 32;
//if (MipMap0_Area[1] < 32) MipMap0_Area[1] = 32;
Size = dim; // MipMap[MipMapLOD]->getDimension();
Size = MipMap[MipMapLOD]->getDimension();
Pitch = MipMap[MipMapLOD]->getPitch();
}
//preCalc mipmap texel center boundaries
for (size_t i = 0; i < array_size(MipMap); ++i)
{
CSoftwareTexture2_Bound& b = TexBound[i];
if (MipMap[i])
{
const core::dimension2du& dim = MipMap[i]->getDimension();
//f32 u = 1.f / dim.Width;
//f32 v = 1.f / dim.Height;
b.w = dim.Width - 1.f;
b.h = dim.Height - 1.f;
b.cx = 0.f; //u*0.005f;
b.cy = 0.f; //v*0.005f;
core::dimension2du dim(0, 0);
if (MipMap[i] && MipMap[i]->getData()) dim = MipMap[i]->getDimension();
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
{
b.w = 0.f;
b.h = 0.f;
b.cx = 0.f;
b.cy = 0.f;
#if 0
const f32 nu = 0.5f / dim.Width;
const f32 nv = 0.5f / dim.Height;
//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)
#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
, IRenderTarget(0)
, IRenderTarget(0), DepthStencil(0)
#endif
{
DriverType = EDT_BURNINGSVIDEO;
@ -393,9 +441,13 @@ CSoftwareRenderTarget2::~CSoftwareRenderTarget2()
{
if (Textures[0])
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))
{
@ -421,8 +473,41 @@ void CSoftwareRenderTarget2::setTextures(ITexture* const * textures, u32 numText
if (!textureDetected)
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] = {
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.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) {
if (x <= 0.f) return 0;
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;
for (int i = 128; i != 0; i >>= 1) {
if (table[y + i] <= x)
@ -505,24 +607,28 @@ int linear_to_srgb_8bit(const float x) {
else
return y + 1;
}
*/
#endif
u32 linear_to_srgb_8bit(const float v)
{
if (v <= 0.f) return 0;
else if (v >= 1.f) return 255;
ieee754 c;
c.f = v;
const size_t x = c.u;
const u32* table = (u32*)srgb_8bit_to_linear_float;
const u32 x = c.u;
const u32* table = (const u32*)srgb_8bit_to_linear_float;
u32 y = 0;
y += table[y + 128] <= x ? 128 : 0;
y += table[y + 64] <= x ? 64 : 0;
y += table[y + 32] <= x ? 32 : 0;
y += table[y + 16] <= x ? 16 : 0;
y += table[y + 8] <= x ? 8 : 0;
y += table[y + 4] <= x ? 4 : 0;
y += table[y + 2] <= x ? 2 : 0;
y += table[y + 1] <= x ? 1 : 0;
y |= table[y | 128] <= x ? 128 : 0;
y |= table[y | 64] <= x ? 64 : 0;
y |= table[y | 32] <= x ? 32 : 0;
y |= table[y | 16] <= x ? 16 : 0;
y |= table[y | 8] <= x ? 8 : 0;
y |= table[y | 4] <= x ? 4 : 0;
y |= table[y | 2] <= x ? 2 : 0;
y |= table[y | 1] <= x ? 1 : 0;
if (srgb_8bit_to_linear_float[y + 1] - x < v - srgb_8bit_to_linear_float[y])
y += 1;
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 src_sRGB = src->get_sRGB();
#else
//assuming sRGB as default
const int dst_sRGB = (flags & CSoftwareTexture2::TEXTURE_IS_LINEAR) ? 0 : 1;
const int src_sRGB = (flags & CSoftwareTexture2::IMAGE_IS_LINEAR) ? 0 : 1;
#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];
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];
ft sum[4];
u32 sbgra = 0;
float f[4];
ft f[4];
int fi[4];
f[3] = (float)sc.y0;
f[3] = (ft)sc.y0;
for (int dy = dc.y0; dy < dc.y1; ++dy)
{
f[1] = f[3];
f[3] = sc.y0 + (dy + 1 - dc.y0) * scale[1];
if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough
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)
{
f[0] = f[2];
f[2] = sc.x0 + (dx + 1 - dc.x0) * scale[0];
if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;
if (f[2] >= sc.x1) f[2] = sc.x1 - (ft)0.001;
//accumulate linear color
sum[0] = 0.f;
sum[1] = 0.f;
sum[2] = 0.f;
sum[3] = 0.f;
sum[0] = (ft)0;
sum[1] = (ft)0;
sum[2] = (ft)0;
sum[3] = (ft)0;
//sample border
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[3] = (int)(f[3]);
float w[2];
ft w[2];
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[3]) w[1] -= fy + 1 - f[3];
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[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)
{
@ -675,17 +787,25 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
}
if (dst_sRGB)
{
sbgra = linear_to_srgb_8bit(sum[0]) |
linear_to_srgb_8bit(sum[1]) << 8 |
linear_to_srgb_8bit(sum[2]) << 16 |
sbgra = linear_to_srgb_8bit((float)sum[0]) |
linear_to_srgb_8bit((float)sum[1]) << 8 |
linear_to_srgb_8bit((float)sum[2]) << 16 |
(u32)(sum[3]) << 24;
}
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]) |
(u32)(sum[1]) << 8 |
(u32)(sum[2]) << 16 |
(u32)(sum[3]) << 24;
*/
}
switch (dstFormat)
{
@ -704,10 +824,9 @@ void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>
}
}
}
#undef ft
}
} // end namespace video
} // end namespace irr
burning_namespace_end
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

@ -27,12 +27,25 @@ class CBurningVideoDriver;
*/
struct CSoftwareTexture2_Bound
{
f32 w; // width - 0.5f;
f32 h; // height- 0.5f;
f32 cx; // texelcenter x 1.f/width*0.5f
f32 cy; // texelcenter y 1.f/height*0.5f
//[0.5 / width, 1 - 0.5 / width]
//int dim[2];
f32 mat[4];
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
{
public:
@ -57,7 +70,8 @@ public:
if ( newLevel < 0 ) newLevel = 0;
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;
}
@ -83,20 +97,6 @@ public:
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)
virtual CImage* getImage() const
@ -115,6 +115,10 @@ public:
{
return TexBound[MipMapLOD];
}
const CSoftwareTexture2_Bound* getTexBound_index() const
{
return TexBound;
}
#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)
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)
const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; };
const core::dimension2d<u32>& getSize() const { return Size; };
E_DRIVER_TYPE getDriverType() const { return DriverType; };
ECOLOR_FORMAT getColorFormat() const { return ColorFormat; };
ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; };
const core::dimension2d<u32>& getOriginalSize() const { return OriginalSize; }
const core::dimension2d<u32>& getSize() const { return Size; }
E_DRIVER_TYPE getDriverType() const { return DriverType; }
ECOLOR_FORMAT getColorFormat() const { return ColorFormat; }
ECOLOR_FORMAT getOriginalColorFormat() const { return OriginalColorFormat; }
u32 getPitch() const { return Pitch; };
bool hasMipMaps() const { return HasMipMaps; }
bool isRenderTarget() const { return IsRenderTarget; }
E_TEXTURE_TYPE getType() const { return Type; }
core::dimension2d<u32> OriginalSize;
core::dimension2d<u32> Size;
E_DRIVER_TYPE DriverType;
@ -141,6 +147,7 @@ public:
u32 Pitch;
bool HasMipMaps;
bool IsRenderTarget;
E_TEXTURE_TYPE Type;
#endif
private:
@ -153,8 +160,10 @@ private:
CImage* MipMap[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)
E_DRIVER_TYPE DriverType;
core::array<ITexture*> Texture;
core::array<ITexture*> Textures;
ITexture* DepthStencil;
#endif
protected:

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

@ -216,7 +216,7 @@ void CTRGouraudAlpha2::fragmentShader()
{
#ifdef IPOL_C0
#ifdef INVERSE_W
inversew = reciprocal_zero_no ( line.w[0] );
inversew = reciprocal_zero( line.w[0] );
#endif
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 );
b2 = b1 + imulFix ( a0, b0 - b1 );
dst[i] = fix4_to_sample( a0,r2, g2, b2 );
dst[i] = fix_to_sample( r2, g2, b2 );
#else
dst[i] = PrimitiveColor;
#endif
@ -285,7 +285,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
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.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) < 0.f ? 1 : 0;
scan.right = 1 - scan.left;
// calculate slopes for the major edge
@ -359,8 +359,8 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -428,7 +428,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif
// render a scanline
interlace_scanline fragmentShader();
if_interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -518,8 +518,8 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
@ -587,7 +587,7 @@ void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s
#endif
// render a scanline
interlace_scanline fragmentShader();
if_interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0];
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[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;
// calculate slopes for the major edge
@ -359,8 +359,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -428,7 +428,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif
// render a scanline
interlace_scanline fragmentShader();
if_interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -518,8 +518,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL
@ -588,7 +588,7 @@ void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, cons
#endif
// render a scanline
interlace_scanline fragmentShader();
if_interlace_scanline fragmentShader();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -636,7 +636,7 @@ namespace video
//! creates a flat triangle renderer
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)
{
//ETR_GOURAUD_ALPHA_NOZ - draw2DRectangle Gradient
// ETR_GOURAUD_ALPHA_NOZ - draw2DRectangle Gradient
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTRGouraudAlphaNoZ2(driver);
#else

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

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

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

@ -125,7 +125,7 @@ void CTRTextureBlend::OnSetMaterial(const SBurningShaderMaterial& material)
int showname = 0;
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_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[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;
// calculate slopes for the major edge
@ -2274,8 +2274,8 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -2343,7 +2343,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif
// render a scanline
interlace_scanline (this->*fragmentShader) ();
if_interlace_scanline (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];
@ -2433,8 +2433,8 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
@ -2502,7 +2502,7 @@ void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4
#endif
// render a scanline
interlace_scanline (this->*fragmentShader) ();
if_interlace_scanline (this->*fragmentShader) ();
scan.x[0] += scan.slopeX[0];
scan.x[1] += scan.slopeX[1];

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

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

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

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

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

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

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

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

@ -68,11 +68,7 @@
#endif
namespace irr
{
namespace video
{
burning_namespace_start
class CTRTextureLightMap2_M4 : public IBurningShader
{
@ -84,19 +80,14 @@ public:
//! 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;
private:
#if defined(SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)
void drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );
void drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );
void scanline_bilinear2_mag ();
void scanline_bilinear2_min ();
#else
#define scanline_bilinear2_mag fragmentShader
#endif
// fragment shader
typedef void (CTRTextureLightMap2_M4::* tFragmentShader) ();
void fragment_linear_mag();
void fragment_nearest_min();
void fragmentShader();
tFragmentShader fragmentShader;
};
@ -107,11 +98,13 @@ CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(CBurningVideoDriver* driver)
#ifdef _DEBUG
setDebugName("CTRTextureLightMap2_M4");
#endif
fragmentShader = &CTRTextureLightMap2_M4::fragment_linear_mag;
}
/*!
*/
void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
void CTRTextureLightMap2_M4::fragment_linear_mag()
{
tVideoSample *dst;
fp24 *z;
@ -138,11 +131,17 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
dst = (tVideoSample*)RenderTarget->getData() + i;
// subTexel
#ifdef SUBTEXEL
const f32 subPixel = ( (f32) xStart ) - line.x[0];
#endif
#ifdef IPOL_W
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;
@ -161,7 +160,11 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
line.w[1] = b;
#else
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;
@ -180,8 +183,11 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
line.z[1] = b;
#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[1][1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;
@ -221,7 +227,6 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
#endif
#ifdef BURNINGVIDEO_RENDERER_FAST
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::scanline_bilinear2_min ()
void CTRTextureLightMap2_M4::fragment_nearest_min()
{
tVideoSample *dst;
fp24 *z;
@ -352,7 +356,6 @@ void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
f32 inversew = FIX_POINT_F32_MUL;
#endif
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) );
@ -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
{
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
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);
@ -392,6 +394,7 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = fill_step_y( ba );
@ -401,14 +404,16 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
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[1] = ca;
temp[2] = a->Pos.x - b->Pos.x;
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;
// calculate slopes for the major edge
@ -481,8 +486,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
yStart = fill_convention_top( a->Pos.y );
yEnd = fill_convention_down( b->Pos.y );
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
@ -518,6 +523,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines
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
// 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[1] += scan.slopeX[1];
@ -590,23 +599,23 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
// advance to middle point
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
scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];
scan.z[0] = a->Pos.z + scan.slopeZ[0] * dy;
#endif
#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
#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
#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
#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
}
@ -641,8 +650,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
yStart = fill_convention_top( b->Pos.y );
yEnd = fill_convention_down( c->Pos.y );
#ifdef SUBTEXEL
@ -679,6 +688,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restric
#endif
line.x_edgetest = fill_convention_edge(scan.slopeX[scan.left]);
// rasterize the edge scanlines
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
// 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[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)
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
burning_namespace_end
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
burning_namespace_start
//! creates a flat triangle renderer
@ -1147,8 +778,4 @@ IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* d
}
} // end namespace video
} // end namespace irr
burning_namespace_end

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

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

@ -21,6 +21,8 @@
#undef INVERSE_W
#undef IPOL_C0
#undef IPOL_C1
#undef IPOL_C1_FOG
#undef IPOL_T0
#undef IPOL_T1
@ -34,45 +36,47 @@
#define WRITE_W
#define IPOL_C0
#define IPOL_C1
#define IPOL_T0
#define IPOL_T1
// apply global override
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef INVERSE_W
#undef INVERSE_W
#endif
#ifndef SOFTWARE_DRIVER_2_SUBTEXEL
#undef SUBTEXEL
#undef SUBTEXEL
#endif
#if BURNING_MATERIAL_MAX_COLORS < 1
#undef IPOL_C0
#undef IPOL_C0
#endif
#if BURNING_MATERIAL_MAX_COLORS < 2
#undef IPOL_C1
#endif
#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
#undef IPOL_W
#endif
#define IPOL_Z
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef CMP_W
#undef CMP_W
#define CMP_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#ifdef WRITE_W
#undef WRITE_W
#define WRITE_Z
#endif
#endif
namespace irr
{
namespace video
{
burning_namespace_start
class CTR_transparent_reflection_2_layer : public IBurningShader
{
@ -94,11 +98,11 @@ private:
//! constructor
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");
#endif
#endif
}
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()
{
tVideoSample *dst;
tVideoSample* dst;
#ifdef USE_ZBUFFER
fp24 *z;
fp24* z;
#endif
s32 xStart;
@ -133,23 +137,23 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
fp24 slopeW;
#endif
#ifdef IPOL_C0
sVec4 slopeC;
sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];
#endif
#ifdef IPOL_T0
sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];
#endif
// apply top-left fill-convention, left
xStart = fill_convention_left( line.x[0] );
xEnd = fill_convention_right( line.x[1] );
xStart = fill_convention_left(line.x[0]);
xEnd = fill_convention_right(line.x[1]);
dx = xEnd - xStart;
if ( dx < 0 )
if (dx < 0)
return;
// 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
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;
#endif
#ifdef IPOL_C0
slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;
slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;
#endif
#ifdef IPOL_C1
slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;
#endif
#ifdef IPOL_T0
slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;
@ -168,7 +175,7 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
#endif
#ifdef SUBTEXEL
subPixel = ( (f32) xStart ) - line.x[0];
subPixel = ((f32)xStart) - line.x[0];
#ifdef IPOL_Z
line.z[0] += slopeZ * subPixel;
#endif
@ -176,7 +183,10 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
line.w[0] += slopeW * subPixel;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC * subPixel;
line.c[0][0] += slopeC[0] * subPixel;
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1] * subPixel;
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0] * subPixel;
@ -187,10 +197,10 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
#endif
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
z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;
z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;
#endif
@ -203,152 +213,197 @@ void CTR_transparent_reflection_2_layer::fragmentShader()
tFixPoint a1;
#endif
switch(MaterialType) {
#ifdef IPOL_C1_FOG
tFixPoint aFog = FIX_POINT_ONE;
#endif
switch (MaterialType) {
default:
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
if (line.z[0] < z[i])
if (line.z[0] < z[i])
#endif
#ifdef CMP_W
if (line.w[0] >= z[i])
if (line.w[0] >= z[i])
#endif
{
{
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
inversew = fix_inverse32(line.w[0]);
#endif
getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
#ifdef IPOL_C1_FOG
//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);
g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1);
getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
r0 = imulFix_tex1(r0, r1);
g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1);
#ifdef IPOL_C0
vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0);
vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0);
#endif
dst[i] = fix_to_sample(r0, g0, b0);
#ifdef 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
z[i] = line.z[0];
z[i] = line.z[0];
#endif
#ifdef WRITE_W
z[i] = line.w[0];
z[i] = line.w[0];
#endif
}
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
line.t[1][0] += slopeT[1];
#endif
}
break;
}
break;
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
if (line.z[0] < z[i])
if (line.z[0] < z[i])
#endif
#ifdef CMP_W
if (line.w[0] >= z[i])
if (line.w[0] >= z[i])
#endif
{
{
#ifdef INVERSE_W
inversew = fix_inverse32(line.w[0]);
inversew = fix_inverse32(line.w[0]);
#endif
getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));
getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));
r0 = imulFix_tex1(r0, r1);
g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1);
r0 = imulFix_tex1(r0, r1);
g0 = imulFix_tex1(g0, g1);
b0 = imulFix_tex1(b0, b1);
#ifdef IPOL_C0
vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0);
vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew);
r0 = imulFix_simple(r1, r0);
g0 = imulFix_simple(g1, g0);
b0 = imulFix_simple(b1, b0);
//vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER
if (a1 + 2 < FIX_POINT_ONE)
{
color_to_fix(r1, g1, b1, dst[i]);
r0 = r1 + imulFix(a1, r0 - r1);
g0 = g1 + imulFix(a1, g0 - g1);
b0 = b1 + imulFix(a1, b0 - b1);
}
//vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER
if (a1 + 2 < FIX_POINT_ONE)
{
color_to_fix(r1, g1, b1, dst[i]);
r0 = r1 + imulFix(a1, r0 - r1);
g0 = g1 + imulFix(a1, g0 - g1);
b0 = b1 + imulFix(a1, b0 - b1);
}
#endif
dst[i] = fix_to_sample(r0, g0, b0);
dst[i] = fix_to_sample(r0, g0, b0);
#ifdef WRITE_Z
//z[i] = line.z[0];
//z[i] = line.z[0];
#endif
#ifdef WRITE_W
//z[i] = line.w[0];
#endif
}
}
#ifdef IPOL_Z
line.z[0] += slopeZ;
line.z[0] += slopeZ;
#endif
#ifdef IPOL_W
line.w[0] += slopeW;
line.w[0] += slopeW;
#endif
#ifdef IPOL_C0
line.c[0][0] += slopeC;
line.c[0][0] += slopeC[0];
#endif
#ifdef IPOL_C1
line.c[1][0] += slopeC[1];
#endif
#ifdef IPOL_T0
line.t[0][0] += slopeT[0];
line.t[0][0] += slopeT[0];
#endif
#ifdef IPOL_T1
line.t[1][0] += slopeT[1];
line.t[1][0] += slopeT[1];
#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
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);
if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
if (F32_A_GREATER_B(b->Pos.y, c->Pos.y)) swapVertexPointer(&b, &c);
if (F32_A_GREATER_B(a->Pos.y, b->Pos.y)) swapVertexPointer(&a, &b);
const f32 ca = c->Pos.y - a->Pos.y;
const f32 ba = b->Pos.y - a->Pos.y;
const f32 cb = c->Pos.y - b->Pos.y;
// calculate delta y of the edges
scan.invDeltaY[0] = fill_step_y( ca );
scan.invDeltaY[1] = fill_step_y( ba );
scan.invDeltaY[2] = fill_step_y( cb );
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] ) )
if (F32_LOWER_EQUAL_0(scan.invDeltaY[0]))
return;
// 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[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;
// 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];
#endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@ -400,7 +460,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif
// rasterize upper sub-triangle
if ( F32_GREATER_0(scan.invDeltaY[1]) )
if (F32_GREATER_0(scan.invDeltaY[1]))
{
// calculate slopes for top edge
scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];
@ -421,6 +481,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@ -432,11 +497,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( a->Pos.y );
yEnd = fill_convention_right( b->Pos.y );
yStart = fill_convention_top(a->Pos.y);
yEnd = fill_convention_down(b->Pos.y);
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - a->Pos.y;
subPixel = ((f32)yStart) - a->Pos.y;
// correct to pixel center
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;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -470,7 +540,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif
// 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.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];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -501,8 +576,8 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif
// render a scanline
interlace_scanline
fragmentShader();
if_interlace_scanline
fragmentShader();
scan.x[0] += scan.slopeX[0];
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];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -536,10 +616,10 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
}
// rasterize lower sub-triangle
if ( F32_GREATER_0(scan.invDeltaY[2]) )
if (F32_GREATER_0(scan.invDeltaY[2]))
{
// 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
@ -553,6 +633,9 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@ -581,6 +664,11 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
scan.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
scan.t[0][1] = b->Tex[0];
@ -592,12 +680,12 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left( b->Pos.y );
yEnd = fill_convention_right( c->Pos.y );
yStart = fill_convention_top(b->Pos.y);
yEnd = fill_convention_down(c->Pos.y);
#ifdef SUBTEXEL
subPixel = ( (f32) yStart ) - b->Pos.y;
subPixel = ((f32)yStart) - b->Pos.y;
// correct to pixel center
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;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -631,7 +724,7 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif
// 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.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];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -662,8 +760,8 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
#endif
// render a scanline
interlace_scanline
fragmentShader();
if_interlace_scanline
fragmentShader();
scan.x[0] += scan.slopeX[0];
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];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -699,33 +802,27 @@ void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning
}
} // end namespace video
} // end namespace irr
burning_namespace_end
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
namespace irr
{
namespace video
{
burning_namespace_start
//! creates a flat triangle renderer
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
*/
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_
return new CTR_transparent_reflection_2_layer(driver);
#else
#else
return 0;
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_
}
} // end namespace video
} // end namespace irr
burning_namespace_end

@ -10,10 +10,7 @@
#include "CSoftwareDriver2.h"
#include "IShaderConstantSetCallBack.h"
namespace irr
{
namespace video
{
burning_namespace_start
const tFixPointu IBurningShader::dithermask[] =
{
@ -30,7 +27,7 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
#endif
#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);
IRR_DEBUG_BREAK_IF(1);
@ -42,7 +39,6 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
Interlaced.nr = 0;
EdgeTestPass = edge_test_pass;
EdgeTestPass_stack = edge_test_pass;
for (u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i)
{
@ -69,6 +65,8 @@ void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)
RenderPass_ShaderIsTransparent = 0;
PrimitiveColor = COLOR_BRIGHT_WHITE;
TL_Flag = 0;
fragment_draw_count = 0;
VertexShaderProgram_buildin = BVT_Fix;
}
IBurningShader::IBurningShader(CBurningVideoDriver* driver)
@ -103,8 +101,66 @@ IBurningShader::IBurningShader(
if (CallBack)
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
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)
RenderTarget->drop();
RenderTarget = (video::CImage*) surface;
RenderTarget = (video::CImage*)surface;
if (RenderTarget)
{
@ -156,7 +212,9 @@ void IBurningShader::setTextureParam(const size_t stage, video::CSoftwareTexture
sInternalTexture* it = &IT[stage];
if (it->Texture)
{
it->Texture->drop();
}
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)
{
drawPoint(a);
@ -234,7 +295,7 @@ void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& l
bool resetAllRenderstates, IMaterialRendererServices* services)
{
if (Driver)
Driver->setFallback_Material(BaseMaterial);
Driver->setFallback_Material(BaseMaterial, VertexShaderProgram_buildin);
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
if (CallBack)
CallBack->OnSetMaterial(material);
@ -243,6 +304,7 @@ void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& l
void IBurningShader::OnUnsetMaterial()
{
//restore previous state
}
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);
}
#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)
{
if (!name || !name[0])
@ -405,6 +520,27 @@ void IBurningShader::setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpf
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()
{
@ -412,7 +548,6 @@ IVideoDriver* IBurningShader::getVideoDriver()
}
} // end namespace video
} // end namespace irr
burning_namespace_end
#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_

@ -8,7 +8,6 @@
#include "SoftwareDriver2_compile_config.h"
#include "IReferenceCounted.h"
#include "irrMath.h"
#include "irrMathFastCompat.h"
#include "IImage.h"
#include "S2DVertex.h"
#include "rect.h"
@ -22,421 +21,467 @@
#include "IMaterialRendererServices.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
sVec4 pos4; //light position Model*View (Identity*View)
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
fog_scale = 0.f;
TL_Flag = TL_LIGHT_LOCAL_VIEWER;
}
void deleteAllDynamicLights()
{
//ENABLED = 0x01,
TL_SCISSOR = 0x02,
TL_LIGHT = 0x04,
TL_SPECULAR = 0x08,
TL_FOG = 0x10,
TL_NORMALIZE_NORMALS = 0x20,
TL_TEXTURE_TRANSFORM = 0x40,
TL_LIGHT_LOCAL_VIEWER = 0x80,
TL_LIGHT0_IS_NORMAL_MAP = 0x100 //sVec4 Light Vector is used as normal or specular
};
Light.set_used(0);
TL_Flag &= ~(TL_LIGHT | TL_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() {}
virtual ~SBurningShaderEyeSpace() {}
void reset ()
{
Light.set_used ( 0 );
Global_AmbientLight.set ( 0.f );
return tiny_istoken(name, other.name);
}
TL_Flag = TL_LIGHT_LOCAL_VIEWER;
}
void resetFog()
{
fog_scale = 0.f;
//cam_distance = 0.f;
}
};
core::array<SBurningShaderLight> Light;
sVec3Color Global_AmbientLight;
class IBurningShader;
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)
//sVec4 cam_world_pos; //Camera Position in world Space
//sVec4 vertex4; //eye coordinate position of vertex
sVec4 normal; //transformed normal
sVec4 vertex; //eye coordinate position of vertex projected
class CBurningVideoDriver;
class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices
{
public:
//! Constructor
IBurningShader(CBurningVideoDriver* driver);
//derivative of vertex
//f32 cam_distance; // vertex.length();
sVec4 cam_dir; //vertex.normalize();
//! 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);
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,
CULL_BACK = 2,
CULL_INVISIBLE = 4, //primitive smaller than a pixel (AreaMinDrawSize)
CULL_FRONT_AND_BACK = 8,
};
EdgeTestPass = pointCloud ? edge_test_point : wireFrame ? edge_test_left : edge_test_pass;
}
enum eBurningStencilOp
{
StencilOp_KEEP = 0x1E00,
StencilOp_INCR = 0x1E02,
StencilOp_DECR = 0x1E03
};
void pushShader(PushShaderData* data, int save);
virtual bool canWireFrame() { return false; }
virtual bool canPointCloud() { return false; }
struct SBurningShaderMaterial
{
SMaterial org;
SMaterial lastMaterial;
bool resetRenderStates;
void setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass);
E_MATERIAL_TYPE Fallback_MaterialType;
//IMaterialRenderer
SMaterial mat2D;
//SMaterial save3D;
virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,
bool resetAllRenderstates, IMaterialRendererServices* services) IRR_OVERRIDE;
size_t CullFlag; //eCullFlag
u32 depth_write;
u32 depth_test;
virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) IRR_OVERRIDE;
sVec3Color AmbientColor;
sVec3Color DiffuseColor;
sVec3Color SpecularColor;
sVec3Color EmissiveColor;
virtual void OnUnsetMaterial() IRR_OVERRIDE;
};
//! Returns if the material is transparent.
virtual bool isTransparent() const IRR_OVERRIDE;
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,
//! Access the callback provided by the users when creating shader materials
virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const IRR_OVERRIDE;
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
{
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;
// 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)
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
}
virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
}
virtual bool setVertexShaderConstant(const c8* name, const f32* floats, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), floats, count);
}
virtual bool setVertexShaderConstant(const c8* name, const bool* bools, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setVertexShaderConstant(const c8* name, const s32* ints, int count)
{
return setVertexShaderConstant(getVertexShaderConstantID(name), ints, count);
}
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
}
virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
}
virtual bool setPixelShaderConstant(const c8* name, const f32* floats, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), floats, count);
}
virtual bool setPixelShaderConstant(const c8* name, const bool* bools, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), (const s32*)bools, count);
}
virtual bool setPixelShaderConstant(const c8* name, const s32* ints, int count)
{
return setPixelShaderConstant(getPixelShaderConstantID(name), ints, count);
}
#endif
//used if no color interpolation is defined
void setPrimitiveColor(const video::SColor& color)
{
PrimitiveColor = color_to_sample(color);
}
void setTLFlag(size_t in /*eTransformLightFlags*/)
{
TL_Flag = in;
}
void setFog(SColor color_fog)
{
fog_color_sample = color_to_sample(color_fog);
color_to_fix(fog_color, fog_color_sample);
}
void setScissor(const AbsRectangle& scissor)
{
Scissor = scissor;
}
//used if no color interpolation is defined
void setPrimitiveColor(const video::SColor& color)
{
PrimitiveColor = color_to_sample(color);
}
void setTLFlag(size_t in /*eTransformLightFlags*/)
{
TL_Flag = in;
}
void setFog(SColor color_fog)
{
fog_color_sample = color_to_sample(color_fog);
color_to_fix(fog_color, fog_color_sample);
}
void setScissor(const AbsRectangle& 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;
IShaderConstantSetCallBack* CallBack;
E_MATERIAL_TYPE BaseMaterial;
s32 UserData;
protected:
//friend class CBurningVideoDriver;
core::array<BurningUniform> UniformInfo;
s32 getShaderConstantID(EBurningUniformFlags program, const c8* name);
bool setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count);
void constructor_IBurningShader(CBurningVideoDriver* driver);
video::CImage* RenderTarget;
CDepthBuffer* DepthBuffer;
CStencilBuffer* Stencil;
tVideoSample ColorMask;
CBurningVideoDriver* Driver;
IShaderConstantSetCallBack* CallBack;
E_MATERIAL_TYPE BaseMaterial;
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
size_t EdgeTestPass; //edge_test_flag
size_t EdgeTestPass_stack;
interlaced_control Interlaced; // passed from driver
sInternalTexture IT[BURNING_MATERIAL_MAX_TEXTURES];
eBurningStencilOp stencilOp[4];
tFixPoint AlphaRef;
int RenderPass_ShaderIsTransparent;
static const tFixPointu dithermask[4 * 4];
sScanConvertData ALIGN(16) scan;
sScanLineData line;
tVideoSample PrimitiveColor; //used if no color interpolation is defined
//draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham
size_t EdgeTestPass; //edge_test_flag
interlaced_control Interlaced; // passed from driver
size_t /*eTransformLightFlags*/ TL_Flag;
tFixPoint fog_color[4];
tVideoSample fog_color_sample;
eBurningStencilOp stencilOp[4];
tFixPoint AlphaRef;
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
{
//RenderTarget->getColorFormat()
size_t /*eTransformLightFlags*/ TL_Flag;
tFixPoint fog_color[4];
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
return color.color;
return color.color;
#else
return color.toA1R5G5B5();
return color.toA1R5G5B5();
#endif
}
}
};
};
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGTextureLightMap2_M4(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureLightMap2_Add(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureDetailMap2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlat2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRFlat2(CBurningVideoDriver* driver);
IBurningShader* createTRFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);
IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlat2(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTextureFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRFlat2(CBurningVideoDriver* driver);
IBurningShader* createTRFlatWire2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);
IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver);
IBurningShader* createTRTextureInverseAlphaBlend(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver);
IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);
IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver);
IBurningShader* createTRTextureInverseAlphaBlend(CBurningVideoDriver* driver);
IBurningShader* createTRNormalMap(CBurningVideoDriver* driver);
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);
IBurningShader* createTRNormalMap(CBurningVideoDriver* driver);
IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver);
IBurningShader* createTriangleRendererReference(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
} // end namespace irr
burning_namespace_end
#endif

@ -9,26 +9,28 @@
#include "SoftwareDriver2_helper.h"
#include "irrAllocator.h"
#include "EPrimitiveTypes.h"
#include "SVertexIndex.h"
namespace irr
{
burning_namespace_start
namespace video
{
struct sVec4;
//! sVec2 used in BurningShader texture coordinates
struct sVec2
{
f32 x;
f32 y;
union
{
struct { f32 x, y; };
struct { f32 s, t; } st;
};
sVec2 () {}
sVec2() {}
sVec2 ( f32 s) : x ( s ), y ( s ) {}
sVec2 ( f32 _x, f32 _y )
: x ( _x ), y ( _y ) {}
sVec2(f32 s) : x(s), y(s) {}
sVec2(f32 _x, f32 _y)
: x(_x), y(_y) {}
void set ( f32 _x, f32 _y )
void set(f32 _x, f32 _y)
{
x = _x;
y = _y;
@ -37,8 +39,8 @@ struct sVec2
// f = a * t + b * ( 1 - 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 ));
y = (f32)(b.y + ( ( a.y - b.y ) * t ));
x = (f32)(b.x + ((a.x - b.x) * t));
y = (f32)(b.y + ((a.y - b.y) * t));
}
sVec2 operator-(const sVec2& other) const
@ -59,10 +61,10 @@ struct sVec2
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;
y *= s;
@ -74,11 +76,29 @@ struct sVec2
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"
//! sVec2Pack is Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents Texutre Coordinates.
//! sVec2Pack is Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents Texture Coordinates.
// Start address is not 4 byte aligned
struct sVec2Pack
{
@ -137,35 +157,36 @@ struct sVec3Pack
#include "irrunpack.h"
//! sVec4 used in Driver,BurningShader, direction/color
struct sVec4
struct ALIGN(16) sVec4
{
union
{
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 ( f32 _x, f32 _y, f32 _z, f32 _w )
: x ( _x ), y ( _y ), z( _z ), w ( _w ){}
sVec4() {}
sVec4(f32 _x, f32 _y, f32 _z, f32 _w)
: x(_x), y(_y), z(_z), w(_w) {}
// 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 ));
y = (f32)(b.y + ( ( a.y - b.y ) * t ));
z = (f32)(b.z + ( ( a.z - b.z ) * t ));
w = (f32)(b.w + ( ( a.w - b.w ) * t ));
x = (f32)(b.x + ((a.x - b.x) * t));
y = (f32)(b.y + ((a.y - b.y) * t));
z = (f32)(b.z + ((a.z - b.z) * t));
w = (f32)(b.w + ((a.w - b.w) * t));
}
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
{
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)
@ -178,15 +199,15 @@ struct sVec4
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;
y *= other.y;
@ -194,12 +215,13 @@ struct sVec4
w *= other.w;
}
void operator=(const sVec4& other)
sVec4& operator=(const sVec4& other)
{
x = other.x;
y = other.y;
z = other.z;
w = other.w;
return *this;
}
//outside shader
@ -210,13 +232,7 @@ struct sVec4
z = _z;
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
{
@ -230,7 +246,7 @@ struct sVec4
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)
@ -249,12 +265,41 @@ struct sVec4
{
//const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z);
f32 l = x * x + y * y + z * z;
l = l > 0.0000001f ? 1.f / sqrtf(l) : 1.f;
x *= l;
y *= l;
z *= l;
if (l > 0.00000001f)
{
l = 1.f / sqrtf(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
sVec4(const sVec3Pack& other)
@ -271,20 +316,36 @@ struct sVec4
f32 l = x * x + y * y + z * z;
l = l > 0.0000001f ? len / sqrtf(l) : 0.f;
out.x = (x*l) + ofs;
out.y = (y*l) + ofs;
out.z = (z*l) + ofs;
out.x = (x * l) + ofs;
out.y = (y * 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
typedef sVec4 sVec3Pack_unpack;
//operator f32* () { return &x; }
//!sVec4 is argb. sVec3Color is rgba
struct sVec3Color
{
f32 r, g, b,a;
void clampf01()
{
if (x < 0.f) x = 0.f; else if (x > 1.f) x = 1.f;
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)
{
@ -294,15 +355,101 @@ struct sVec3Color
a = s;
}
void setA8R8G8B8(const u32 argb)
void setColorf(const video::SColorf& color)
{
r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);
g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);
b = ((argb & 0x000000FF) ) * (1.f / 255.f);
a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);
r = color.r;
g = color.g;
b = color.b;
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;
g = color.g;
@ -332,7 +479,7 @@ struct sVec3Color
}
//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.r = r <= 1.f ? r : 1.f;
@ -340,7 +487,7 @@ struct sVec3Color
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;
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;
}
void sat_xyz(sVec4 &dest, const sVec3Color& v1) const
void sat_xyz(sVec4& dest, const sVec3Color& v1) const
{
f32 v;
dest.a = 1.f;
@ -357,46 +504,47 @@ struct sVec3Color
v = b * v1.b; dest.b = v < 1.f ? v : 1.f;
}
};
#endif
//internal BurningShaderFlag for a Vertex
enum e4DVertexFlag
{
VERTEX4D_CLIPMASK = 0x0000003F,
VERTEX4D_CLIP_NEAR = 0x00000001,
VERTEX4D_CLIP_FAR = 0x00000002,
VERTEX4D_CLIP_LEFT = 0x00000004,
VERTEX4D_CLIP_RIGHT = 0x00000008,
VERTEX4D_CLIP_BOTTOM = 0x00000010,
VERTEX4D_CLIP_TOP = 0x00000020,
VERTEX4D_INSIDE = 0x0000003F,
VERTEX4D_CLIPMASK = 0x0000003F,
VERTEX4D_CLIP_NEAR = 0x00000001,
VERTEX4D_CLIP_FAR = 0x00000002,
VERTEX4D_CLIP_LEFT = 0x00000004,
VERTEX4D_CLIP_RIGHT = 0x00000008,
VERTEX4D_CLIP_BOTTOM = 0x00000010,
VERTEX4D_CLIP_TOP = 0x00000020,
VERTEX4D_INSIDE = 0x0000003F,
VERTEX4D_PROJECTED = 0x00000100,
VERTEX4D_VAL_ZERO = 0x00000200,
VERTEX4D_VAL_ONE = 0x00000400,
VERTEX4D_PROJECTED = 0x00000100,
//VERTEX4D_VAL_ZERO = 0x00000200,
//VERTEX4D_VAL_ONE = 0x00000400,
VERTEX4D_FORMAT_MASK = 0xFFFF0000,
VERTEX4D_FORMAT_MASK = 0xFFFF0000,
VERTEX4D_FORMAT_MASK_TEXTURE = 0x000F0000,
VERTEX4D_FORMAT_TEXTURE_1 = 0x00010000,
VERTEX4D_FORMAT_TEXTURE_2 = 0x00020000,
VERTEX4D_FORMAT_TEXTURE_3 = 0x00030000,
VERTEX4D_FORMAT_TEXTURE_4 = 0x00040000,
VERTEX4D_FORMAT_MASK_TEXTURE = 0x000F0000,
VERTEX4D_FORMAT_TEXTURE_1 = 0x00010000,
VERTEX4D_FORMAT_TEXTURE_2 = 0x00020000,
VERTEX4D_FORMAT_TEXTURE_3 = 0x00030000,
VERTEX4D_FORMAT_TEXTURE_4 = 0x00040000,
VERTEX4D_FORMAT_MASK_COLOR = 0x00F00000,
VERTEX4D_FORMAT_COLOR_1 = 0x00100000,
VERTEX4D_FORMAT_COLOR_2_FOG = 0x00200000,
VERTEX4D_FORMAT_COLOR_3 = 0x00300000,
VERTEX4D_FORMAT_COLOR_4 = 0x00400000,
VERTEX4D_FORMAT_MASK_COLOR = 0x00F00000,
VERTEX4D_FORMAT_COLOR_1 = 0x00100000,
VERTEX4D_FORMAT_COLOR_2_FOG = 0x00200000,
VERTEX4D_FORMAT_COLOR_3 = 0x00300000,
VERTEX4D_FORMAT_COLOR_4 = 0x00400000,
VERTEX4D_FORMAT_MASK_LIGHT = 0x0F000000,
VERTEX4D_FORMAT_LIGHT_1 = 0x01000000,
VERTEX4D_FORMAT_LIGHT_2 = 0x02000000,
VERTEX4D_FORMAT_MASK_LIGHT = 0x0F000000,
VERTEX4D_FORMAT_LIGHT_1 = 0x01000000,
VERTEX4D_FORMAT_LIGHT_2 = 0x02000000,
VERTEX4D_FORMAT_MASK_TANGENT = 0xF0000000,
VERTEX4D_FORMAT_BUMP_DOT3 = 0x10000000,
VERTEX4D_FORMAT_SPECULAR = 0x20000000,
VERTEX4D_FORMAT_MASK_TANGENT = 0xF0000000,
VERTEX4D_FORMAT_BUMP_DOT3 = 0x10000000,
VERTEX4D_FORMAT_SPECULAR = 0x20000000,
};
@ -418,28 +566,28 @@ enum e4DIndexType
{
E4IT_16BIT = 1, // EIT_16BIT,
E4IT_32BIT = 2, // EIT_32BIT,
E4IT_NONE = 4, //
E4IT_NONE = 4, //
};
#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL
#define BURNING_MATERIAL_MAX_TEXTURES 4
#define BURNING_MATERIAL_MAX_COLORS 4
#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
#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_COLORS 4
#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
//ensure handcrafted sizeof(s4DVertex)
#define sizeof_s4DVertex 128
//ensure handcrafted sizeof(s4DVertex)
#define sizeof_s4DVertex 128
#else
#define BURNING_MATERIAL_MAX_TEXTURES 2
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define BURNING_MATERIAL_MAX_COLORS 1
#else
#define BURNING_MATERIAL_MAX_COLORS 0
#endif
#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
#define BURNING_MATERIAL_MAX_TEXTURES 2
#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
#define BURNING_MATERIAL_MAX_COLORS 1
#else
#define BURNING_MATERIAL_MAX_COLORS 0
#endif
#define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1
//ensure handcrafted sizeof(s4DVertex)
#define sizeof_s4DVertex 64
//ensure handcrafted sizeof(s4DVertex)
#define sizeof_s4DVertex 64
#endif
// dummy Vertex. used for calculation vertex memory size
@ -467,10 +615,10 @@ struct s4DVertex
{
sVec4 Pos;
#if BURNING_MATERIAL_MAX_TEXTURES > 0
sVec2 Tex[ BURNING_MATERIAL_MAX_TEXTURES ];
sVec2 Tex[BURNING_MATERIAL_MAX_TEXTURES];
#endif
#if BURNING_MATERIAL_MAX_COLORS > 0
sVec4 Color[ BURNING_MATERIAL_MAX_COLORS ];
sVec4 Color[BURNING_MATERIAL_MAX_COLORS];
#endif
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
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
u8 __align [sizeof_s4DVertex - sizeof (s4DVertex_proxy) ];
u8 __align[sizeof_s4DVertex - sizeof(s4DVertex_proxy)];
#endif
// 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
Tex[0].interpolate(a.Tex[0], b.Tex[0], t);
Tex[1].interpolate(a.Tex[1], b.Tex[1], t);
@ -499,45 +647,103 @@ struct s4DVertex
#if BURNING_MATERIAL_MAX_TEXTURES > 0
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
#if BURNING_MATERIAL_MAX_COLORS > 0
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
#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0
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
}
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 ---------------------------
// 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;
#define sizeof_s4DVertexPairRel 2
#define s4DVertex_ofs(index) ((index)*sizeof_s4DVertexPairRel)
#define s4DVertex_proj(index) ((index)*sizeof_s4DVertexPairRel) + 1
#define s4DVertex_ofs(index) ((index)*sizeof_s4DVertexPairRel)
#define s4DVertex_pro(index) (((index)*sizeof_s4DVertexPairRel) + 1)
struct SAligned4DVertex
{
SAligned4DVertex()
:data(0),ElementSize(0),mem(0) {}
:data(0), ElementSize(0), mem(0) {}
virtual ~SAligned4DVertex ()
virtual ~SAligned4DVertex()
{
if (mem)
{
@ -581,17 +787,17 @@ static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const vo
u64* burning_restrict dst64 = (u64*)dst;
const u64* burning_restrict src64 = (const u64*)src;
dst64[0] = src64[0];
dst64[1] = src64[1];
dst64[2] = src64[2];
dst64[3] = src64[3];
dst64[4] = src64[4];
dst64[5] = src64[5];
dst64[6] = src64[6];
dst64[7] = src64[7];
dst64[0] = src64[0];
dst64[1] = src64[1];
dst64[2] = src64[2];
dst64[3] = src64[3];
dst64[4] = src64[4];
dst64[5] = src64[5];
dst64[6] = src64[6];
dst64[7] = src64[7];
dst64[8] = src64[8];
dst64[9] = src64[9];
dst64[8] = src64[8];
dst64[9] = src64[9];
dst64[10] = src64[10];
dst64[11] = src64[11];
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;
const u64* burning_restrict src64 = (const u64*)src;
dst64[0] = src64[0];
dst64[1] = src64[1];
dst64[2] = src64[2];
dst64[3] = src64[3];
dst64[4] = src64[4];
dst64[5] = src64[5];
dst64[6] = src64[6];
dst64[7] = src64[7];
dst64[0] = src64[0];
dst64[1] = src64[1];
dst64[2] = src64[2];
dst64[3] = src64[3];
dst64[4] = src64[4];
dst64[5] = src64[5];
dst64[6] = src64[6];
dst64[7] = src64[7];
dst64[8] = src64[8];
dst64[9] = src64[9];
dst64[8] = src64[8];
dst64[9] = src64[9];
dst64[10] = src64[10];
dst64[11] = src64[11];
dst64[12] = src64[12];
@ -656,13 +862,13 @@ static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const vo
*dst32++ = *src32++;
len -= 32;
}
/*
while (len >= 4)
{
*dst32++ = *src32++;
len -= 4;
}
*/
/*
while (len >= 4)
{
*dst32++ = *src32++;
len -= 4;
}
*/
#endif
}
@ -670,14 +876,14 @@ static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const vo
//! hold info for different Vertex Types
struct SVSize
{
size_t Format; // e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE
size_t Pitch; // sizeof Vertex
size_t TexSize; // amount Textures
size_t TexCooSize; // sizeof TextureCoordinates
u32 Format; // e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE
u32 Pitch; // sizeof Vertex
u32 TexSize; // amount Textures
u32 TexCooSize; // sizeof TextureCoordinates
};
// a cache info
// index cache info
struct SCacheInfo
{
u32 index;
@ -687,18 +893,14 @@ struct SCacheInfo
//must at least hold all possible (clipped) vertices of primitive.
#define VERTEXCACHE_ELEMENT 16
#define VERTEXCACHE_MISS 0xFFFFFFFF
struct SVertexCache
struct SVertexShader
{
SVertexCache () {}
~SVertexCache() {}
SVertexShader() {}
~SVertexShader() {}
//VertexType
SVSize vSize[E4VT_COUNT];
SCacheInfo info[VERTEXCACHE_ELEMENT];
SCacheInfo info_temp[VERTEXCACHE_ELEMENT];
// Transformed and lite, clipping state
// + Clipped, Projected
SAligned4DVertex mem;
@ -714,12 +916,50 @@ struct SVertexCache
u32 indicesPitch;
// primitives consist of x vertices
size_t primitiveHasVertex;
u32 primitiveHasVertex;
u32 primitiveRun;
e4DVertexType vType; //E_VERTEX_TYPE
scene::E_PRIMITIVE_TYPE pType; //scene::E_PRIMITIVE_TYPE
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
struct sPixelShaderData
{
tVideoSample *dst;
fp24 *z;
tVideoSample* dst;
fp24* z;
s32 xStart;
s32 xEnd;
@ -816,7 +1056,7 @@ struct sPixelShaderData
/*
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);
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
*/
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);
r = tofix ( v.r, 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);
a = tofix(v.a, FIX_POINT_F32_MUL);
r = tofix(v.r, 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);
}
/*
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);
g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);
b = tofix ( v.b, 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);
b = tofix(v.b, COLOR_MAX * FIX_POINT_F32_MUL);
}
#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]
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);
g = tofix(v.g, 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);
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);
}
}
}
burning_namespace_end
#endif

@ -10,7 +10,7 @@
// Generic Render Flags for burning's video rasterizer
// 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
#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT
@ -18,19 +18,19 @@
#define SOFTWARE_DRIVER_2_BILINEAR
#define SOFTWARE_DRIVER_2_LIGHTING
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR
#define SOFTWARE_DRIVER_2_USE_WBUFFER
#define SOFTWARE_DRIVER_2_32BIT
#define SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A8R8G8B8
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 256
#define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE 0x100000
#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_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED
#define SOFTWARE_DRIVER_2_RENDERTARGET_SCALE
#endif
@ -49,10 +49,10 @@
#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 16
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 1
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_3D
#define SOFTWARE_DRIVER_2_INTERLACED
#define SOFTWARE_DRIVER_2_RENDERTARGET_SCALE
#endif
//! Set Flags for Windows Mobile
@ -70,7 +70,6 @@
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
//#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#endif
@ -88,7 +87,6 @@
#define SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 4
#define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE 8
#define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN
#define SOFTWARE_DRIVER_2_CLIPPING
#define SOFTWARE_DRIVER_2_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED
@ -104,13 +102,12 @@
#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR
//#define SOFTWARE_DRIVER_2_USE_WBUFFER
#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_RENDERTARGET_COLOR_FORMAT ECF_A1R5G5B5
//#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM
#define SOFTWARE_DRIVER_2_MIPMAPPING_MAX 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_2D_AS_2D
#define SOFTWARE_DRIVER_2_INTERLACED
@ -126,6 +123,7 @@
#endif
#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)
//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_mask ((1<<interlace_control_bit)-1)
struct interlaced_control
union interlaced_control
{
unsigned enable : 1;
unsigned bypass : 1;
unsigned nr : interlace_control_bit;
struct {
unsigned enable : 1;
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; };
static inline interlaced_control interlace_disabled()
static inline interlaced_control interlaced_disabled()
{
interlaced_control v;
v.raw = 0;
v.bypass = 1;
/*
v.enable = 0;
v.bypass = 1;
v.nr = 0;
v.target_scalex = 0;
v.target_scaley = 0;
v.tex_scalex = 0;
v.tex_scaley = 0;
*/
return v;
}
#if defined(SOFTWARE_DRIVER_2_INTERLACED)
#define interlace_scanline if ( Interlaced.bypass | ((line.y & interlace_control_mask) == Interlaced.nr) )
#define interlace_scanline_enabled if ( (line.y & interlace_control_mask) == Interlaced.nr )
//#define interlace_scanline if ( Interlaced.disabled | (((line.y >> (interlace_control_bit-1) ) & 1) == (Interlaced.nr & 1)) )
//#define interlace_scanline
#define interlace_scanline_active ((line.y & interlace_control_mask) == Interlaced.nr)
#define if_interlace_scanline_active if (interlace_scanline_active)
#define if_interlace_scanline if ( Interlaced.bypass || interlace_scanline_active )
#else
#define interlace_scanline
#define interlace_scanline_enabled
#define if_interlace_scanline_active
#define if_interlace_scanline
#endif
#define scissor_test_y if ((~TL_Flag & TL_SCISSOR) || ((line.y >= Scissor.y0) & (line.y <= Scissor.y1)))
#define scissor_test_x if ((~TL_Flag & TL_SCISSOR) || ((i+xStart >= Scissor.x0) & (i+xStart <= Scissor.x1)))
#define if_scissor_test_y if ((~TL_Flag & TL_SCISSOR) || ((line.y >= Scissor.y0) & (line.y <= Scissor.y1)))
#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_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_edge(x) (s32) floorf(fabsf(x)+0.f)
//#define fill_convention_left(x) 65536 - int(65536.0f - x)
#define fill_convention_edge(x) (s32) floorf(fabsf(x))
//fixpoint
//#define fill_convention_top_left(x) 65536 - int(65536.0f - x)
//#define fill_convention_right(x) 65535 - int(65536.0f - x)
//Check coordinates are in render target/window space
//Check that coordinates are in render target/window space
//#define SOFTWARE_DRIVER_2_DO_CLIPCHECK
#if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32)
#define SOFTWARE_DRIVER_2_CLIPCHECK if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()
@ -241,6 +267,7 @@ typedef float ipoltype;
#endif
#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)
#if (_MSC_VER > 1700 )
@ -249,29 +276,20 @@ typedef float ipoltype;
#define burning_restrict
#endif
/*
if (condition) state |= mask; else state &= ~mask;
*/
static inline void burning_setbit(size_t& state, int condition, size_t mask)
{
if (condition) state |= mask;
else state &= ~mask;
}
#if 0 && defined(_MSC_VER) && (_MSC_VER > 1500) && !defined(_DEBUG)
#pragma auto_inline(on)
#pragma inline_depth(255)
#pragma inline_recursion(on)
#endif
/*
if (condition) state |= m; else state &= ~m;
*/
REALINLINE void burning_setbit32(unsigned int& state, int condition, const unsigned int mask)
{
// 0, or any positive to mask
//s32 conmask = -condition >> 31;
state ^= ((-condition >> 31) ^ state) & mask;
}
#define burning_stringify(s) #s
#define burning_create_indirect(s) create_##s
#define burning_create(s) burning_create_indirect(s)
// 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)
#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_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:
RenderPass_ShaderIsTransparent = 1;
AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);
AlphaRef = tofix(material.org.MaterialTypeParam, FIX_POINT_COLOR_MAX);
break;
default:
RenderPass_ShaderIsTransparent = 0;
@ -53,7 +53,9 @@ void burning_shader_class::OnSetMaterial(const SBurningShaderMaterial& material)
{
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 /*if (material.org.ZBuffer == ECFN_DISABLED)*/

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

@ -27,6 +27,7 @@ private:
void fragment_nodepth_perspective_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;
@ -67,7 +68,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define burning_shader_fragment fragment_nodepth_noperspective_blend_one_zero
#define SUBTEXEL
#define IPOL_C0
#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX
#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"
@ -78,7 +79,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define INVERSE_W
#define IPOL_W
#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_frag
#include "burning_shader_compile_fragment_end.h"
@ -91,7 +92,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define IPOL_C0
#define USE_ZBUFFER
#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_frag
#include "burning_shader_compile_fragment_end.h"
@ -105,7 +106,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define USE_ZBUFFER
#define CMP_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"
@ -117,7 +118,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define SUBTEXEL
#define IPOL_C0
#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_frag
#include "burning_shader_compile_fragment_end.h"
@ -129,7 +130,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define IPOL_W
#define IPOL_C0
#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_frag
#include "burning_shader_compile_fragment_end.h"
@ -143,7 +144,7 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define IPOL_A0
#define USE_ZBUFFER
#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_frag
#include "burning_shader_compile_fragment_end.h"
@ -158,7 +159,18 @@ IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver
#define USE_ZBUFFER
#define CMP_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_frag
#include "burning_shader_compile_fragment_end.h"

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

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

@ -13,6 +13,7 @@
#undef IPOL_C0
#undef IPOL_A0
#undef IPOL_C1
#undef IPOL_T0
#undef IPOL_T1
#undef IPOL_T2
@ -22,3 +23,4 @@
#undef ipol_test
#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[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;
// 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];
#endif
#ifdef IPOL_C1
scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];
scan.c[1][0] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];
scan.t[0][0] = a->Tex[0];
@ -91,6 +96,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
scan.c[0][1] = a->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];
scan.c[1][1] = a->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];
scan.t[0][1] = a->Tex[0];
@ -102,8 +112,8 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left(a->Pos.y);
yEnd = fill_convention_right(b->Pos.y);
yStart = fill_convention_top(a->Pos.y);
yEnd = fill_convention_down(b->Pos.y);
#ifdef SUBTEXEL
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;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -162,6 +177,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -173,7 +193,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif
// render a scanline
interlace_scanline
if_interlace_scanline
(this->*fragmentShader) ();
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];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];
@ -225,6 +250,9 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#ifdef IPOL_C0
scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];
#endif
#ifdef IPOL_C1
scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];
#endif
#ifdef IPOL_T0
scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];
#endif
@ -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.c[0][1] = b->Color[0];
#endif
#ifdef IPOL_C1
scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];
scan.c[1][1] = b->Color[1];
#endif
#ifdef IPOL_T0
scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];
@ -264,8 +296,8 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif
// apply top-left fill convention, top part
yStart = fill_convention_left(b->Pos.y);
yEnd = fill_convention_right(c->Pos.y);
yStart = fill_convention_top(b->Pos.y);
yEnd = fill_convention_down(c->Pos.y);
#ifdef SUBTEXEL
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;
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0] * subPixel;
scan.c[1][1] += scan.slopeC[1][1] * subPixel;
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0] * subPixel;
scan.t[0][1] += scan.slopeT[0][1] * subPixel;
@ -324,6 +361,11 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
line.c[0][scan.right] = scan.c[0][1];
#endif
#ifdef IPOL_C1
line.c[1][scan.left] = scan.c[1][0];
line.c[1][scan.right] = scan.c[1][1];
#endif
#ifdef IPOL_T0
line.t[0][scan.left] = scan.t[0][0];
line.t[0][scan.right] = scan.t[0][1];
@ -335,7 +377,7 @@ void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, con
#endif
// render a scanline
interlace_scanline
if_interlace_scanline
(this->*fragmentShader) ();
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];
#endif
#ifdef IPOL_C1
scan.c[1][0] += scan.slopeC[1][0];
scan.c[1][1] += scan.slopeC[1][1];
#endif
#ifdef IPOL_T0
scan.t[0][0] += scan.slopeT[0][0];
scan.t[0][1] += scan.slopeT[0][1];

@ -173,7 +173,8 @@ bool testExactPlacement(video::E_DRIVER_TYPE driverType)
video::IImage* img = driver->createImage(renderTargetTex, core::vector2di(), renderTargetTex->getSize());
driver->writeImageToFile(img, "results/fireball.png");
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->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.
//burning v0.53 works
#if 0
if (driverType==video::EDT_BURNINGSVIDEO && Type==scene::EPT_TRIANGLE_FAN)
continue;
#endif
driver->setMaterial(Buffer.Material);
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
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