diff --git a/examples/10.Shaders/main.cpp b/examples/10.Shaders/main.cpp index d59145ac..2cc89b5d 100644 --- a/examples/10.Shaders/main.cpp +++ b/examples/10.Shaders/main.cpp @@ -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; } diff --git a/examples/23.SMeshHandling/main.cpp b/examples/23.SMeshHandling/main.cpp index a4ef9ebc..a7e2b433 100644 --- a/examples/23.SMeshHandling/main.cpp +++ b/examples/23.SMeshHandling/main.cpp @@ -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), diff --git a/examples/27.PostProcessing/main.cpp b/examples/27.PostProcessing/main.cpp index 2f49ccfc..ae4d6c48 100644 --- a/examples/27.PostProcessing/main.cpp +++ b/examples/27.PostProcessing/main.cpp @@ -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; diff --git a/examples/BuildAllExamples_vc14.sln b/examples/BuildAllExamples_vc14.sln index 4766c3b5..52bdb31e 100644 --- a/examples/BuildAllExamples_vc14.sln +++ b/examples/BuildAllExamples_vc14.sln @@ -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 diff --git a/examples/Demo/CMainMenu.cpp b/examples/Demo/CMainMenu.cpp index bb93e025..ab98d19b 100644 --- a/examples/Demo/CMainMenu.cpp +++ b/examples/Demo/CMainMenu.cpp @@ -70,7 +70,7 @@ bool CMainMenu::run() gui::IGUIListBox* box = guienv->addListBox(core::rect(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 ) { diff --git a/source/Irrlicht/CBlit.h b/source/Irrlicht/CBlit.h index c2fcf775..ee3b079a 100644 --- a/source/Irrlicht/CBlit.h +++ b/source/Irrlicht/CBlit.h @@ -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& rect, const video::SColor &color) +static inline void drawRectangle(video::IImage* img, const core::rect& 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& rect, const //! draws a line from to with color -static void drawLine(video::IImage* img, const core::position2d& from, +static inline void drawLine(video::IImage* img, const core::position2d& from, const core::position2d& to, const video::SColor &color) { AbsRectangle clip; diff --git a/source/Irrlicht/CDepthBuffer.cpp b/source/Irrlicht/CDepthBuffer.cpp index ec05bdab..6fe25cc2 100644 --- a/source/Irrlicht/CDepthBuffer.cpp +++ b/source/Irrlicht/CDepthBuffer.cpp @@ -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& 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& size) size_t TotalSize = Pitch * size.Height; Buffer = new u8[align_next(TotalSize,16)]; - clear(0, interlace_disabled()); + clear(0, interlaced_disabled()); } diff --git a/source/Irrlicht/CImage.cpp b/source/Irrlicht/CImage.cpp index 182623d0..c97f35f5 100644 --- a/source/Irrlicht/CImage.cpp +++ b/source/Irrlicht/CImage.cpp @@ -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; diff --git a/source/Irrlicht/CImage.h b/source/Irrlicht/CImage.h index 1f0ae700..edf3cd5b 100644 --- a/source/Irrlicht/CImage.h +++ b/source/Irrlicht/CImage.h @@ -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 diff --git a/source/Irrlicht/CSoftware2MaterialRenderer.h b/source/Irrlicht/CSoftware2MaterialRenderer.h index 3fa42acf..a346d664 100644 --- a/source/Irrlicht/CSoftware2MaterialRenderer.h +++ b/source/Irrlicht/CSoftware2MaterialRenderer.h @@ -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: diff --git a/source/Irrlicht/CSoftwareDriver2.cpp b/source/Irrlicht/CSoftwareDriver2.cpp index e6a9a036..253d0319 100644 --- a/source/Irrlicht/CSoftwareDriver2.cpp +++ b/source/Irrlicht/CSoftwareDriver2.cpp @@ -18,6 +18,51 @@ // Matrix now here +template +bool mat33_transposed_inverse(irr::core::CMatrix4& out, const irr::core::CMatrix4& M) +{ + const T* burning_restrict m = M.pointer(); + + double d = + (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) - + (m[0] * m[6] - m[2] * m[4]) * (m[9] * m[15] - m[11] * m[13]) + + (m[0] * m[7] - m[3] * m[4]) * (m[9] * m[14] - m[10] * m[13]) + + (m[1] * m[6] - m[2] * m[5]) * (m[8] * m[15] - m[11] * m[12]) - + (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) + + (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]); + + if (fabs(d) < DBL_MIN) + { + out.makeIdentity(); + return false; + } + + d = 1.0 / d; + T* burning_restrict o = out.pointer(); + o[0] = (T)(d * (m[5] * (m[10] * m[15] - m[11] * m[14]) + m[6] * (m[11] * m[13] - m[9] * m[15]) + m[7] * (m[9] * m[14] - m[10] * m[13]))); + o[4] = (T)(d * (m[9] * (m[2] * m[15] - m[3] * m[14]) + m[10] * (m[3] * m[13] - m[1] * m[15]) + m[11] * (m[1] * m[14] - m[2] * m[13]))); + o[8] = (T)(d * (m[13] * (m[2] * m[7] - m[3] * m[6]) + m[14] * (m[3] * m[5] - m[1] * m[7]) + m[15] * (m[1] * m[6] - m[2] * m[5]))); + o[12] = 0.f; + + o[1] = (T)(d * (m[6] * (m[8] * m[15] - m[11] * m[12]) + m[7] * (m[10] * m[12] - m[8] * m[14]) + m[4] * (m[11] * m[14] - m[10] * m[15]))); + o[5] = (T)(d * (m[10] * (m[0] * m[15] - m[3] * m[12]) + m[11] * (m[2] * m[12] - m[0] * m[14]) + m[8] * (m[3] * m[14] - m[2] * m[15]))); + o[9] = (T)(d * (m[14] * (m[0] * m[7] - m[3] * m[4]) + m[15] * (m[2] * m[4] - m[0] * m[6]) + m[12] * (m[3] * m[6] - m[2] * m[7]))); + o[13] = 0.f; + + o[2] = (T)(d * (m[7] * (m[8] * m[13] - m[9] * m[12]) + m[4] * (m[9] * m[15] - m[11] * m[13]) + m[5] * (m[11] * m[12] - m[8] * m[15]))); + o[6] = (T)(d * (m[11] * (m[0] * m[13] - m[1] * m[12]) + m[8] * (m[1] * m[15] - m[3] * m[13]) + m[9] * (m[3] * m[12] - m[0] * m[15]))); + o[10] = (T)(d * (m[15] * (m[0] * m[5] - m[1] * m[4]) + m[12] * (m[1] * m[7] - m[3] * m[5]) + m[13] * (m[3] * m[4] - m[0] * m[7]))); + o[14] = 0.f; + + o[3] = 0.f; + o[7] = 0.f; + o[11] = 0.f; + o[15] = 1.f; + + return true; +} + +#if 0 template bool mat44_transposed_inverse(irr::core::CMatrix4& out, const irr::core::CMatrix4& M) { @@ -61,13 +106,14 @@ bool mat44_transposed_inverse(irr::core::CMatrix4& out, const irr::core::CMat return true; } +#endif #if 0 // difference to CMatrix4::getInverse . higher precision in determinant. return identity on failure template -bool mat44_inverse(CMatrix4& out, const CMatrix4& M) +bool mat44_inverse(irr::core::CMatrix4& out, const irr::core::CMatrix4& M) { - const T* m = M.pointer(); + const T* burning_restrict m = M.pointer(); double d = (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) - @@ -84,7 +130,7 @@ bool mat44_inverse(CMatrix4& out, const CMatrix4& M) } d = 1.0 / d; - T* o = out.pointer(); + T* burning_restrict o = out.pointer(); o[0] = (T)(d * (m[5] * (m[10] * m[15] - m[11] * m[14]) + m[6] * (m[11] * m[13] - m[9] * m[15]) + m[7] * (m[9] * m[14] - m[10] * m[13]))); o[1] = (T)(d * (m[9] * (m[2] * m[15] - m[3] * m[14]) + m[10] * (m[3] * m[13] - m[1] * m[15]) + m[11] * (m[1] * m[14] - m[2] * m[13]))); o[2] = (T)(d * (m[13] * (m[2] * m[7] - m[3] * m[6]) + m[14] * (m[3] * m[5] - m[1] * m[7]) + m[15] * (m[1] * m[6] - m[2] * m[5]))); @@ -135,21 +181,122 @@ inline void transformVec3Vec4(const irr::core::CMatrix4& m, T* burning_restri #endif template -inline void rotateVec3Vec4(const irr::core::CMatrix4& m, T* burning_restrict out, const T* burning_restrict in) +inline void rotateMat44Vec3Vec4(const irr::core::CMatrix4& m, T* burning_restrict out, const T* burning_restrict in) { const T* burning_restrict M = m.pointer(); out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8]; out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9]; out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10]; - out[3] = 0.f; + out[3] = in[0] * M[3] + in[1] * M[7] + in[2] * M[11]; + //out[3] = 0.f; } +template +inline void rotateMat33Vec3Vec4(const irr::core::CMatrix4& m, T* burning_restrict out, const T* burning_restrict in) +{ + const T* burning_restrict M = m.pointer(); + + out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8]; + out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9]; + out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10]; + out[3] = 0.f; //in[0] * M[3] + in[1] * M[7] + in[2] * M[11]; +} + +#if 0 +template +irr::video::sVec4 operator* (const irr::core::CMatrix4& m, const irr::core::vector3df& in) +{ + const T* burning_restrict M = m.pointer(); + return irr::video::sVec4( + in.X * M[0] + in.Y * M[4] + in.Z * M[8] + M[12], + in.X * M[1] + in.Y * M[5] + in.Z * M[9] + M[13], + in.X * M[2] + in.Y * M[6] + in.Z * M[10] + M[14], + in.X * M[3] + in.Y * M[7] + in.Z * M[11] + M[15]); +} + +template +irr::video::sVec4 operator* (const irr::core::vector3df& in, const irr::core::CMatrix4& m) +{ + const T* burning_restrict M = m.pointer(); + return irr::video::sVec4( + in.X * M[0] + in.Y * M[1] + in.Z * M[2] + M[3], + in.X * M[4] + in.Y * M[5] + in.Z * M[6] + M[7], + in.X * M[8] + in.Y * M[9] + in.Z * M[10] + M[11], + in.X * M[12] + in.Y * M[13] + in.Z * M[14] + M[15]); +} +#endif + +template +irr::video::sVec4 operator* (const irr::core::CMatrix4& m, const irr::video::sVec4& v) +{ + const T* burning_restrict M = m.pointer(); + const float* burning_restrict in = &v.x; + return irr::video::sVec4( + in[0] * M[0] + in[1] * M[4] + in[2] * M[8] + in[3] * M[12], + in[0] * M[1] + in[1] * M[5] + in[2] * M[9] + in[3] * M[13], + in[0] * M[2] + in[1] * M[6] + in[2] * M[10] + in[3] * M[14], + in[0] * M[3] + in[1] * M[7] + in[2] * M[11] + in[3] * M[15]); +} + +template +irr::video::sVec4 operator* (const irr::video::sVec4& v, const irr::core::CMatrix4& m) +{ + const T* burning_restrict M = m.pointer(); + const float* burning_restrict in = &v.x; + return irr::video::sVec4( + in[0] * M[0] + in[1] * M[1] + in[2] * M[2] + in[3] * M[3], + in[0] * M[4] + in[1] * M[5] + in[2] * M[6] + in[3] * M[7], + in[0] * M[8] + in[1] * M[9] + in[2] * M[10] + in[3] * M[11], + in[0] * M[12] + in[1] * M[13] + in[2] * M[14] + in[3] * M[15]); +} + +static inline float dot(const irr::video::sVec4& a, const irr::video::sVec4& b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} + + +static inline irr::video::sVec4 operator-(const irr::video::sVec4& a) +{ + return irr::video::sVec4(-a.x, -a.y, -a.z, -a.w); +} + +static inline irr::video::sVec4 normalize(const irr::video::sVec4& a) +{ + float l = a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w; + if (l < 0.00000001f) + return irr::video::sVec4(0.f, 0.f, 1.f, 1.f); + l = 1.f / sqrtf(l); + return irr::video::sVec4(a.x * l, a.y * l, a.z * l, a.w * l); +} + +// sVec3 xyz +static inline irr::video::sVec4 cross(const irr::video::sVec4& a, const irr::video::sVec4& b) +{ + return irr::video::sVec4(a.y * b.z - b.y * a.z, a.z * b.x - b.z * a.x, a.x * b.y - b.x * a.y, 0.f); +} + + +void irr::video::sVec4::setA8R8G8B8(const u32 argb) +{ + //error term necessary. cancels out(somehow) at 255 argb((tofixpoint(r/w)+fix_0.5) + static const f32 is = 1.f / (255.f); + r = ((argb & 0x00FF0000) >> 16) * is; + g = ((argb & 0x0000FF00) >> 8) * is; + b = ((argb & 0x000000FF)) * is; + a = ((argb & 0xFF000000) >> 24) * is; +} + + +//need to prevent floating point over/underflow //based on https://github.com/ekmett/approximate/blob/master/cbits/fast.c powf_fast_precise static inline float powf_limit(const float a, const float b) { - if (a <= 0.0000001f) return 0.f; - else if (a >= 1.f) return 1.f; + if (a < 0.00000001f) + return 0.f; + else if (a >= 1.f) + return a * b; /* calculate approximation with fraction of the exponent */ int e = (int)b; @@ -162,8 +309,8 @@ static inline float powf_limit(const float a, const float b) if (e & 1) { r *= ua; } - if (ua < 0.00000001f) - break; + if (ua < 0.000000001f) + return 0.f; ua *= ua; e >>= 1; } @@ -172,12 +319,27 @@ static inline float powf_limit(const float a, const float b) return r; } -//! clamp(value,0,1) -static inline float clampf01(const float v) + +/* + if (condition) state |= m; else state &= ~m; +*/ +REALINLINE void burning_setbit32(unsigned int& state, int condition, const unsigned int mask) { - return v < 0.f ? 0.f : v > 1.f ? 1.f : v; + // 0, or any positive to mask + //s32 conmask = -condition >> 31; + state ^= ((-condition >> 31) ^ state) & mask; } +/* + 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; +} + + // IImage::fill static void image_fill(irr::video::IImage* image, const irr::video::SColor& color, const interlaced_control interlaced) { @@ -199,41 +361,175 @@ static void image_fill(irr::video::IImage* image, const irr::video::SColor& colo } -union scale_setup -{ - struct - { - unsigned char x : 3; - unsigned char y : 3; - unsigned char i : 2; - }; - unsigned char v; -}; //setup Antialias. v0.52 uses as Interlaced -void get_scale(scale_setup& s, const irr::SIrrlichtCreationParameters& params) +void get_scale(interlaced_control& o, const irr::SIrrlichtCreationParameters& params) { - s.x = 1; - s.y = 1; - s.i = 0; - if (params.AntiAlias && params.WindowSize.Width <= 160 && params.WindowSize.Height <= 120) + o.raw = 0; + o.bypass = 1; +#if !defined(SOFTWARE_DRIVER_2_RENDERTARGET_SCALE) + return; +#endif + + //test case + if (0 || params.WindowSize.Width <= 160 || params.WindowSize.Height <= 128) { return; } + union scale_setup + { + struct + { + unsigned char x : 3; + unsigned char y : 3; + unsigned char i : 2; + }; + unsigned char v; + }; + + scale_setup s; + s.x = 1; + s.y = 1; + s.i = 0; + switch (params.AntiAlias) { + default: + case 0: s.x = 1; s.y = 1; s.i = 0; break; case 2: s.x = 1; s.y = 1; s.i = 1; break; case 4: s.x = 2; s.y = 2; s.i = 0; break; - case 8: s.x = 2; s.y = 2; s.i = 1; break; + case 8: s.x = 2; s.y = 2; s.i = params.Vsync ? 1 : 0; break; case 16:s.x = 4; s.y = 4; s.i = 0; break; case 32:s.x = 4; s.y = 4; s.i = 1; break; case 3: s.x = 3; s.y = 3; s.i = 0; break; case 5: s.x = 3; s.y = 3; s.i = 1; break; } + + /* + if (params.WindowSize.Height > 384) + { + s.i = params.Vsync ? 0 : 1; + s.x = params.AntiAlias ? 1 : 2; + s.y = params.AntiAlias ? 1 : 2; + } + */ + + o.enable = s.i; + o.target_scalex = s.x - 1; + o.tex_scalex = 0; // s.x >= 2 ? s.x - 1 : 0; + +#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) + o.enable = params.Vsync ? 0 : 1; + + switch (params.AntiAlias) + { + default: + case 0: o.target_scalex = 0; o.tex_scalex = 0; break; + case 2: o.target_scalex = 1; o.tex_scalex = 0; break; + case 4: o.target_scalex = 1; o.tex_scalex = 1; break; + case 8: o.target_scalex = 2; o.tex_scalex = 1; break; + } +#endif + + o.bypass = o.enable == 0; + o.nr = 0; + o.target_scaley = o.target_scalex; + o.tex_scaley = o.tex_scalex; + + if (o.enable || o.target_scalex || o.tex_scalex) + { + char buf[256]; + snprintf_irr(buf, sizeof(buf), "Burningvideo: Interlaced:%d,%d target:%d,%d tex:%d,%d", + o.enable, + o.bypass, + o.target_scalex, + o.target_scaley, + o.tex_scalex, + o.tex_scaley + ); + irr::os::Printer::log(buf, irr::ELL_NONE); + } } +#if 0 +#include +//#pragma STDC FENV_ACCESS ON +#pragma fenv_access (on) +void show_fe_exceptions(void) +{ + int t = fetestexcept(FE_ALL_EXCEPT); + if (t == 0) return; + + printf("exceptions raised:"); + if (t & FE_DIVBYZERO) printf(" FE_DIVBYZERO"); + if (t & FE_INEXACT) printf(" FE_INEXACT"); + if (t & FE_INVALID) printf(" FE_INVALID"); + if (t & FE_OVERFLOW) printf(" FE_OVERFLOW"); + if (t & FE_UNDERFLOW) printf(" FE_UNDERFLOW"); + feclearexcept(FE_ALL_EXCEPT); + printf("\n"); +} +#endif + +#if 0 +//code snippets +#include +#include +#include +#include +void switch_between_ortho_and_perspective_projection(irr::IrrlichtDevice* device, irr::video::E_DRIVER_TYPE driverType) +{ + //switch between ortho and perspective projection + irr::scene::ICameraSceneNode* cam = device->getSceneManager()->addCameraSceneNode(); + cam->setPosition(irr::core::vector3df(300, 250, -300)); + cam->setTarget(irr::core::vector3df(0, 20, 0)); + if (1 || driverType != irr::video::EDT_BURNINGSVIDEO) + { + cam->setProjectionMatrix(irr::core::matrix4().buildProjectionMatrixOrthoLH(120, 90, 0.9f, 5000.f, driverType != irr::video::EDT_OPENGL), true); + } + else + { + irr::f32 w = (2.f * 0.9f) / (2.f / 120.f * (cam->getTarget() - cam->getPosition()).getLength()); + cam->setProjectionMatrix(irr::core::matrix4().buildProjectionMatrixPerspectiveLH(w, w * (90.f / 120.f), 0.9f, 5000.f, driverType != irr::video::EDT_OPENGL), true); + } +} + +/* + For using an alternative camera in the examples. + Try to translate the viewpoint (Maya internal CameraRotation) +*/ +static inline void switchToMayaCamera(irr::IrrlichtDevice* device) +{ + if (!device) return; + + irr::scene::ICameraSceneNode* camera = device->getSceneManager()->getActiveCamera(); + if (!camera || camera->getID() == 54321) return; + + + irr::core::vector3df target = camera->getTarget() - camera->getPosition(); + irr::core::vector3df relativeRotation = target.getHorizontalAngle(); + + irr::scene::ICameraSceneNode* maya = device->getSceneManager()->addCameraSceneNodeMaya( + 0, -1500, 1000, 1500, + 54321, + target.getLength(), + true, + relativeRotation.X + 90, relativeRotation.Y + ); + if (maya) + { + maya->setNearValue(camera->getNearValue()); + maya->setFarValue(camera->getFarValue()); + } + + device->getCursorControl()->setVisible(true); + device->setResizable(true); +} +#endif + + //turn on/off fpu exception void fpu_exception(int on) { @@ -244,10 +540,7 @@ void fpu_exception(int on) #endif } -namespace irr -{ -namespace video -{ +burning_namespace_start //! constructor CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) @@ -266,21 +559,20 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters& VertexCache_map_source_format(); //Use AntiAlias(hack) to shrink BackBuffer Size and keep ScreenSize the same as Input - scale_setup scale; - get_scale(scale, params); - //Control Interlaced BackBuffer - Interlaced.enable = scale.i; - Interlaced.bypass = !Interlaced.enable; - Interlaced.nr = 0; + //Control Interlaced/scaled BackBuffer + get_scale(Interlaced, params); + TexBias[ETF_STACK_3D] = 1.f; + TexBias[ETF_STACK_2D] = 1.f; // create backbuffer. - core::dimension2du use(params.WindowSize.Width / scale.x, params.WindowSize.Height / scale.y); + core::dimension2du use(params.WindowSize.Width / (Interlaced.target_scalex + 1), + params.WindowSize.Height / (Interlaced.target_scaley + 1)); BackBuffer = new CImage(SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT, use); if (BackBuffer) { //BackBuffer->fill(SColor(0)); - image_fill(BackBuffer, SColor(0), interlace_disabled()); + image_fill(BackBuffer, SColor(0), interlaced_disabled()); // create z buffer if (params.ZBufferBits) @@ -372,14 +664,14 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters& //umr->drop (); // select render target - setRenderTargetImage2(BackBuffer,0, 0); + setRenderTargetImage2(BackBuffer, 0, 0); //reset Lightspace - EyeSpace.reset(); - EyeSpace.resetFog(); + EyeSpace.init(); // select the right renderer setMaterial(Material.org); + samples_passed = 0; } @@ -392,8 +684,13 @@ CBurningVideoDriver::~CBurningVideoDriver() BackBuffer->drop(); BackBuffer = 0; } + //release textures + if (CurrentShader) + { + } + Material.mat2D.setTexture(0, 0); - // delete triangle renderers + // deleteMaterialRenders for (s32 i = 0; i < ETR2_COUNT; ++i) { if (BurningShader[i]) @@ -402,6 +699,7 @@ CBurningVideoDriver::~CBurningVideoDriver() BurningShader[i] = 0; } } + //deleteMaterialRenders(); // delete Additional buffer if (StencilBuffer) @@ -429,7 +727,6 @@ CBurningVideoDriver::~CBurningVideoDriver() } fpu_exception(0); - } @@ -488,6 +785,9 @@ bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const break; #endif #endif + case EVDF_OCCLUSION_QUERY: + on = 1; + break; default: on = 0; break; @@ -507,7 +807,7 @@ void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO st size_t ok = 0; switch (state) { - case ETS_PROJ_MODEL_VIEW: + case ETS_MODEL_VIEW_PROJ: if (0 == (flag[ETS_VIEW_PROJECTION] & ETF_VALID)) transform_calc(ETS_VIEW_PROJECTION); ok = flag[ETS_WORLD] & flag[ETS_VIEW] & flag[ETS_PROJECTION] & flag[ETS_VIEW_PROJECTION] & ETF_VALID; break; @@ -535,7 +835,7 @@ void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO st switch (state) { - case ETS_PROJ_MODEL_VIEW: + case ETS_MODEL_VIEW_PROJ: if (flag[ETS_WORLD] & ETF_IDENTITY) { matrix[state] = matrix[ETS_VIEW_PROJECTION]; @@ -560,7 +860,7 @@ void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO st } break; case ETS_NORMAL: - mat44_transposed_inverse(matrix[state], matrix[ETS_MODEL_VIEW]); + mat33_transposed_inverse(matrix[state], matrix[ETS_MODEL_VIEW]); break; default: @@ -594,7 +894,7 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core: burning_setbit(TransformationFlag[state], mat.getDefinitelyIdentityMatrix(), ETF_IDENTITY); #else burning_setbit(flag[state], - !memcmp(mat.pointer(), core::IdentityMatrix.pointer(), sizeof(mat)), ETF_IDENTITY + 0 == memcmp(mat.pointer(), core::IdentityMatrix.pointer(), sizeof(mat)), ETF_IDENTITY ); #endif @@ -604,17 +904,17 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core: switch (state) { case ETS_PROJECTION: - flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID; + flag[ETS_MODEL_VIEW_PROJ] &= ~ETF_VALID; flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID; break; case ETS_VIEW: - flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID; + flag[ETS_MODEL_VIEW_PROJ] &= ~ETF_VALID; flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID; flag[ETS_MODEL_VIEW] &= ~ETF_VALID; flag[ETS_NORMAL] &= ~ETF_VALID; break; case ETS_WORLD: - flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID; + flag[ETS_MODEL_VIEW_PROJ] &= ~ETF_VALID; flag[ETS_MODEL_VIEW] &= ~ETF_VALID; flag[ETS_NORMAL] &= ~ETF_VALID; break; @@ -636,7 +936,7 @@ void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core: #endif if (0 == (flag[state] & ETF_IDENTITY)) { - EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM; + flag[state] |= ETF_TEXGEN_MATRIX; } break; default: @@ -693,7 +993,7 @@ bool CBurningVideoDriver::setRenderTarget(video::ITexture* texture, bool clearBa CSoftwareRenderTarget2 target(this); target.RenderTexture = texture; target.TargetType = ERT_RENDER_TEXTURE; - target.Texture[0] = texture; + target.Textures[0] = texture; if (texture) texture->grab(); @@ -728,7 +1028,7 @@ bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag #if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) RenderTargetTexture = target ? target->getTexture()[0] : 0; #else - RenderTargetTexture = target ? ((CSoftwareRenderTarget2*)target)->Texture[0] : 0; + RenderTargetTexture = target ? ((CSoftwareRenderTarget2*)target)->Textures[0] : 0; #endif if (RenderTargetTexture) @@ -739,7 +1039,7 @@ bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag } else { - Interlaced.bypass = !Interlaced.enable; + Interlaced.bypass = Interlaced.enable == 0; setRenderTargetImage2(BackBuffer); } @@ -791,29 +1091,30 @@ void CBurningVideoDriver::setRenderTargetImage2(video::IImage* color, video::IIm //--------- Transform from NDC to DC, transform TexCoo ---------------------------------------------- -//! Blur 2D Image with PixelOffset. (default 0.375f for OpenGL and Burning) -/** SideEffects: -* if IRRLICHT_2D_TEXEL_OFFSET > 0 is applied to OpenGL/Burning, Pixel-exact Texture Coordinates do not match. -* Currently Version 1.8,1.9 has that in the Irrlicht 2D Examples where you get a Magenta Border on the Sprites -* and in the draw2DImage4cFilter Tests -*/ -#define IRRLICHT_2D_TEXEL_OFFSET 0.f - //--------- Transform from NDC to DC ---------------------------------------------- -// used to scale <-1,-1><1,1> to viewport [center,scale] +// used to scale <-1,-1><1,1> to viewport [scale,center] // controls subtexel and fill convention. // Don't tweak SOFTWARE_DRIVER_2_SUBTEXEL (-0.5f in m[1]) anymore to control texture blur effect, it's used for viewport scaling. // naming is misleading. it will write outside memory location.. -void buildNDCToDCMatrix(f32* m, const core::rect& viewport, f32 tx) +//xw = (xn+1)*(w/2) + x +void buildNDCToDCMatrix(f32* burning_restrict dc_matrix, const core::rect& viewport, const f32 center) { - m[0] = (viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X + tx) * 0.5f; - m[1] = (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X-1) * 0.5f; + //const f32 center = -0.5f; // combined with top / left fill convention to (0,0)-(x-1,y-1) + + f32 x0 = viewport.UpperLeftCorner.X + center; + f32 x1 = viewport.LowerRightCorner.X - 1 - center; + f32 y0 = viewport.UpperLeftCorner.Y + center; + f32 y1 = viewport.LowerRightCorner.Y - 1 - center; + + dc_matrix[0] = (x1 - x0) * 0.5f; + dc_matrix[1] = dc_matrix[0] + x0; + + dc_matrix[2] = (y0 - y1) * 0.5f; + dc_matrix[3] = dc_matrix[2] + y1; - m[2] = (viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y + tx) * -0.5f; - m[3] = (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y-1) * 0.5f; } @@ -821,13 +1122,23 @@ void buildNDCToDCMatrix(f32* m, const core::rect& viewport, f32 tx) //! sets a viewport void CBurningVideoDriver::setViewPort(const core::rect& area) { + //const core::rect rendert(0, 0, getCurrentRenderTargetSize().Width, getCurrentRenderTargetSize().Height); + const core::rect rendert(0, 0, RenderTargetSize.Width, RenderTargetSize.Height); + ViewPort = area; - - core::rect rendert(0, 0, RenderTargetSize.Width, RenderTargetSize.Height); ViewPort.clipAgainst(rendert); + const s32 viewarea = ViewPort.getArea(); - buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[0], ViewPort, 1.f/2048.f); //SkyBox,Billboard 90° problem - buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[1], ViewPort, 0.f); // OverrideMaterial2DEnabled ? -IRRLICHT_2D_TEXEL_OFFSET : 0.f); + //is this even possible to be pixel-perfect if i have not the same depth range as openGL? + //fill convention maybe flipped because window space is flipped so +-1 pixel always off? + buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[ETF_STACK_3D], ViewPort, -0.5f); + + //Pixel Offset in window space here and not in view-space to avoid clipping + //[-0.5,-0.5]-[w-0.5,h-0.5] + buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[ETF_STACK_2D], ViewPort, -0.5f); + + TexBias[ETF_STACK_3D] = viewarea <= (160 * 120) ? 1.5f : Interlaced.target_scalex ? 0.75f : 0.75f; + TexBias[ETF_STACK_2D] = 1.5f; if (CurrentShader) CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced); @@ -862,17 +1173,16 @@ void CBurningVideoDriver::setScissor(int x, int y, int width, int height) cam is (0,0,-1) */ -const sVec4 CBurningVideoDriver::NDCPlane[6 + 2] = +static const sVec4 NDCPlane[6 + 2] = { - sVec4(0.f, 0.f, -1.f, -1.f), // near - sVec4(0.f, 0.f, 1.f, -1.f), // far + sVec4(0.f, 0.f, 1.f, -1.f), // near + sVec4(0.f, 0.f, -1.f, -1.f), // far sVec4(1.f, 0.f, 0.f, -1.f), // left sVec4(-1.f, 0.f, 0.f, -1.f), // right sVec4(0.f, 1.f, 0.f, -1.f), // bottom - sVec4(0.f, -1.f, 0.f, -1.f) // top + sVec4(0.f, -1.f, 0.f, -1.f) // top }; - /* test a vertex if it's inside the standard frustum @@ -943,9 +1253,9 @@ REALINLINE size_t CBurningVideoDriver::clipToFrustumTest(const s4DVertex* v) con #else -REALINLINE size_t clipToFrustumTest(const s4DVertex* v) +REALINLINE u32 clipToFrustumTest(const s4DVertex* v) { - size_t flag = 0; + u32 flag = 0; flag |= v->Pos.z <= v->Pos.w ? (size_t)VERTEX4D_CLIP_NEAR : 0; flag |= -v->Pos.z <= v->Pos.w ? (size_t)VERTEX4D_CLIP_FAR : 0; @@ -957,26 +1267,32 @@ REALINLINE size_t clipToFrustumTest(const s4DVertex* v) flag |= -v->Pos.y <= v->Pos.w ? (size_t)VERTEX4D_CLIP_TOP : 0; - /* - for ( u32 i = 0; i <= 6; ++i ) - { - if (v->Pos.dot_xyzw(NDCPlane[i]) <= 0.f) flag |= ((size_t)1) << i; - } - */ + //verify with plane +/* + size_t flag2 = 0; + for ( u32 i = 0; i < 6; ++i ) + { + if (v->Pos.dot_xyzw(NDCPlane[i]) <= 0.f) flag2 |= ((size_t)1) << i; + } + if (flag != flag2) + { + int g = 1; + } +*/ return flag; } #endif // _MSC_VER -size_t clipToHyperPlane( +u32 clipToHyperPlane( s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, - const size_t inCount, + const u32 inCount, const sVec4& plane ) { - size_t outCount = 0; + u32 outCount = 0; s4DVertexPair* out = dest; const s4DVertex* a; @@ -996,8 +1312,10 @@ size_t clipToHyperPlane( a = source + index; #endif */ + + // polygon scan conversion edge sharing opposite side? //Sutherland–Hodgman - for (size_t i = 0; i < inCount; ++i) + for (u32 i = 0; i < inCount; ++i) { a = source + (i == inCount - 1 ? 0 : s4DVertex_ofs(i + 1)); @@ -1008,7 +1326,9 @@ size_t clipToHyperPlane( if (ipol_greater_0(bDotPlane)) { // intersect line segment with plane - out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane)); + //out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane)); + ipoltype denom = (b->Pos - a->Pos).dot_xyzw(plane); + out->interpolate(*b, *a, bDotPlane / denom); out += sizeof_s4DVertexPairRel; outCount += 1; } @@ -1024,11 +1344,13 @@ size_t clipToHyperPlane( else { // current point outside - if (ipol_lower_equal_0(bDotPlane)) + if (ipol_lower_0(bDotPlane)) { // previous was inside // intersect line segment with plane - out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane)); + //out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane)); + ipoltype denom = (b->Pos - a->Pos).dot_xyzw(plane); + out->interpolate(*b, *a, bDotPlane / denom); out += sizeof_s4DVertexPairRel; outCount += 1; } @@ -1047,15 +1369,15 @@ size_t clipToHyperPlane( Clip on all planes. Clipper.data clipmask per face */ -size_t CBurningVideoDriver::clipToFrustum(const size_t vIn /*, const size_t clipmask_for_face*/) +u32 CBurningVideoDriver::clipToFrustum(const u32 vIn /*, const size_t clipmask_for_face*/) { s4DVertexPair* v0 = Clipper.data; - s4DVertexPair* v1 = Clipper_temp.data; - size_t vOut = vIn; + s4DVertexPair* v1 = Clipper_disjoint.data; + u32 vOut = vIn; //clear all clipping & projected flags const u32 flag = v0[0].flag & VERTEX4D_FORMAT_MASK; - for (size_t g = 0; g != Clipper.ElementSize; ++g) + for (u32 g = 0; g != Clipper.ElementSize; ++g) { v0[g].flag = flag; v1[g].flag = flag; @@ -1064,8 +1386,8 @@ size_t CBurningVideoDriver::clipToFrustum(const size_t vIn /*, const size_t clip #if 0 for (size_t i = 0; i < 6; ++i) { - v0 = i & 1 ? Clipper_temp.data : Clipper.data; - v1 = i & 1 ? Clipper.data : Clipper_temp.data; + v0 = i & 1 ? Clipper_disjoint.data : Clipper.data; + v1 = i & 1 ? Clipper.data : Clipper_disjoint.data; //clipMask checked outside - always clip all planes #if 0 @@ -1084,7 +1406,7 @@ size_t CBurningVideoDriver::clipToFrustum(const size_t vIn /*, const size_t clip #endif - vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[0]); if (vOut < vIn) return vOut; + vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[0]); if (vOut < vIn) return vOut; vOut = clipToHyperPlane(v0, v1, vOut, NDCPlane[1]); if (vOut < vIn) return vOut; vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[2]); if (vOut < vIn) return vOut; vOut = clipToHyperPlane(v0, v1, vOut, NDCPlane[3]); if (vOut < vIn) return vOut; @@ -1109,18 +1431,18 @@ size_t CBurningVideoDriver::clipToFrustum(const size_t vIn /*, const size_t clip replace w/w by 1/w */ //aliasing problems! [dest = source + 1] +#if 0 inline void CBurningVideoDriver::ndc_2_dc_and_project(s4DVertexPair* dest, const s4DVertexPair* source, const size_t vIn) const { const f32* dc = Transformation_ETS_CLIPSCALE[TransformationStack]; - for (size_t g = 0; g != vIn; g += sizeof_s4DVertexPairRel) + for (size_t g = 0; g < vIn; g += sizeof_s4DVertexPairRel) { //cache doesn't work anymore? //if ( dest[g].flag & VERTEX4D_PROJECTED ) // continue; //dest[g].flag = source[g].flag | VERTEX4D_PROJECTED; - - const f32 iw = reciprocal_zero(source[g].Pos.w); + const f32 iw = reciprocal_zero_pos_underflow(source[g].Pos.w); // to device coordinates dest[g].Pos.x = iw * source[g].Pos.x * dc[0] + dc[1]; @@ -1132,6 +1454,9 @@ inline void CBurningVideoDriver::ndc_2_dc_and_project(s4DVertexPair* dest, const #endif dest[g].Pos.w = iw; + //ortographic projection w == 1 looses stencil + //dest[g].Pos.w = 1.f - dest[g].Pos.z; + // Texture Coordinates will be projected after mipmap selection // satisfy write-combiner #if 1 @@ -1147,7 +1472,6 @@ inline void CBurningVideoDriver::ndc_2_dc_and_project(s4DVertexPair* dest, const #if BURNING_MATERIAL_MAX_TEXTURES > 3 dest[g].Tex[3] = source[g].Tex[3]; #endif - #endif #if BURNING_MATERIAL_MAX_COLORS > 0 @@ -1188,8 +1512,201 @@ inline void CBurningVideoDriver::ndc_2_dc_and_project(s4DVertexPair* dest, const } } +#endif +inline void ndc_2_dc_and_project(s4DVertexPair* burning_restrict v, const u32 vIn, + const f32* burning_restrict dc_matrix +) +{ +#define src v[g] +#define dst v[g+1] + + for (u32 g = 0; g < vIn; g += sizeof_s4DVertexPairRel) + { + //cache doesn't work anymore? + //if ( dst.flag & VERTEX4D_PROJECTED ) continue; + //dst.flag = src.flag | VERTEX4D_PROJECTED; + + const f32 iw = reciprocal_zero_pos_underflow(src.Pos.w); + + // from normalized device to window coordinates (-1,-1) viewport + + //limit sub pixel for consistent fill convention (wrong place) +#if SOFTWARE_DRIVER_2_SUBPIXEL_LIMIT > 0 && 0 + dst.Pos.x = floorf((iw * src.Pos.x * dc_matrix[0] + dc_matrix[1]) * 128.f+0.5f) * (1.f / 128.f); + dst.Pos.y = floorf((iw * src.Pos.y * dc_matrix[2] + dc_matrix[3]) * 128.f + 0.5f) * (1.f/ 128.f); +#else + dst.Pos.x = iw * src.Pos.x * dc_matrix[0] + dc_matrix[1]; + dst.Pos.y = iw * src.Pos.y * dc_matrix[2] + dc_matrix[3]; +#endif + + + //burning uses direct Z. for OpenGL it should be -Z,[-1;1] and texture flip +#if !defined(SOFTWARE_DRIVER_2_USE_WBUFFER) || 1 + dst.Pos.z = -iw * src.Pos.z * 0.5f + 0.5f; +#endif + dst.Pos.w = iw; + + //ortographic projection w == 1 looses stencil + //dest[g].Pos.w = 1.f - dest[g].Pos.z; + + // Texture Coordinates will be projected after mipmap selection + // satisfy write-combiner + //todo: only set on flag +#if 1 +#if BURNING_MATERIAL_MAX_TEXTURES > 0 + dst.Tex[0].x = src.Tex[0].x; + dst.Tex[0].y = src.Tex[0].y; +#endif +#if BURNING_MATERIAL_MAX_TEXTURES > 1 + dst.Tex[1].x = src.Tex[1].x; + dst.Tex[1].y = src.Tex[1].y; +#endif +#if BURNING_MATERIAL_MAX_TEXTURES > 2 + dst.Tex[2].x = src.Tex[2].x; + dst.Tex[2].y = src.Tex[2].y; +#endif +#if BURNING_MATERIAL_MAX_TEXTURES > 3 + dst.Tex[3].x = src.Tex[3].x; + dst.Tex[3].y = src.Tex[3].y; +#endif +#endif + + // alpha? +#if BURNING_MATERIAL_MAX_COLORS > 0 +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dst.Color[0].r = src.Color[0].r * iw; + dst.Color[0].g = src.Color[0].g * iw; + dst.Color[0].b = src.Color[0].b * iw; + dst.Color[0].a = src.Color[0].a * iw; +#else + dst.Color[0] = src.Color[0]; +#endif +#endif + +#if BURNING_MATERIAL_MAX_COLORS > 1 +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dst.Color[1].r = src.Color[1].r * iw; + dst.Color[1].g = src.Color[1].g * iw; + dst.Color[1].b = src.Color[1].b * iw; + dst.Color[1].a = src.Color[1].a * iw; +#else + dst.Color[1] = src.Color[1]; +#endif +#endif + +#if BURNING_MATERIAL_MAX_COLORS > 2 +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dst.Color[2].r = src.Color[2].r * iw; + dst.Color[2].g = src.Color[2].g * iw; + dst.Color[2].b = src.Color[2].b * iw; + dst.Color[2].a = src.Color[2].a * iw; +#else + dst.Color[2] = src.Color[2]; +#endif +#endif + +#if BURNING_MATERIAL_MAX_COLORS > 3 +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dst.Color[3].r = src.Color[3].r * iw; + dst.Color[3].g = src.Color[3].g * iw; + dst.Color[3].b = src.Color[3].b * iw; + dst.Color[3].a = src.Color[3].a * iw; +#else + dst.Color[3] = src.Color[3]; +#endif +#endif + +#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0 +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dst.LightTangent[0].x = src.LightTangent[0].x * iw; + dst.LightTangent[0].y = src.LightTangent[0].y * iw; + dst.LightTangent[0].z = src.LightTangent[0].z * iw; +#else + dst.LightTangent[0] = src.LightTangent[0]; +#endif +#endif + } + +#undef src +#undef dst + +} + +inline void ndc_2_dc_and_project_grid(s4DVertexPair* burning_restrict v, const u32 vIn, + const f32* burning_restrict dc_matrix +) +{ +#define src v[g] +#define dst v[g+1] + + u32 i; + u32 size; + + for (u32 g = 0; g < vIn; g += sizeof_s4DVertexPairRel) + { + const f32 iw = reciprocal_zero_pos_underflow(src.Pos.w); + + // from normalized device to window coordinates (-1,-1) viewport + + //limit sub pixel for consistent fill convention (wrong place) + dst.Pos.x = floorf((iw * src.Pos.x * dc_matrix[0] + dc_matrix[1]) * 4096.f + 0.5f) * (1.f / 4096.f); + dst.Pos.y = floorf((iw * src.Pos.y * dc_matrix[2] + dc_matrix[3]) * 4096.f + 0.5f) * (1.f / 4096.f); + + //burning uses direct Z. for OpenGL it should be -Z,[-1;1] and texture flip +#if !defined(SOFTWARE_DRIVER_2_USE_WBUFFER) || 1 + dst.Pos.z = -iw * src.Pos.z * 0.5f + 0.5f; +#endif + dst.Pos.w = iw; + +#if BURNING_MATERIAL_MAX_TEXTURES > 0 + size = (src.flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16; + for (i = 0; i != size; ++i) + { + dst.Tex[i].x = src.Tex[i].x; + dst.Tex[i].y = src.Tex[i].y; + } +#endif + +#if BURNING_MATERIAL_MAX_COLORS > 0 + size = (src.flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20; + for (i = 0; i != size; ++i) + { + // alpha? +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dst.Color[i].r = src.Color[i].r * iw; + dst.Color[i].g = src.Color[i].g * iw; + dst.Color[i].b = src.Color[i].b * iw; + dst.Color[i].a = src.Color[i].a * iw; +#else + dst.Color[i] = src.Color[i]; +#endif + } +#endif + + +#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0 + size = (src.flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24; + for (i = 0; i != size; ++i) + { +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + dst.LightTangent[i].x = src.LightTangent[i].x * iw; + dst.LightTangent[i].y = src.LightTangent[i].y * iw; + dst.LightTangent[i].z = src.LightTangent[i].z * iw; +#else + dst.LightTangent[i] = src.LightTangent[i]; +#endif + } +#endif + +} + +#undef src +#undef dst + +} + #if 0 /*! @@ -1225,6 +1742,20 @@ f32 MipmapLevel(const sVec2& uv, const sVec2& textureSize) //#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( (u32)tex ) ) #define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.TextureLayer[tex].Texture ) +//! clamp(value,0,1) +static inline float clampfuv(const float v, const float b) +{ + // b = 1.f - (2.f * (1/width)) + return v < b ? b : v > 1.f - b ? 1.f - b : v; + //return v < b ? b : v > 1.f-b ? 1.f-b : v; +} + +static inline float clampf01(const float v) +{ + return v < 0.f ? 0.f : v > 1.f ? 1.f : v; +} + +#if 0 /*! calculate from unprojected. attribute need not to follow winding rule from position. @@ -1233,7 +1764,7 @@ f32 MipmapLevel(const sVec2& uv, const sVec2& textureSize) Atlas problem */ REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burning_restrict const face[], - const size_t m, const f32 dc_area, const f32 lod_bias) const + const size_t m, const f32 dc_area_one_over, const f32 lod_bias) const { /* sVec2 a(v[1]->Tex[tex].x - v[0]->Tex[tex].x,v[1]->Tex[tex].y - v[0]->Tex[tex].y); @@ -1255,7 +1786,7 @@ REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burnin t[2].f = face[2]->Tex[m].x - face[0]->Tex[m].x; t[3].f = face[2]->Tex[m].y - face[0]->Tex[m].y; - //crossproduct in projected 2D -> screen area triangle + //|crossproduct| in projected 2D -> screen area triangle * 0.5f signedArea.f = t[0].f * t[3].f - t[2].f * t[1].f; //signedArea = @@ -1296,43 +1827,44 @@ REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burnin f32 texelspace = d[0] * d[1] * lod_bias; //(m ? 0.5f : 0.5f); ieee754 ratio; - ratio.f = (signedArea.f * texelspace) * dc_area; + ratio.f = (signedArea.f * texelspace) * dc_area_one_over; ratio.fields.sign = 0; //log2(0)==denormal [ use high lod] [ only if dc_area == 0 checked outside ] return (ratio.fields.exp & 0x80) ? ratio.fields.exp - 127 : 0; /*denormal very high lod*/ } +#endif - +#if 0 /*! texcoo in current mipmap dimension (face, already clipped) -> want to help fixpoint */ -inline void CBurningVideoDriver::select_polygon_mipmap_inside(s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b) const +inline void CBurningVideoDriver::select_polygon_mipmap_inside(s4DVertexPair* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b) const { #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT - (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * (face[0] + 1)->Pos.w * b.w + b.cx; - (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * (face[0] + 1)->Pos.w * b.h + b.cy; + (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * (face[0] + 1)->Pos.w * b.mat[0] + b.mat[1]; + (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * (face[0] + 1)->Pos.w * b.mat[2] + b.mat[3]; - (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * (face[1] + 1)->Pos.w * b.w + b.cx; - (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * (face[1] + 1)->Pos.w * b.h + b.cy; + (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * (face[1] + 1)->Pos.w * b.mat[0] + b.mat[1]; + (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * (face[1] + 1)->Pos.w * b.mat[2] + b.mat[3]; - (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * (face[2] + 1)->Pos.w * b.w + b.cx; - (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * (face[2] + 1)->Pos.w * b.h + b.cy; + (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * (face[2] + 1)->Pos.w * b.mat[0] + b.mat[1]; + (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * (face[2] + 1)->Pos.w * b.mat[2] + b.mat[3]; #else - (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * b.w; - (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * b.h; + (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * b.mat[0] + b.mat[1]; + (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * b.mat[2] + b.mat[3]; - (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * b.w; - (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * b.h; + (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * b.mat[0] + b.mat[1]; + (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * b.mat[2] + b.mat[3]; - (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * b.w; - (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * b.h; + (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * b.mat[0] + b.mat[1]; + (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * b.mat[2] + b.mat[3]; #endif } - +#endif // Vertex Cache @@ -1361,7 +1893,7 @@ void CBurningVideoDriver::VertexCache_map_source_format() IRR_DEBUG_BREAK_IF(1); } - if (((unsigned long long)Transformation&15) || ((unsigned long long)TransformationFlag & 15)) + if (((unsigned long long)Transformation & 15) || ((unsigned long long)TransformationFlag & 15)) { os::Printer::log("BurningVideo Matrix Stack not 16 byte aligned", ELL_ERROR); IRR_DEBUG_BREAK_IF(1); @@ -1369,14 +1901,14 @@ void CBurningVideoDriver::VertexCache_map_source_format() #endif - SVSize* vSize = VertexCache.vSize; + SVSize* vSize = VertexShader.vSize; //vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_SPECULAR; vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_2_FOG; vSize[E4VT_STANDARD].Pitch = sizeof(S3DVertex); vSize[E4VT_STANDARD].TexSize = 1; vSize[E4VT_STANDARD].TexCooSize = 1; - vSize[E4VT_2TCOORDS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1; + vSize[E4VT_2TCOORDS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_2_FOG; vSize[E4VT_2TCOORDS].Pitch = sizeof(S3DVertex2TCoords); vSize[E4VT_2TCOORDS].TexSize = 2; vSize[E4VT_2TCOORDS].TexCooSize = 2; @@ -1388,7 +1920,7 @@ void CBurningVideoDriver::VertexCache_map_source_format() vSize[E4VT_TANGENTS].TexCooSize = 2; // reflection map - vSize[E4VT_REFLECTION_MAP].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1; + vSize[E4VT_REFLECTION_MAP].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_2_FOG; vSize[E4VT_REFLECTION_MAP].Pitch = sizeof(S3DVertex); vSize[E4VT_REFLECTION_MAP].TexSize = 2; vSize[E4VT_REFLECTION_MAP].TexCooSize = 1; //TexCoo2 generated @@ -1411,14 +1943,16 @@ void CBurningVideoDriver::VertexCache_map_source_format() vSize[E4VT_LINE].TexSize = 0; vSize[E4VT_LINE].TexCooSize = 0; - size_t size; + //verify with global defines + u32 size; for (size_t i = 0; i < E4VT_COUNT; ++i) { - size_t& flag = vSize[i].Format; + u32& flag = vSize[i].Format; #if !defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR) flag &= ~VERTEX4D_FORMAT_SPECULAR; #endif + if (vSize[i].TexSize > BURNING_MATERIAL_MAX_TEXTURES) vSize[i].TexSize = BURNING_MATERIAL_MAX_TEXTURES; @@ -1441,18 +1975,22 @@ void CBurningVideoDriver::VertexCache_map_source_format() } } - VertexCache.mem.resize(VERTEXCACHE_ELEMENT * 2); - VertexCache.vType = E4VT_STANDARD; + VertexShader.mem.resize(VERTEXCACHE_ELEMENT * 2); + VertexShader.vType = E4VT_STANDARD; Clipper.resize(VERTEXCACHE_ELEMENT * 2); - Clipper_temp.resize(VERTEXCACHE_ELEMENT * 2); + Clipper_disjoint.resize(VERTEXCACHE_ELEMENT * 2); - TransformationStack = 0; + TransformationStack = ETF_STACK_3D; memset(TransformationFlag, 0, sizeof(TransformationFlag)); memset(Transformation_ETS_CLIPSCALE, 0, sizeof(Transformation_ETS_CLIPSCALE)); Material.resetRenderStates = true; Material.Fallback_MaterialType = EMT_SOLID; + Material.VertexShader = BVT_Fix; + + PushShader.CurrentShader = 0; + PushShader.EdgeTestPass = 0; } @@ -1463,35 +2001,244 @@ void CBurningVideoDriver::VertexCache_map_source_format() */ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex) { - u8* burning_restrict source; + const u8* burning_restrict source; s4DVertex* burning_restrict dest; - source = (u8*)VertexCache.vertices + (sourceIndex * VertexCache.vSize[VertexCache.vType].Pitch); + source = (u8*)VertexShader.vertices + (sourceIndex * VertexShader.vSize[VertexShader.vType].Pitch); // it's a look ahead so we never hit it.. // but give priority... - //VertexCache.info[ destIndex ].hit = hitCount; + //VertexShader.info[ destIndex ].hit = hitCount; // store info - VertexCache.info[destIndex].index = sourceIndex; - VertexCache.info[destIndex].hit = 0; + VertexShader.info[destIndex].index = sourceIndex; + VertexShader.info[destIndex].hit = 0; // destination Vertex - dest = VertexCache.mem.data + s4DVertex_ofs(destIndex); + dest = VertexShader.mem.data + s4DVertex_ofs(destIndex); + dest->reset_interpolate(); //Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents const S3DVertex* base = ((S3DVertex*)source); - - // transform Model * World * Camera * Projection * NDCSpace matrix const core::matrix4* matrix = Transformation[TransformationStack]; - matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, base->Pos); + + if (Material.VertexShader == BVT_Fix) goto fftransform; + + { + IBurningShader* shader = (u32)Material.org.MaterialType < MaterialRenderers.size() ? + (IBurningShader*)MaterialRenderers[Material.org.MaterialType].Renderer : CurrentShader; + + // Vertex program attribute inputs: + sVec4 gl_Vertex(base->Pos.X, base->Pos.Y, base->Pos.Z, 1.f); + sVec4 gl_Normal(base->Normal.X, base->Normal.Y, base->Normal.Z, 1.f); + sVec4 gl_Color; gl_Color.setA8R8G8B8(base->Color.color); + + // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address! + sVec4 gl_MultiTexCoord0(base->TCoords.X, base->TCoords.Y, 1.f, 1.f); + sVec4 gl_MultiTexCoord1(((S3DVertex2TCoords*)source)->TCoords2.X, ((S3DVertex2TCoords*)source)->TCoords2.Y, 1.f, 1.f); + +#define gl_Position dest->Pos +#define gl_TexCoord dest->Tex +#define gl_FrontColor dest->Color[0] +#define gl_BackColor dest->Color[1] +#define vec2 sVec2 +#define vec3 sVec4 +#define vec4 sVec4 +#define mat4 core::matrix4 +#define gl_NormalMatrix matrix[ETS_NORMAL] +#define gl_ModelViewMatrix matrix[ETS_MODEL_VIEW] +#define gl_ModelViewProjectionMatrix matrix[ETS_MODEL_VIEW_PROJ] +#define ftransform() (matrix[ETS_MODEL_VIEW_PROJ] * gl_Vertex) + + //#define uniform(var,name) const var& name = shader->uniform_##var(#name) + //#define varying(var,name) var name = shader->varying_##var(#name) + +#define uniform(var,name) const var& name = (const var&)*shader->getUniform(#name,BL_VERTEX_FLOAT) +#define varying(var,name) var& name = (var&)*shader->getUniform(#name,BL_FRAGMENT_FLOAT) + +#ifdef _MSC_VER +#pragma warning (disable: 4244) // float/double conversion +#pragma warning (disable: 4305) // truncation +#endif + //init for default pixelshader + gl_FrontColor = gl_Color; + + //gl_FrontColor.setA8R8G8B8(gl_Color); + if (Material.VertexShader == BVT_815_0x1f847599) + { + //varying(vec2,TexCoords); + gl_Position = gl_Vertex; + + // TexCoords = (gl_Vertex.xy * 0.5 + 0.5); + gl_TexCoord[0].x = gl_Vertex.x * 0.5f + 0.5f; + gl_TexCoord[0].y = gl_Vertex.y * -0.5f + 0.5f; // runtime flip + } + else if (Material.VertexShader == BVT_opengl_vsh_shaderexample) + { + uniform(mat4, mWorldViewProj); + uniform(mat4, mInvWorld); + uniform(mat4, mTransWorld); + uniform(vec3, mLightPos); // actually just camera-pos in this case + uniform(vec4, mLightColor); + + gl_Position = mWorldViewProj * gl_Vertex; + + // transform normal somehow (NOTE: for the real vertex normal you would use an inverse-transpose world matrix instead of mInvWorld) + vec4 normal = vec4(gl_Normal, 0.0); + normal = mInvWorld * normal; + normal = normalize(normal); + + // (NOTE: not sure why transposed world is used instead of world?) + vec4 worldpos = gl_Vertex * mTransWorld; + + vec4 lightVector = worldpos - vec4(mLightPos, 1.0); + lightVector = normalize(lightVector); + + float tmp2 = dot(-lightVector, normal); + + sVec4 tmp = mLightColor * tmp2; + gl_FrontColor = gl_BackColor = vec4(tmp.x, tmp.y, tmp.z, 0.0); + + gl_TexCoord[0] = gl_MultiTexCoord0; + + gl_FrontColor.clampf01(); + } + else if (Material.VertexShader == STK_1259_0xc8226e1a) + { + // Creates a bubble (wave) effect by distorting the texture depending on time + + uniform(float, time); + varying(vec2, uv); + + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = ftransform(); + + float delta_x = cos(time * 3.0) * sin(4.0 * gl_TexCoord[0].st.s * 6.28318531); + float delta_y = cos(time * 2.0) * sin(3.0 * gl_TexCoord[0].st.t * 6.28318531); + + uv = gl_TexCoord[0].st_op() + vec2(0.02 * delta_x, 0.02 * delta_y); + + //fragment + uniform(float, transparency); + gl_TexCoord[0] = uv; + gl_FrontColor.a *= transparency; + + } + else if (Material.VertexShader == STK_958_0xa048973b) + { + // motion_blur.vert + gl_TexCoord[0].st_op() = vec2(gl_MultiTexCoord0.s, gl_MultiTexCoord0.t); + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = gl_Vertex; + } + else if (Material.VertexShader == STK_1309_0x1fd689c2) + { + varying(vec3, lightVec); + varying(vec3, halfVec); + varying(vec3, eyeVec); + + uniform(vec3, lightdir); + + gl_TexCoord[0] = gl_MultiTexCoord0; + + // Building the matrix Eye Space -> Tangent Space + vec3 n = normalize(gl_NormalMatrix * gl_Normal); + vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz()); // tangent + vec3 b = cross(n, t); + + vec3 vertexPosition = vec3(gl_ModelViewMatrix * gl_Vertex); + + // transform light and half angle vectors by tangent basis + vec3 v; + v.x = dot(lightdir, t); + v.y = dot(lightdir, b); + v.z = dot(lightdir, n); + lightVec = normalize(v); + + v.x = dot(vertexPosition, t); + v.y = dot(vertexPosition, b); + v.z = dot(vertexPosition, n); + eyeVec = normalize(v); + + vertexPosition = normalize(vertexPosition); + + // Normalize the halfVector to pass it to the fragment shader + + // No need to divide by two, the result is normalized anyway. + // vec3 halfVector = normalize((vertexPosition + lightDir) / 2.0); + vec3 halfVector = normalize(vertexPosition + lightdir); + v.x = dot(halfVector, t); + v.y = dot(halfVector, b); + v.z = dot(halfVector, n); + + // No need to normalize, t,b,n and halfVector are normal vectors. + //normalize (v); + halfVec = v; + + + gl_Position = ftransform(); + } + else if (Material.VertexShader == STK_1204_0x072a4094) + { + varying(vec3, normal); + varying(vec4, vertex_color); + varying(vec3, lightdir2); + uniform(vec3, lightdir); + + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[1] = gl_MultiTexCoord1; + gl_Position = ftransform(); + vertex_color = gl_Color; + + //normal = normalize(gl_NormalMatrix * gl_Normal); + normal = normalize(gl_Normal); + lightdir2 = normalize(lightdir); + } + +#ifdef _MSC_VER +#pragma warning (default: 4244) // conversion +#pragma warning (default: 4305) // truncation +#endif + +#undef vec2 +#undef vec3 +#undef vec4 +#undef mat4 +#undef uniform +#undef varying +#undef gl_TexCoord +#undef gl_FrontColor +#undef gl_BackColor +#undef ftransform +#undef gl_NormalMatrix +#undef gl_ModelViewMatrix +#undef gl_ModelViewProjectionMatrix + + goto clipandproject; + } + +fftransform: + // transform Model * World * Camera * Projection * NDCSpace matrix + matrix[ETS_MODEL_VIEW_PROJ].transformVect(&dest[0].Pos.x, base->Pos); + +/* + ieee754* p = (ieee754*) &dest[0].Pos.x; + p[0].fields.frac &= 0xFFFFFFF0; + p[1].fields.frac &= 0xFFFFFFF0; + p[2].fields.frac &= 0xFFFFFFF0; + //p[3].fields.frac &= 0xFFFFFFF0; +*/ + //dest[0].Pos.x = floorf(dest[0].Pos.x * 4096.f + 0.5f) * (1.f / 4096.f); + //dest[0].Pos.y = floorf(dest[0].Pos.y * 4096.f + 0.5f) * (1.f / 4096.f); + //dest[0].Pos.z = floorf(dest[0].Pos.z * 4096.f + 0.5f) * (1.f / 4096.f); + //dest[0].Pos.w = floorf(dest[0].Pos.w * 4096.f + 0.5f) * (1.f / 4096.f); //mhm ... maybe no goto - if (VertexCache.vType == E4VT_SHADOW) + if (VertexShader.vType == E4VT_SHADOW) { //core::vector3df i = base->Pos; //i.Z -= 0.5f; - //matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, i); + //matrix[ETS_MODEL_VIEW_PROJ].transformVect(&dest->Pos.x, i); //GL_DEPTH_CLAMP,EVDF_DEPTH_CLAMP //if ( dest->Pos.z < dest->Pos.w) @@ -1510,61 +2257,45 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest #if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM ) // vertex, normal in light(eye) space - if (Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG))) + if (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG | TL_LIGHT)) { sVec4 vertex4; //eye coordinate position of vertex matrix[ETS_MODEL_VIEW].transformVect(&vertex4.x, base->Pos); - const f32 iw = reciprocal_zero(vertex4.w); + f32 iw = reciprocal_zero_pos_underflow(vertex4.w); EyeSpace.vertex.x = vertex4.x * iw; EyeSpace.vertex.y = vertex4.y * iw; EyeSpace.vertex.z = vertex4.z * iw; EyeSpace.vertex.w = iw; //EyeSpace.cam_distance = EyeSpace.vertex.length_xyz(); - EyeSpace.cam_dir = EyeSpace.vertex; - EyeSpace.cam_dir.normalize_dir_xyz(); +/* + if ( GL_LIGHT_MODEL_LOCAL_VIEWER == 0 ) + { + EyeSpace.cam_dir.x = 0.f; + EyeSpace.cam_dir.y = 0.f; + EyeSpace.cam_dir.z = 1.f; + } +*/ + EyeSpace.vertexn = EyeSpace.vertex; + EyeSpace.vertexn.normalize_dir_xyz(); - matrix[ETS_NORMAL].rotateVect(&EyeSpace.normal.x, base->Normal); + //matrix[ETS_NORMAL].rotateVect(&EyeSpace.normal.x, base->Normal); + rotateMat33Vec3Vec4(matrix[ETS_NORMAL], &EyeSpace.normal.x, &base->Normal.X); if (EyeSpace.TL_Flag & TL_NORMALIZE_NORMALS) - EyeSpace.normal.normalize_dir_xyz(); + { + EyeSpace.normal.normalize_dir_xyz_zero(); + } } #endif -#if BURNING_MATERIAL_MAX_COLORS > 1 - dest->Color[1].a = 1.f; - dest->Color[1].r = 0.f; - dest->Color[1].g = 0.f; - dest->Color[1].b = 0.f; -#endif - -#if BURNING_MATERIAL_MAX_COLORS > 2 - dest->Color[2].a = 1.f; - dest->Color[2].r = 0.f; - dest->Color[2].g = 0.f; - dest->Color[2].b = 0.f; -#endif - -#if BURNING_MATERIAL_MAX_COLORS > 3 - dest->Color[3].a = 1.f; - dest->Color[3].r = 0.f; - dest->Color[3].g = 0.f; - dest->Color[3].b = 0.f; -#endif - -#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0 - dest->LightTangent[0].x = 0.f; - dest->LightTangent[0].y = 0.f; - dest->LightTangent[0].z = 0.f; -#endif - #if BURNING_MATERIAL_MAX_COLORS > 0 // apply lighting model #if defined (SOFTWARE_DRIVER_2_LIGHTING) - if (Material.org.Lighting) + if (EyeSpace.TL_Flag & TL_LIGHT) { lightVertex_eye(dest, base->Color.color); } @@ -1600,25 +2331,23 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest break; } - sVec4* a = dest->Color + ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG) ? 1 : 0); + sVec4* a = dest->Color + ((VertexShader.vSize[VertexShader.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG) ? 1 : 0); a->a = clampf01(fog_factor); } - // Texture Coo Transform - // Always set all internal uv (v1.9 SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM always on) - for (size_t t = 0; t < BURNING_MATERIAL_MAX_TEXTURES; ++t) + // Texture Coo Generation and Transform + for (u32 m = 0; m < VertexShader.vSize[VertexShader.vType].TexSize; ++m) { sVec4 r; f32 tx, ty; // texgen - const size_t flag = TransformationFlag[TransformationStack][ETS_TEXTURE_0 + t]; + const size_t& flag = TransformationFlag[TransformationStack][ETS_TEXTURE_0 + m]; if (flag & ETF_TEXGEN_CAMERA_SPHERE) { //reflect(u,N) u - 2.0 * dot(N, u) * N - // cam is (0,0,-1), tex flipped - const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized + const sVec4& u = EyeSpace.vertexn; // EyeSpace.vertex.normalized const sVec4& n = EyeSpace.normal; f32 dot = -2.f * n.dot_xyz(u); @@ -1629,7 +2358,8 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest //openGL f32 m = 2.f * sqrtf(r.x * r.x + r.y * r.y + (r.z + 1.f) * (r.z + 1.f)); tx = r.x / m + 0.5f; - ty = -r.y / m + 0.5f; + ty = -(r.y / m + 0.5f); // tex flipped + /* //~d3d with spheremap scale @@ -1641,33 +2371,28 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest else if (flag & ETF_TEXGEN_CAMERA_REFLECTION) { //reflect(u,N) u - 2.0 * dot(N, u) * N - // cam is (0,0,-1), tex flipped - const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized + const sVec4& u = EyeSpace.vertexn; // EyeSpace.vertex.normalized const sVec4& n = EyeSpace.normal; f32 dot = -2.f * n.dot_xyz(u); - r.x = u.x + dot * n.x; - r.y = u.y + dot * n.y; - r.z = u.z + dot * n.z; //openGL - tx = r.x; - ty = -r.y; - /* - //~d3d with spheremap scale - dest[0].Tex[t].x = r.x; - dest[0].Tex[t].y = r.y; - */ + tx = /*r.x =*/ u.x + dot * n.x; + ty = /*r.y =*/ u.y + dot * n.y; + //r.z = u.z + dot * n.z; + + //~d3d with spheremap transform + //tx = r.x * 0.5f + 0.5f; + //ty = r.y * -0.5f + 0.5f; } - else - if (t < VertexCache.vSize[VertexCache.vType].TexCooSize) + else if (m < VertexShader.vSize[VertexShader.vType].TexCooSize) { // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address! const sVec2Pack* baseTCoord = (const sVec2Pack*)&base->TCoords.X; - tx = baseTCoord[t].x; - ty = baseTCoord[t].y; + tx = baseTCoord[m].x; + ty = baseTCoord[m].y; } else { @@ -1675,8 +2400,16 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest ty = 0.f; } - //transform - if (!(flag & ETF_IDENTITY)) +#if 0 + static const CSoftwareTexture2_Bound empty_bound = { 0.f,0.f,0.f,0.f,0 }; + + const video::CSoftwareTexture2* tex = MAT_TEXTURE(t); + const CSoftwareTexture2_Bound& texb = tex ? tex->getTexBound_index()[0] : empty_bound; + const bool filter = Material.org.TextureLayer[t].BilinearFilter; +#endif + + //Texture Matrix Transform + if (flag & ETF_TEXGEN_MATRIX) // !(flag & ETF_IDENTITY) { /* Generate texture coordinates as linear functions so that: @@ -1689,7 +2422,7 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest Uw Vw 0 0 */ - const f32* M = matrix[ETS_TEXTURE_0 + t].pointer(); + const f32* M = matrix[ETS_TEXTURE_0 + m].pointer(); f32 _tx = tx; f32 _ty = ty; @@ -1697,9 +2430,12 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest ty = M[1] * _tx + M[5] * _ty + M[9]; } - switch (Material.org.TextureLayer[t].TextureWrapU) + switch (Material.org.TextureLayer[m].TextureWrapU) { case ETC_CLAMP: + tx = clampf01(tx); + break; + case ETC_CLAMP_TO_EDGE: case ETC_CLAMP_TO_BORDER: tx = clampf01(tx); @@ -1720,11 +2456,17 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest default: break; } - switch (Material.org.TextureLayer[t].TextureWrapV) + switch (Material.org.TextureLayer[m].TextureWrapV) { case ETC_CLAMP: + ty = clampf01(ty); + break; case ETC_CLAMP_TO_EDGE: case ETC_CLAMP_TO_BORDER: + //if (ty < 0.f) ty = 0.f; + //else if (ty > texb.pixelclampy) ty = texb.pixelclampy; + + //ty = clampfuv(ty, filter ? texb.pixelclampy : 0.f); ty = clampf01(ty); break; case ETC_MIRROR: @@ -1744,14 +2486,14 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest break; } - dest->Tex[t].x = tx; - dest->Tex[t].y = ty; + dest->Tex[m].x = tx; + dest->Tex[m].y = ty; } #if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0 if ((EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) && - ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_TANGENT) == VERTEX4D_FORMAT_BUMP_DOT3) + ((VertexShader.vSize[VertexShader.vType].Format & VERTEX4D_FORMAT_MASK_TANGENT) == VERTEX4D_FORMAT_BUMP_DOT3) ) { const S3DVertexTangents* tangent = ((S3DVertexTangents*)source); @@ -1791,7 +2533,7 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest dest->Tex[1].y = dest->Tex[0].y; } - else if (Material.org.Lighting) + else if (EyeSpace.TL_Flag & TL_LIGHT) { //dest->LightTangent[0].x = 0.f; //dest->LightTangent[0].y = 0.f; @@ -1799,34 +2541,197 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest } #endif //if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0 -//#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM + //#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM clipandproject: - // test vertex visible - dest[0].flag = (u32)(clipToFrustumTest(dest) | VertexCache.vSize[VertexCache.vType].Format); - dest[1].flag = dest[0].flag; + // test vertex visibility + const u32 flag = clipToFrustumTest(dest) | VertexShader.vSize[VertexShader.vType].Format; + + dest[s4DVertex_ofs(0)].flag = + dest[s4DVertex_pro(0)].flag = flag; // to DC Space, project homogenous vertex - if ((dest[0].flag & VERTEX4D_CLIPMASK) == VERTEX4D_INSIDE) + if ((flag & VERTEX4D_CLIPMASK) == VERTEX4D_INSIDE) { - ndc_2_dc_and_project(dest + s4DVertex_proj(0), dest + s4DVertex_ofs(0), s4DVertex_ofs(1)); + ndc_2_dc_and_project(dest, s4DVertex_ofs(1), Transformation_ETS_CLIPSCALE[TransformationStack]); } } - +#if 0 //todo: this should return only index s4DVertexPair* CBurningVideoDriver::VertexCache_getVertex(const u32 sourceIndex) const { for (size_t i = 0; i < VERTEXCACHE_ELEMENT; ++i) { - if (VertexCache.info[i].index == sourceIndex) + if (VertexShader.info[i].index == sourceIndex) { - return VertexCache.mem.data + s4DVertex_ofs(i); + return VertexShader.mem.data + s4DVertex_ofs(i); + } + } + return VertexShader.mem.data; //error +} +#endif + + +void SVertexShader::setIndices(const void* _indices, const video::E_INDEX_TYPE _iType) +{ + indices = _indices; + indicesIndex = 0; + indicesRun = 0; + + switch (_iType) + { + case EIT_16BIT: iType = E4IT_16BIT; break; + case EIT_32BIT: iType = E4IT_32BIT; break; + default: iType = (e4DIndexType)iType; break; + } + if (!indices) + iType = E4IT_NONE; +} + +void SVertexShader::setPrimitiveType(const scene::E_PRIMITIVE_TYPE primitiveType, const u32 primitiveCount) +{ + pType = primitiveType; + primitiveHasVertex = 3; + indicesPitch = 1; + + switch (pType) + { + default: + case scene::EPT_POINTS: + case scene::EPT_POINT_SPRITES: + indexCount = primitiveCount; + indicesPitch = 1; + primitiveHasVertex = 1; + break; + + case scene::EPT_LINE_STRIP: + case scene::EPT_LINE_LOOP: + indexCount = primitiveCount + 1; + indicesPitch = 1; + primitiveHasVertex = 2; + break; + case scene::EPT_LINES: + indexCount = 2 * primitiveCount; + indicesPitch = 2; + primitiveHasVertex = 2; + break; + case scene::EPT_TRIANGLE_STRIP: + indexCount = primitiveCount + 2; + indicesPitch = 1; + primitiveHasVertex = 3; + break; + case scene::EPT_TRIANGLES: + indexCount = primitiveCount + primitiveCount + primitiveCount; + indicesPitch = 3; + primitiveHasVertex = 3; + break; + case scene::EPT_TRIANGLE_FAN: + indexCount = primitiveCount + 2; + indicesPitch = 1; + primitiveHasVertex = 3; + break; + case scene::EPT_POLYGON: + indexCount = primitiveCount; + indicesPitch = 1; + primitiveHasVertex = 3; // drawn a triangle fan + break; + + case scene::EPT_QUAD_STRIP: + indexCount = 2 * primitiveCount + 2; + indicesPitch = 2; + primitiveHasVertex = 4; + break; + case scene::EPT_QUADS: + indexCount = 4 * primitiveCount; + indicesPitch = 4; + primitiveHasVertex = 4; + //draw two triangles.. + break; + } +} + +void SVertexShader::set_info_miss() +{ + //memset(info, VERTEXCACHE_MISS, sizeof(info)); + for (size_t i = 0; i != VERTEXCACHE_ELEMENT; ++i) + { + info[i].hit = VERTEXCACHE_MISS; + info[i].index = VERTEXCACHE_MISS; + } +} + +// get the next unique index cache line +void SVertexShader::get_next_index_cacheline() +{ + u32 i; + + // cache element 0 + switch (pType) + { + case scene::EPT_POLYGON: + case scene::EPT_TRIANGLE_FAN: + fillIndex = indicesRun ? 1 : 0; + break; + default: + fillIndex = 0; + break; + } + + // set_info_temp_miss + for (i = fillIndex; i != VERTEXCACHE_ELEMENT; ++i) + { + info_temp[i].hit = VERTEXCACHE_MISS; + info_temp[i].index = VERTEXCACHE_MISS; + } + + // rewind to start of primitive + indicesIndex = indicesRun; + + while (indicesIndex < indexCount && fillIndex < VERTEXCACHE_ELEMENT) + { + u32 sourceIndex = index(indicesIndex); + indicesIndex += 1; + + // if not exist, push back + u32 exist = 0; + for (u32 dIndex = 0; dIndex < fillIndex; ++dIndex) + { + if (info_temp[dIndex].index == sourceIndex) + { + exist = 1; + break; + } + } + + if (0 == exist) + { + info_temp[fillIndex].index = sourceIndex; + fillIndex += 1; + } + } + + // clear marks + for (i = 0; i != VERTEXCACHE_ELEMENT; ++i) + { + info[i].hit = 0; + } + + // mark all existing + for (i = 0; i != fillIndex; ++i) + { + for (u32 dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex) + { + if (info[dIndex].index == info_temp[i].index) + { + info_temp[i].hit = dIndex; + info[dIndex].hit = 1; + break; + } } } - return VertexCache.mem.data; //error } @@ -1835,143 +2740,129 @@ s4DVertexPair* CBurningVideoDriver::VertexCache_getVertex(const u32 sourceIndex) fill blockwise on the next 16(Cache_Size) unique vertices in indexlist merge the next 16 vertices with the current */ -void CBurningVideoDriver::VertexCache_get(s4DVertexPair* face[4]) +void SVertexShader::getPrimitive(s4DVertexPair* face[4], CBurningVideoDriver* driver) { // next primitive must be complete in cache - if (VertexCache.indicesIndex - VertexCache.indicesRun < VertexCache.primitiveHasVertex && - VertexCache.indicesIndex < VertexCache.indexCount - ) + if (indicesIndex - indicesRun < primitiveHasVertex && indicesIndex < indexCount) { - - size_t i; - //memset(info, VERTEXCACHE_MISS, sizeof(info)); - for (i = 0; i != VERTEXCACHE_ELEMENT; ++i) - { - VertexCache.info_temp[i].hit = VERTEXCACHE_MISS; - VertexCache.info_temp[i].index = VERTEXCACHE_MISS; - } - - // rewind to start of primitive - VertexCache.indicesIndex = VertexCache.indicesRun; - - - // get the next unique vertices cache line - u32 fillIndex = 0; - u32 dIndex = 0; - u32 sourceIndex = 0; - - while (VertexCache.indicesIndex < VertexCache.indexCount && - fillIndex < VERTEXCACHE_ELEMENT - ) - { - switch (VertexCache.iType) - { - case E4IT_16BIT: - sourceIndex = ((u16*)VertexCache.indices)[VertexCache.indicesIndex]; - break; - case E4IT_32BIT: - sourceIndex = ((u32*)VertexCache.indices)[VertexCache.indicesIndex]; - break; - default: - case E4IT_NONE: - sourceIndex = VertexCache.indicesIndex; - break; - } - - VertexCache.indicesIndex += 1; - - // if not exist, push back - s32 exist = 0; - for (dIndex = 0; dIndex < fillIndex; ++dIndex) - { - if (VertexCache.info_temp[dIndex].index == sourceIndex) - { - exist = 1; - break; - } - } - - if (0 == exist) - { - VertexCache.info_temp[fillIndex++].index = sourceIndex; - } - } - - // clear marks - for (i = 0; i != VERTEXCACHE_ELEMENT; ++i) - { - VertexCache.info[i].hit = 0; - } - - // mark all existing - for (i = 0; i != fillIndex; ++i) - { - for (dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex) - { - if (VertexCache.info[dIndex].index == VertexCache.info_temp[i].index) - { - VertexCache.info_temp[i].hit = dIndex; - VertexCache.info[dIndex].hit = 1; - break; - } - } - } + // get the next unique indices cache line + get_next_index_cacheline(); // fill new - for (i = 0; i != fillIndex; ++i) + for (u32 i = 0; i != fillIndex; ++i) { - if (VertexCache.info_temp[i].hit != VERTEXCACHE_MISS) + if (info_temp[i].hit != VERTEXCACHE_MISS) continue; - for (dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex) + for (u32 dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex) { - if (0 == VertexCache.info[dIndex].hit) + if (0 == info[dIndex].hit) { - VertexCache_fill(VertexCache.info_temp[i].index, dIndex); - VertexCache.info[dIndex].hit += 1; - VertexCache.info_temp[i].hit = dIndex; + driver->VertexCache_fill(info_temp[i].index, dIndex); + info[dIndex].hit += 1; + info_temp[i].hit = dIndex; break; } } } } - //const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun ); - const u32 i0 = VertexCache.pType != scene::EPT_TRIANGLE_FAN ? VertexCache.indicesRun : 0; + // all primitive indices are in the index cache line + switch (pType) + { + case scene::EPT_POLYGON: + case scene::EPT_TRIANGLE_FAN: + face[0] = vertex(index(0)); + face[1] = vertex(index(indicesRun + 1)); + face[2] = vertex(index(indicesRun + 2)); + break; + case scene::EPT_TRIANGLE_STRIP: + face[0] = vertex(index(indicesRun + 0)); + face[(primitiveRun & 1) ? 2 : 1] = vertex(index(indicesRun + 1)); + face[(primitiveRun & 1) ? 1 : 2] = vertex(index(indicesRun + 2)); + break; + default: + for (u32 i = 0; i < primitiveHasVertex; ++i) + { + face[i] = vertex(index(indicesRun + i)); + } + break; + } + indicesRun += indicesPitch; +} - switch (VertexCache.iType) +#if 0 +void CBurningVideoDriver::VertexCache_get(s4DVertexPair* face[4]) +{ + // next primitive must be complete in cache + if (VertexShader.indicesIndex - VertexShader.indicesRun < VertexShader.primitiveHasVertex && + VertexShader.indicesIndex < VertexShader.indexCount + ) + { + // get the next unique vertices cache line + VertexShader.get_next_info(); + + // mark all existing + VertexShader.mark_existing(); + + // fill new + for (u32 i = 0; i != VertexShader.fillIndex; ++i) + { + if (VertexShader.info_temp[i].hit != VERTEXCACHE_MISS) + continue; + + for (u32 dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex) + { + if (0 == VertexShader.info[dIndex].hit) + { + VertexCache_fill(VertexShader.info_temp[i].index, dIndex); + VertexShader.info[dIndex].hit += 1; + VertexShader.info_temp[i].hit = dIndex; + break; + } + } + } + } + + VertexShader.getPrimitive(face); +#if 0 + //const u32 i0 = core::if_c_a_else_0 ( VertexShader.pType != scene::EPT_TRIANGLE_FAN, VertexShader.indicesRun ); + const u32 i0 = VertexShader.pType != scene::EPT_TRIANGLE_FAN ? VertexShader.indicesRun : 0; + + switch (VertexShader.iType) { case E4IT_16BIT: { - const u16* p = (const u16*)VertexCache.indices; + const u16* p = (const u16*)VertexShader.indices; face[0] = VertexCache_getVertex(p[i0]); - face[1] = VertexCache_getVertex(p[VertexCache.indicesRun + 1]); - face[2] = VertexCache_getVertex(p[VertexCache.indicesRun + 2]); + face[1] = VertexCache_getVertex(p[VertexShader.indicesRun + 1]); + face[2] = VertexCache_getVertex(p[VertexShader.indicesRun + 2]); } break; case E4IT_32BIT: { - const u32* p = (const u32*)VertexCache.indices; + const u32* p = (const u32*)VertexShader.indices; face[0] = VertexCache_getVertex(p[i0]); - face[1] = VertexCache_getVertex(p[VertexCache.indicesRun + 1]); - face[2] = VertexCache_getVertex(p[VertexCache.indicesRun + 2]); + face[1] = VertexCache_getVertex(p[VertexShader.indicesRun + 1]); + face[2] = VertexCache_getVertex(p[VertexShader.indicesRun + 2]); } break; case E4IT_NONE: - face[0] = VertexCache_getVertex(VertexCache.indicesRun + 0); - face[1] = VertexCache_getVertex(VertexCache.indicesRun + 1); - face[2] = VertexCache_getVertex(VertexCache.indicesRun + 2); + face[0] = VertexCache_getVertex(VertexShader.indicesRun + 0); + face[1] = VertexCache_getVertex(VertexShader.indicesRun + 1); + face[2] = VertexCache_getVertex(VertexShader.indicesRun + 2); break; default: - face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0); + face[0] = face[1] = face[2] = VertexCache_getVertex(VertexShader.indicesRun + 0); break; } face[3] = face[0]; // quad unsupported - VertexCache.indicesRun += VertexCache.indicesPitch; + VertexShader.indicesRun += VertexShader.indicesPitch; +#endif } - +#endif /*! */ @@ -1982,130 +2873,47 @@ int CBurningVideoDriver::VertexCache_reset(const void* vertices, u32 vertexCount E_INDEX_TYPE iType) { - // These calls would lead to crashes due to wrong index usage. - // The vertex cache needs to be rewritten for these primitives. - if (0 == CurrentShader || - pType == scene::EPT_POINTS || pType == scene::EPT_LINE_STRIP || - pType == scene::EPT_LINE_LOOP || pType == scene::EPT_LINES || - pType == scene::EPT_POLYGON || - pType == scene::EPT_POINT_SPRITES) + if (0 == CurrentShader) { return 1; } - VertexCache.vertices = vertices; - VertexCache.vertexCount = vertexCount; + VertexShader.vertices = vertices; + VertexShader.vertexCount = vertexCount; switch (Material.org.MaterialType) // (Material.Fallback_MaterialType) { case EMT_REFLECTION_2_LAYER: case EMT_TRANSPARENT_REFLECTION_2_LAYER: - VertexCache.vType = E4VT_REFLECTION_MAP; + VertexShader.vType = vType == EVT_STANDARD ? E4VT_REFLECTION_MAP : (e4DVertexType)vType; break; default: - VertexCache.vType = (e4DVertexType)vType; + VertexShader.vType = (e4DVertexType)vType; break; } - //check material - SVSize* vSize = VertexCache.vSize; - for (int m = (int)vSize[VertexCache.vType].TexSize - 1; m >= 0; --m) + //check material material->OnRender(VertexType) + SVSize* vSize = VertexShader.vSize; + for (int m = (int)vSize[VertexShader.vType].TexSize - 1; m >= 0; --m) { - ITexture* tex = MAT_TEXTURE(m); + const ITexture* tex = MAT_TEXTURE(m); if (!tex) { - vSize[E4VT_NO_TEXTURE] = vSize[VertexCache.vType]; + //vSize[E4VT_NO_TEXTURE] = vSize[VertexShader.vType]; + vSize[E4VT_NO_TEXTURE].Format = (vSize[VertexShader.vType].Format & ~VERTEX4D_FORMAT_MASK_COLOR) | VERTEX4D_FORMAT_COLOR_1; + vSize[E4VT_NO_TEXTURE].Pitch = vSize[VertexShader.vType].Pitch; vSize[E4VT_NO_TEXTURE].TexSize = m; vSize[E4VT_NO_TEXTURE].TexCooSize = m; - VertexCache.vType = E4VT_NO_TEXTURE; + + VertexShader.vType = E4VT_NO_TEXTURE; //flags downconvert? } } - VertexCache.indices = indices; - VertexCache.indicesIndex = 0; - VertexCache.indicesRun = 0; + VertexShader.setIndices(indices, iType); + VertexShader.setPrimitiveType(pType, primitiveCount); - switch (iType) - { - case EIT_16BIT: VertexCache.iType = E4IT_16BIT; break; - case EIT_32BIT: VertexCache.iType = E4IT_32BIT; break; - default: - VertexCache.iType = (e4DIndexType)iType; break; - } - if (!VertexCache.indices) - VertexCache.iType = E4IT_NONE; - - VertexCache.pType = pType; - VertexCache.primitiveHasVertex = 3; - VertexCache.indicesPitch = 1; - switch (VertexCache.pType) - { - // most types here will not work as expected, only triangles/triangle_fan - // is known to work. - case scene::EPT_POINTS: - VertexCache.indexCount = primitiveCount; - VertexCache.indicesPitch = 1; - VertexCache.primitiveHasVertex = 1; - break; - case scene::EPT_LINE_STRIP: - VertexCache.indexCount = primitiveCount + 1; - VertexCache.indicesPitch = 1; - VertexCache.primitiveHasVertex = 2; - break; - case scene::EPT_LINE_LOOP: - VertexCache.indexCount = primitiveCount + 1; - VertexCache.indicesPitch = 1; - VertexCache.primitiveHasVertex = 2; - break; - case scene::EPT_LINES: - VertexCache.indexCount = 2 * primitiveCount; - VertexCache.indicesPitch = 2; - VertexCache.primitiveHasVertex = 2; - break; - case scene::EPT_TRIANGLE_STRIP: - VertexCache.indexCount = primitiveCount + 2; - VertexCache.indicesPitch = 1; - VertexCache.primitiveHasVertex = 3; - break; - case scene::EPT_TRIANGLES: - VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount; - VertexCache.indicesPitch = 3; - VertexCache.primitiveHasVertex = 3; - break; - case scene::EPT_TRIANGLE_FAN: - VertexCache.indexCount = primitiveCount + 2; - VertexCache.indicesPitch = 1; - VertexCache.primitiveHasVertex = 3; - break; - case scene::EPT_QUAD_STRIP: - VertexCache.indexCount = 2 * primitiveCount + 2; - VertexCache.indicesPitch = 2; - VertexCache.primitiveHasVertex = 4; - break; - case scene::EPT_QUADS: - VertexCache.indexCount = 4 * primitiveCount; - VertexCache.indicesPitch = 4; - VertexCache.primitiveHasVertex = 4; - break; - case scene::EPT_POLYGON: - VertexCache.indexCount = primitiveCount + 1; - VertexCache.indicesPitch = 1; - VertexCache.primitiveHasVertex = primitiveCount; - break; - case scene::EPT_POINT_SPRITES: - VertexCache.indexCount = primitiveCount; - VertexCache.indicesPitch = 1; - VertexCache.primitiveHasVertex = 1; - break; - } - - //memset( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) ); - for (size_t i = 0; i != VERTEXCACHE_ELEMENT; ++i) - { - VertexCache.info[i].hit = VERTEXCACHE_MISS; - VertexCache.info[i].index = VERTEXCACHE_MISS; - } + VertexShader.set_info_miss(); return 0; } @@ -2124,14 +2932,17 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert if (VertexCache_reset(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType)) return; - if ((u32)Material.org.MaterialType < MaterialRenderers.size()) - { - MaterialRenderers[Material.org.MaterialType].Renderer->OnRender(this, vType); - } - + pushShader(pType, 1); + /* + if ((u32)Material.org.MaterialType < MaterialRenderers.size()) + { + MaterialRenderers[Material.org.MaterialType].Renderer->OnRender(this, vType); + } + */ //Matrices needed for this primitive - transform_calc(ETS_PROJ_MODEL_VIEW); - if (Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG))) + transform_calc(ETS_MODEL_VIEW_PROJ); + if ((EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG | TL_LIGHT)) || + Material.VertexShader != BVT_Fix) { transform_calc(ETS_MODEL_VIEW); transform_calc(ETS_NORMAL); @@ -2140,14 +2951,18 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert s4DVertexPair* face[4]; - size_t vOut; - size_t vertex_from_clipper; // from VertexCache or CurrentOut - size_t has_vertex_run; + u32 vOut; + u32 vertex_from_clipper; // from VertexShader or CurrentOut + u32 has_vertex_run; - for (size_t primitive_run = 0; primitive_run < primitiveCount; ++primitive_run) + // magnitude crossproduct (area of parallelogram * 0.5 = triangle screen size, winding) + ieee754 dc_area; + + CurrentShader->fragment_draw_count = 0; + for (VertexShader.primitiveRun = 0; VertexShader.primitiveRun < primitiveCount; ++VertexShader.primitiveRun) { //collect pointer to face vertices - VertexCache_get(face); + VertexShader.getPrimitive(face, this); size_t clipMask_i; size_t clipMask_o; @@ -2155,7 +2970,7 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert clipMask_i = face[0]->flag; clipMask_o = face[0]->flag; - for (has_vertex_run = 1; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run) + for (has_vertex_run = 1; has_vertex_run < VertexShader.primitiveHasVertex; ++has_vertex_run) { clipMask_i |= face[has_vertex_run]->flag; // if fully outside or outside on same side clipMask_o &= face[has_vertex_run]->flag; // if fully inside @@ -2174,24 +2989,32 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert else if (clipMask_o == VERTEX4D_INSIDE) { // if primitive fully inside - vOut = VertexCache.primitiveHasVertex; + vOut = VertexShader.primitiveHasVertex; vertex_from_clipper = 0; } else #if defined(SOFTWARE_DRIVER_2_CLIPPING) { // else if not complete inside clipping necessary - // check: clipping should reuse vertexcache (try to minimize clipping) - for (has_vertex_run = 0; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run) + + // todo: clipping should reuse vertexcache (try to minimize clipping) + for (has_vertex_run = 0; has_vertex_run < VertexShader.primitiveHasVertex; ++has_vertex_run) { memcpy_s4DVertexPair(Clipper.data + s4DVertex_ofs(has_vertex_run), face[has_vertex_run]); } - vOut = clipToFrustum(VertexCache.primitiveHasVertex); + //clipping should happen in R^3 before perspective divide, avoid flipping points + //x = A_x * (1 - da/(da - db)) + A_y * (da/(da-db)) + vOut = clipToFrustum(VertexShader.primitiveHasVertex); vertex_from_clipper = 1; + // to DC Space, project homogenous vertex - ndc_2_dc_and_project(Clipper.data + s4DVertex_proj(0), Clipper.data + s4DVertex_ofs(0), s4DVertex_ofs(vOut)); + if (vOut > VertexShader.primitiveHasVertex ) + ndc_2_dc_and_project_grid(Clipper.data, s4DVertex_ofs(vOut), Transformation_ETS_CLIPSCALE[TransformationStack]); + else + ndc_2_dc_and_project(Clipper.data, s4DVertex_ofs(vOut), Transformation_ETS_CLIPSCALE[TransformationStack]); + } #else { @@ -2200,84 +3023,228 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert vertex_from_clipper = 0; } #endif - // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. ) - for (has_vertex_run = 0; (has_vertex_run + VertexCache.primitiveHasVertex) <= vOut; has_vertex_run += 1) + +#if BURNING_MATERIAL_MAX_TEXTURES > 0 + s32 lod_max[BURNING_MATERIAL_MAX_TEXTURES]; + for (u32 m = 0; m < VertexShader.vSize[VertexShader.vType].TexSize; ++m) { - // set from clipped geometry - if (vertex_from_clipper) - { - face[0] = Clipper.data + s4DVertex_ofs(0); - face[1] = Clipper.data + s4DVertex_ofs(has_vertex_run + 1); - face[2] = Clipper.data + s4DVertex_ofs(has_vertex_run + 2); - } - - //area of primitive in device space - // projected triangle screen area is used for culling ( sign of normal ) and mipmap selection - //f32 dc_area = screenarea_inside(face); - - // crossproduct (area of parallelogram * 0.5 = triangle screen size) - f32 dc_area; - { - const sVec4& v0 = (face[0] + s4DVertex_proj(0))->Pos; - const sVec4& v1 = (face[1] + s4DVertex_proj(0))->Pos; - const sVec4& v2 = (face[2] + s4DVertex_proj(0))->Pos; - - //dc_area = a.x * b.y - b.x * a.y; - dc_area = ((v1.x - v0.x) * (v2.y - v0.y) - (v2.x - v0.x) * (v1.y - v0.y)) * 0.5f; - } - - //geometric clipping has problem with invisible or very small Triangles - //size_t sign = dc_area < 0.001f ? CULL_BACK : dc_area > 0.001f ? CULL_FRONT : CULL_INVISIBLE; - ieee754 t; - t.f = dc_area; - size_t sign = t.fields.sign ? CULL_BACK : CULL_FRONT; - sign |= t.abs.frac_exp < 981668463 /*0.01f*/ ? CULL_INVISIBLE : 0; - if (Material.CullFlag & sign) - break; //continue; - - //select mipmap ratio between drawing space and texture space (for multiply divide here) - dc_area = reciprocal_zero(dc_area); - - // select mipmap - for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m) - { - video::CSoftwareTexture2* tex = MAT_TEXTURE(m); - - //only guessing: take more detail (lower mipmap) in light+bump textures - f32 lod_bias = 0.100f;// core::clamp(map_value((f32)ScreenSize.Width * ScreenSize.Height, 160 * 120, 640 * 480, 1.f / 8.f, 1.f / 8.f), 0.01f, 1.f); - - //assume transparent add is ~50% transparent -> more detail - switch (Material.org.MaterialType) - { - case EMT_TRANSPARENT_ADD_COLOR: - case EMT_TRANSPARENT_ALPHA_CHANNEL: - lod_bias *= 0.5f; - break; - default: - break; - } - lod_bias *= tex->get_lod_bias(); - //lod_bias += Material.org.TextureLayer[m].LODBias * 0.125f; - - s32 lodFactor = lodFactor_inside(face, m, dc_area, lod_bias); - - CurrentShader->setTextureParam(m, tex, lodFactor); - //currently shader receives texture coordinate as Pixelcoo of 1 Texture - select_polygon_mipmap_inside(face, m, tex->getTexBound()); - } - - CurrentShader->drawWireFrameTriangle(face[0] + s4DVertex_proj(0), face[1] + s4DVertex_proj(0), face[2] + s4DVertex_proj(0)); - vertex_from_clipper = 1; + lod_max[m] = 0; } +#endif + + f32 t[4]; + + +#define BURNING_MAX_MIP_CLIPPER 1 + +#if BURNING_MAX_MIP_CLIPPER == 1 + //select largest texture for clipped triangle + //very small long triangles are very undersampled here ("skybox flicker") + int use_max_mip = vertex_from_clipper && VertexShader.vSize[VertexShader.vType].TexSize && + vOut > VertexShader.primitiveHasVertex ? 1 : 0; + + for (int probe = use_max_mip; probe >= 0; probe -= 1) +#endif + { + // re-tesselate + for (has_vertex_run = 0; (has_vertex_run + VertexShader.primitiveHasVertex) <= vOut; has_vertex_run += 1) + { + // set from clipped geometry ( triangle fan 0-1-2,0-2-3.. ) + if (vertex_from_clipper) + { + face[0] = Clipper.data + s4DVertex_ofs(0); + face[1] = Clipper.data + s4DVertex_ofs(has_vertex_run + 1); + face[2] = Clipper.data + s4DVertex_ofs(has_vertex_run + 2); + face[3] = Clipper.data + s4DVertex_ofs(has_vertex_run + 3); + } + + //area of primitive in device space + // projected triangle screen area is used for culling ( sign of normal ) and mipmap selection + //f32 dc_area = screenarea_inside(face); + + // magnitude crossproduct + dc_area.f = 1.f; + if (VertexShader.primitiveHasVertex >= 3) + { + const sVec4& v0 = (face[0] + s4DVertex_pro(0))->Pos; + const sVec4& v1 = (face[1] + s4DVertex_pro(0))->Pos; + const sVec4& v2 = (face[2] + s4DVertex_pro(0))->Pos; + + //dc_area = 2d triangle normal.crossproduct (a.x * b.y - b.x * a.y).length/2; + dc_area.f = ((v1.x - v0.x) * (v2.y - v0.y) - (v2.x - v0.x) * (v1.y - v0.y)) /* * 0.5f */; + + //geometric clipping has problem with invisible or very small Triangles + //size_t sign = dc_area < 0.001f ? CULL_BACK : dc_area > 0.001f ? CULL_FRONT : CULL_INVISIBLE; + + size_t sign = dc_area.fields.sign ? CULL_BACK : CULL_FRONT; + sign |= dc_area.abs.frac_exp < CULL_EPSILON_00001 ? CULL_INVISIBLE : 0; + + if (Material.CullFlag & sign) + continue; //not break; per clipper triangle + + + // mipmap2 +#if 1 + // select mipmap +#if BURNING_MAX_MIP_CLIPPER == 1 + if (probe == use_max_mip) +#endif + for (u32 m = 0; m < VertexShader.vSize[VertexShader.vType].TexSize; ++m) + { + video::CSoftwareTexture2* tex = MAT_TEXTURE(m); + + const sVec2& v0 = (face[0] + s4DVertex_ofs(0))->Tex[m]; + const sVec2& v1 = (face[1] + s4DVertex_ofs(0))->Tex[m]; + const sVec2& v2 = (face[2] + s4DVertex_ofs(0))->Tex[m]; + + //todo: get triangle setup here + //bbox + t[0] = t[2] = v0.x; + t[1] = t[3] = v0.y; + if (v1.x < t[0]) t[0] = v1.x; + if (v1.y < t[1]) t[1] = v1.y; + if (v1.x > t[2]) t[2] = v1.x; + if (v1.y > t[3]) t[3] = v1.y; + + if (v2.x < t[0]) t[0] = v2.x; + if (v2.y < t[1]) t[1] = v2.y; + if (v2.x > t[2]) t[2] = v2.x; + if (v2.y > t[3]) t[3] = v2.y; + + f32 tex_area = fabsf((t[2] - t[0]) * (t[3] - t[1])); + + //tex_area = |a.x * b.y - b.x * a.y| * 0.5; // crossproduct + //f32 tex_area = fabsf((v1.x - v0.x) * (v2.y - v0.y) - (v2.x - v0.x) * (v1.y - v0.y)); + + //various over and underflow cases + if (tex_area <= 0.000001f) + tex_area = 0.000001f; + else if (tex_area > 1.01f) + tex_area = 1.f / tex_area; + + /* 2.f * tex_area * 1.6f bias. 1.6 too much for detailsmap3 */ + //not dc_area * 0.5 cancel out 2 * TexBias + const u32 dc_area_over_tex_area = (u32)floorf( /*/tex_area > 0.0000001f ? */ + fabsf(dc_area.f) * TexBias[TransformationStack] / tex_area + /*: 0.f*/ + ); + + // get a near 1:1 ratio between pixel and texel + // tex_area * b[lodFactor].w * b[lodFactor].h > dc_area_abs + + s32 lodFactor = 0; + const CSoftwareTexture2_Bound* b = tex->getTexBound_index(); + while (lodFactor < SOFTWARE_DRIVER_2_MIPMAPPING_MAX && + b[lodFactor].area > dc_area_over_tex_area + ) + { + lodFactor += 1; + } + + //clipped triangle should take single area based mipmap from unclipped face + //skybox,billboard test case + //if (vertex_from_clipper) lodFactor -= 1; + if (has_vertex_run == 0) lod_max[m] = lodFactor; + else if (lodFactor < lod_max[m]) lod_max[m] = lodFactor; + + //CurrentShader->setTextureParam(m, tex, lodFactor); + //select_polygon_mipmap_inside(face, m, tex->getTexBound()); + } + +#else + //select mipmap ratio between drawing space and texture space (for multiply divide here) + dc_area.f = reciprocal_zero(dc_area.f); + + // select mipmap + for (u32 m = 0; m < VertexShader.vSize[VertexShader.vType].TexSize; ++m) + { + video::CSoftwareTexture2* tex = MAT_TEXTURE(m); + + //only guessing: take more detail (lower mipmap) in light+bump textures + f32 lod_bias = 0.100f;// core::clamp(map_value((f32)ScreenSize.Width * ScreenSize.Height, 160 * 120, 640 * 480, 1.f / 8.f, 1.f / 8.f), 0.01f, 1.f); + + //assume transparent add is ~50% transparent -> more detail + switch (Material.org.MaterialType) + { + case EMT_TRANSPARENT_ADD_COLOR: + case EMT_TRANSPARENT_ALPHA_CHANNEL: + lod_bias *= 0.5f; + break; + default: + break; + } + lod_bias *= tex->get_lod_bias(); + //lod_bias += Material.org.TextureLayer[m].LODBias * 0.125f; + + s32 lodFactor = lodFactor_inside(face, m, dc_area.f, lod_bias); + + CurrentShader->setTextureParam(m, tex, lodFactor); + //currently shader receives texture coordinate as Pixelcoo of 1 Texture + select_polygon_mipmap_inside(face, m, tex->getTexBound()); + } +#endif + } + //else /* if (VertexShader.primitiveHasVertex == 3) */ +#if BURNING_MAX_MIP_CLIPPER == 1 + if (probe > 0) + continue; +#endif + // set single mipmap + for (u32 m = 0; m < VertexShader.vSize[VertexShader.vType].TexSize; ++m) + { + video::CSoftwareTexture2* tex = MAT_TEXTURE(m); + CurrentShader->setTextureParam(m, tex, lod_max[m]); + + //select_polygon_mipmap_inside(face, m, tex->getTexBound()); + //currently shader receives texture coordinate as Pixelcoo of 1 Texture + const CSoftwareTexture2_Bound& b = tex->getTexBound(); + for (u32 v = 0; v < VertexShader.primitiveHasVertex; ++v) + { + const sVec2& src = (face[v] + s4DVertex_ofs(0))->Tex[m]; + sVec2& dst = (face[v] + s4DVertex_pro(0))->Tex[m]; + +#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT + const f32 iw = (face[v] + s4DVertex_pro(0))->Pos.w; + dst.x = src.x * iw * b.mat[0] + b.mat[1]; + dst.y = src.y * iw * b.mat[2] + b.mat[3]; +#else + dst.x = src.x * b.mat[0] + b.mat[1]; + dst.y = src.y * b.mat[2] + b.mat[3]; +#endif + } + } + + switch (VertexShader.primitiveHasVertex) + { + case 1: + CurrentShader->drawPoint(face[0] + s4DVertex_pro(0)); + break; + case 2: + CurrentShader->drawLine(face[0] + s4DVertex_pro(0), face[1] + s4DVertex_pro(0)); + break; + case 3: + CurrentShader->drawWireFrameTriangle(face[0] + s4DVertex_pro(0), face[1] + s4DVertex_pro(0), face[2] + s4DVertex_pro(0)); + break; + case 4: + //todo: + CurrentShader->drawWireFrameTriangle(face[0] + s4DVertex_pro(0), face[1] + s4DVertex_pro(0), face[2] + s4DVertex_pro(0)); + CurrentShader->drawWireFrameTriangle(face[0] + s4DVertex_pro(0), face[2] + s4DVertex_pro(0), face[3] + s4DVertex_pro(0)); + break; + } + + //vertex_from_clipper = 1; + } + } // probe } + this->samples_passed += CurrentShader->fragment_draw_count; + //release texture - for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m) + for (u32 m = 0; m < VertexShader.vSize[VertexShader.vType].TexSize; ++m) { CurrentShader->setTextureParam(m, 0, 0); } - } @@ -2290,12 +3257,8 @@ void CBurningVideoDriver::setAmbientLight(const SColorf& color) } -//! adds a dynamic light -s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) +void CBurningVideoDriver::assignHardwareLight(SBurningShaderLight& l, const SLight& dl) { - (void)CNullDriver::addDynamicLight(dl); - - SBurningShaderLight l; // l.org = dl; l.Type = dl.Type; l.LightIsOn = true; @@ -2311,22 +3274,21 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) nDirection.z = dl.Direction.Z; nDirection.normalize_dir_xyz(); - switch (dl.Type) { case ELT_DIRECTIONAL: - l.pos.x = dl.Position.X; - l.pos.y = dl.Position.Y; - l.pos.z = dl.Position.Z; + l.pos.x = -nDirection.x; + l.pos.y = -nDirection.y; + l.pos.z = -nDirection.z; l.pos.w = 0.f; l.constantAttenuation = 1.f; l.linearAttenuation = 0.f; l.quadraticAttenuation = 0.f; - l.spotDirection.x = -nDirection.x; - l.spotDirection.y = -nDirection.y; - l.spotDirection.z = -nDirection.z; + l.spotDirection.x = 0.f; + l.spotDirection.y = 0.f; + l.spotDirection.z = -1.f; l.spotDirection.w = 0.f; l.spotCosCutoff = -1.f; l.spotCosInnerCutoff = 1.f; @@ -2343,9 +3305,9 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) l.linearAttenuation = dl.Attenuation.Y; l.quadraticAttenuation = dl.Attenuation.Z; - l.spotDirection.x = -nDirection.x; - l.spotDirection.y = -nDirection.y; - l.spotDirection.z = -nDirection.z; + l.spotDirection.x = 0.f; + l.spotDirection.y = 0.f; + l.spotDirection.z = -1.f; l.spotDirection.w = 0.f; l.spotCosCutoff = -1.f; l.spotCosInnerCutoff = 1.f; @@ -2374,16 +3336,46 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) break; } - //which means ETS_VIEW + //which means ETS_VIEW, irrlicht openGL setTransform(ETS_WORLD, irr::core::IdentityMatrix); transform_calc(ETS_MODEL_VIEW); + //transform_calc(ETS_NORMAL); const core::matrix4* matrix = Transformation[TransformationStack]; transformVec4Vec4(matrix[ETS_MODEL_VIEW], &l.pos4.x, &l.pos.x); - rotateVec3Vec4(matrix[ETS_MODEL_VIEW], &l.spotDirection4.x, &l.spotDirection.x); + rotateMat44Vec3Vec4(matrix[ETS_MODEL_VIEW], &l.spotDirection4.x, &l.spotDirection.x); + + /* + //case ELT_DIRECTIONAL: + if (l.pos.w == 0.f) + { + l.pos4n = l.pos4; + l.pos4n.normalize_dir_xyz(); + + //GL_LIGHT_MODEL_LOCAL_VIEWER = 0 + + l.halfVector = l.pos4n; + l.halfVector.z += 1.f; + l.halfVector.normalize_dir_xyz(); + + } +*/ +} + +//! adds a dynamic light +s32 CBurningVideoDriver::addDynamicLight(const SLight& dl) +{ + s32 i0 = CNullDriver::addDynamicLight(dl); + + SBurningShaderLight l; EyeSpace.Light.push_back(l); - return EyeSpace.Light.size() - 1; + s32 i1 = EyeSpace.Light.size() - 1; + + //i0 and i1 must be in sync + assignHardwareLight(EyeSpace.Light[i1], dl); + + return i1; } @@ -2392,14 +3384,20 @@ void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn) { if ((u32)lightIndex < EyeSpace.Light.size()) { - EyeSpace.Light[lightIndex].LightIsOn = turnOn; + SBurningShaderLight& l = EyeSpace.Light[lightIndex]; + // some glitches with STK, always set, currently twice. openGL forces ModelMatrix to Identity + if (!l.LightIsOn && turnOn) + { + assignHardwareLight(l, CNullDriver::getDynamicLight(lightIndex)); + } + l.LightIsOn = turnOn; } } //! deletes all dynamic lights there are void CBurningVideoDriver::deleteAllDynamicLights() { - EyeSpace.reset(); + EyeSpace.deleteAllDynamicLights(); CNullDriver::deleteAllDynamicLights(); } @@ -2411,6 +3409,16 @@ u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const } +// a != b +size_t compare_3d_material(const SMaterial& a, const SMaterial& b) +{ + size_t flag = 0; + flag |= a.MaterialType == b.MaterialType ? 0 : 1; + flag |= a.TextureLayer[0].Texture == b.TextureLayer[0].Texture ? 0 : 4; + if (flag) return flag; + return a != b; +} + //! sets a material void CBurningVideoDriver::setMaterial(const SMaterial& material) { @@ -2420,21 +3428,29 @@ void CBurningVideoDriver::setMaterial(const SMaterial& material) const SMaterial& in = Material.org; - // ---------- Notify Shader + //basically set always. 2d does its own compare + //if (TransformationStack == ETF_STACK_2D || Material.resetRenderStates || compare_3d_material(Material.lastMaterial,in)) + { + // ---------- Notify Shader // unset old material - u32 mi; - mi = (u32)Material.lastMaterial.MaterialType; - if (mi != material.MaterialType && mi < MaterialRenderers.size()) - MaterialRenderers[mi].Renderer->OnUnsetMaterial(); + u32 shaderid_old = (u32)Material.lastMaterial.MaterialType; + u32 shaderid = (u32)in.MaterialType; - // set new material. - mi = (u32)in.MaterialType; - if (mi < MaterialRenderers.size()) - MaterialRenderers[mi].Renderer->OnSetMaterial( - in, Material.lastMaterial, Material.resetRenderStates, this); + if (shaderid != shaderid_old && shaderid_old < MaterialRenderers.size()) + { + MaterialRenderers[shaderid_old].Renderer->OnUnsetMaterial(); + } - Material.lastMaterial = in; - Material.resetRenderStates = false; + // set new material. + if (shaderid < MaterialRenderers.size()) + { + MaterialRenderers[shaderid].Renderer->OnSetMaterial( + in, Material.lastMaterial, Material.resetRenderStates, this); + } + + Material.lastMaterial = in; + Material.resetRenderStates = false; + } //CSoftware2MaterialRenderer sets Material.Fallback_MaterialType @@ -2447,30 +3463,39 @@ void CBurningVideoDriver::setMaterial(const SMaterial& material) size_t* flag = TransformationFlag[TransformationStack]; + EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP); + #ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM - for (u32 m = 0; m < BURNING_MATERIAL_MAX_TEXTURES /*&& m < vSize[VertexCache.vType].TexSize*/; ++m) + for (u32 m = 0; m < VertexShader.vSize[VertexShader.vType].TexSize; ++m) { - setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + m), in.getTextureMatrix(m)); flag[ETS_TEXTURE_0 + m] &= ~ETF_TEXGEN_MASK; + setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + m), in.getTextureMatrix(m)); } #endif #ifdef SOFTWARE_DRIVER_2_LIGHTING - Material.AmbientColor.setA8R8G8B8(in.AmbientColor.color); - Material.DiffuseColor.setA8R8G8B8(in.ColorMaterial ? 0xFFFFFFFF : in.DiffuseColor.color); - Material.EmissiveColor.setA8R8G8B8(in.EmissiveColor.color); - Material.SpecularColor.setA8R8G8B8(in.SpecularColor.color); - - burning_setbit(EyeSpace.TL_Flag, in.Lighting, TL_LIGHT); - burning_setbit(EyeSpace.TL_Flag, (in.Shininess != 0.f) && (in.SpecularColor.color & 0x00ffffff), TL_SPECULAR); burning_setbit(EyeSpace.TL_Flag, in.FogEnable, TL_FOG); burning_setbit(EyeSpace.TL_Flag, in.NormalizeNormals, TL_NORMALIZE_NORMALS); - //if (EyeSpace.Flags & SPECULAR ) EyeSpace.Flags |= NORMALIZE_NORMALS; + + burning_setbit(EyeSpace.TL_Flag, in.Lighting, TL_LIGHT); + if (EyeSpace.TL_Flag & TL_LIGHT) + { + burning_setbit(EyeSpace.TL_Flag, in.ColorMaterial == ECM_AMBIENT || in.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT, TL_COLORMAT_AMBIENT); + burning_setbit(EyeSpace.TL_Flag, in.ColorMaterial == ECM_DIFFUSE || in.ColorMaterial == ECM_DIFFUSE_AND_AMBIENT, TL_COLORMAT_DIFFUSE); + burning_setbit(EyeSpace.TL_Flag, in.ColorMaterial == ECM_SPECULAR, TL_COLORMAT_SPECULAR); + + Material.AmbientColor.setA8R8G8B8(in.AmbientColor.color); + Material.DiffuseColor.setA8R8G8B8(in.DiffuseColor.color); + Material.EmissiveColor.setA8R8G8B8(in.EmissiveColor.color); + Material.SpecularColor.setA8R8G8B8(in.SpecularColor.color); + + burning_setbit(EyeSpace.TL_Flag, (in.Shininess != 0.f) && (in.SpecularColor.color & 0x00ffffff), TL_SPECULAR); + } #endif -//--------------- setCurrentShader + //--------------- setCurrentShader ITexture* texture0 = in.getTexture(0); ITexture* texture1 = in.getTexture(1); @@ -2484,7 +3509,6 @@ void CBurningVideoDriver::setMaterial(const SMaterial& material) //if (maxTex < 3) texture2 = 0; //if (maxTex < 4) texture3 = 0; - EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP); //todo: seperate depth test from depth write Material.depth_write = getWriteZBuffer(in); @@ -2516,6 +3540,8 @@ void CBurningVideoDriver::setMaterial(const SMaterial& material) case EMT_TRANSPARENT_ADD_COLOR: shader = Material.depth_test ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z; + if (Material.org.BlendOperation == EBO_ADD) + shader = ETR_TEXTURE_GOURAUD_ADD_NO_Z; break; case EMT_TRANSPARENT_VERTEX_ALPHA: @@ -2630,15 +3656,16 @@ void CBurningVideoDriver::setMaterial(const SMaterial& material) if (EyeSpace.TL_Flag & TL_SCISSOR) CurrentShader->setScissor(Scissor); CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced); CurrentShader->OnSetMaterial(Material); - CurrentShader->pushEdgeTest(in.Wireframe, in.PointCloud, 0); + CurrentShader->setEdgeTest(in.Wireframe, in.PointCloud); } - /* - mi = (u32)Material.org.MaterialType; - if (mi < MaterialRenderers.size()) - MaterialRenderers[mi].Renderer->OnRender(this, (video::E_VERTEX_TYPE)VertexCache.vType); - */ + { + u32 shaderid = (u32)Material.org.MaterialType; + if (shaderid < MaterialRenderers.size()) + MaterialRenderers[shaderid].Renderer->OnRender(this, (video::E_VERTEX_TYPE)VertexShader.vType); + } + } @@ -2659,7 +3686,8 @@ void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start, /*! applies lighting model */ -void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) + +void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, const u32 vertexargb) { //gl_FrontLightModelProduct.sceneColor = gl_FrontMaterial.emission + gl_FrontMaterial.ambient * gl_LightModel.ambient @@ -2667,9 +3695,8 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) sVec3Color diffuse; sVec3Color specular; - // the universe started in darkness.. - ambient = EyeSpace.Global_AmbientLight; + ambient.set(0.f); diffuse.set(0.f); specular.set(0.f); @@ -2678,7 +3705,7 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) f32 dot; f32 distance; f32 attenuation; - sVec4 vp; // unit vector vertex to light + sVec4 vp; // vertex to light sVec4 lightHalf; // blinn-phong reflection f32 spotDot; // cos of angle between spotlight and point on surface @@ -2689,19 +3716,41 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) if (!light.LightIsOn) continue; - switch (light.Type) + switch (light.Type | (EyeSpace.TL_Flag & TL_SPECULAR)) { case ELT_DIRECTIONAL: + case ELT_DIRECTIONAL | TL_SPECULAR: + // surface to light vp = light.pos4n = light.pos4 - //angle between normal and light vector - dot = EyeSpace.normal.dot_xyz(light.spotDirection4); + // attenuation = 1 + // distance = 1 // accumulate ambient ambient.add_rgb(light.AmbientColor); - // diffuse component - if (dot > 0.f) - diffuse.mad_rgb(light.DiffuseColor, dot); + //angle between normal and light vector + dot = EyeSpace.normal.dot_xyz(light.pos4); + if (dot <= 0.f) continue; + + diffuse.mad_rgb(light.DiffuseColor, dot); + + if (!(EyeSpace.TL_Flag & TL_SPECULAR)) + continue; + + //light.halfvector + lightHalf.x = light.pos4.x - EyeSpace.vertexn.x; // + 0.f; + lightHalf.y = light.pos4.y - EyeSpace.vertexn.y; // + 0.f; + lightHalf.z = light.pos4.z - EyeSpace.vertexn.z; // + 1.f; + //lightHalf.normalize_dir_xyz(); + + dot = EyeSpace.normal.dot_xyz(lightHalf); + if (dot <= 0.f) continue; + + distance = lightHalf.length_xyz(); + distance = reciprocal_zero(distance); + + specular.mad_rgb(light.SpecularColor, powf_limit(dot * distance, Material.org.Shininess)); + break; case ELT_POINT: @@ -2711,10 +3760,9 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) vp.z = light.pos4.z - EyeSpace.vertex.z; distance = vp.length_xyz(); - attenuation = light.constantAttenuation - + light.linearAttenuation * distance - + light.quadraticAttenuation * (distance * distance); + + distance * (light.linearAttenuation + light.quadraticAttenuation * distance); + attenuation = reciprocal_one(attenuation); //att = clamp(1.0 - dist/radius, 0.0, 1.0); att *= att @@ -2725,28 +3773,60 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) // build diffuse reflection //angle between normal and light vector - vp.mul_xyz(reciprocal_zero(distance)); //normalize + //vp.mul_xyz(reciprocal_zero(distance)); //normalize dot = EyeSpace.normal.dot_xyz(vp); if (dot <= 0.f) continue; + distance = reciprocal_zero(distance); + // diffuse component - diffuse.mad_rgb(light.DiffuseColor, dot * attenuation); + diffuse.mad_rgb(light.DiffuseColor, (dot * distance) * attenuation); + break; - if (!(EyeSpace.TL_Flag & TL_SPECULAR)) - continue; + case ELT_POINT | TL_SPECULAR: + // surface to light + vp.x = light.pos4.x - EyeSpace.vertex.x; + vp.y = light.pos4.y - EyeSpace.vertex.y; + vp.z = light.pos4.z - EyeSpace.vertex.z; - lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x; - lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y; - lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z; - lightHalf.normalize_dir_xyz(); + distance = vp.length_xyz(); + attenuation = light.constantAttenuation + + distance * (light.linearAttenuation + light.quadraticAttenuation * distance); + attenuation = reciprocal_one(attenuation); + + // accumulate ambient + ambient.mad_rgb(light.AmbientColor, attenuation); + + // build diffuse reflection + dot = EyeSpace.normal.dot_xyz(vp); + if (dot <= 0.f) continue; + + distance = reciprocal_zero(distance); + + // diffuse component + diffuse.mad_rgb(light.DiffuseColor, (dot * distance) * attenuation); + + //vp.mul_xyz(distance); //normalize + + //halfVector = normalize(VP + eye), GL_LIGHT_MODEL_LOCAL_VIEWER + lightHalf.x = vp.x * distance - EyeSpace.vertexn.x; // + 0.f; + lightHalf.y = vp.y * distance - EyeSpace.vertexn.y; // + 0.f; + lightHalf.z = vp.z * distance - EyeSpace.vertexn.z; // + 1.f; + + //lightHalf.normalize_dir_xyz(); + dot = EyeSpace.normal.dot_xyz(lightHalf); + if (dot <= 0.f) continue; + + distance = lightHalf.length_xyz(); + dot *= reciprocal_zero(distance); //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation - specular.mad_rgb(light.SpecularColor, - powf_limit(EyeSpace.normal.dot_xyz(lightHalf), Material.org.Shininess) * attenuation - ); + specular.mad_rgb(light.SpecularColor, powf_limit(dot, Material.org.Shininess) * attenuation); + break; case ELT_SPOT: + case ELT_SPOT | TL_SPECULAR: // surface to light vp.x = light.pos4.x - EyeSpace.vertex.x; vp.y = light.pos4.y - EyeSpace.vertex.y; @@ -2783,9 +3863,9 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) if (!(EyeSpace.TL_Flag & TL_SPECULAR)) continue; - lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x; - lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y; - lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z; + lightHalf.x = vp.x - EyeSpace.vertexn.x; // + 0.f; + lightHalf.y = vp.y - EyeSpace.vertexn.y; // + 0.f; + lightHalf.z = vp.z - EyeSpace.vertexn.z; // + 1.f; lightHalf.normalize_dir_xyz(); //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation @@ -2800,45 +3880,57 @@ void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb) } + sVec3Color vertexColor; + vertexColor.setA8R8G8B8(vertexargb); + // sum up lights + //If = Ia + Id + Is sVec3Color dColor; dColor.set(0.f); + + //Ia = gl_light_model_ambient* ambient_material + ambient_light * ambient_material + const sVec4& amb_mat = (EyeSpace.TL_Flag & TL_COLORMAT_AMBIENT) ? vertexColor : Material.AmbientColor; + dColor.mad_rgbv(EyeSpace.Global_AmbientLight, amb_mat); + dColor.mad_rgbv(ambient, amb_mat); + + //Id = diffuse_light * lambertTerm dot(N,L) * diffuse_material + dColor.mad_rgbv(diffuse, (EyeSpace.TL_Flag & TL_COLORMAT_DIFFUSE) ? vertexColor : Material.DiffuseColor); +#if 0 dColor.mad_rgbv(diffuse, Material.DiffuseColor); //diffuse * vertex color. //has to move to shader (for vertex color only this will fit [except clamping]) - sVec3Color c; - c.setA8R8G8B8(vertexargb); - dColor.r *= c.r; - dColor.g *= c.g; - dColor.b *= c.b; + dColor.r *= vertexColor.r; + dColor.g *= vertexColor.g; + dColor.b *= vertexColor.b; +#endif //separate specular + const sVec4& spec_mat = (EyeSpace.TL_Flag & TL_COLORMAT_SPECULAR) ? vertexColor : Material.SpecularColor; #if defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR) - if ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG)) + if ((VertexShader.vSize[VertexShader.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG)) { - specular.sat_xyz(dest->Color[1], Material.SpecularColor); + specular.sat_mul_xyz(dest->Color[1], spec_mat); + } + else if (!(EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) && + (VertexShader.vSize[VertexShader.vType].Format & VERTEX4D_FORMAT_MASK_LIGHT) + ) + { + specular.sat_mul_xyz(dest->LightTangent[0], spec_mat); } else - if (!(EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) && - (VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_LIGHT) - ) - { - specular.sat_xyz(dest->LightTangent[0], Material.SpecularColor); - } - else #endif - { - dColor.mad_rgbv(specular, Material.SpecularColor); - } + { + dColor.mad_rgbv(specular, spec_mat); + } - dColor.mad_rgbv(ambient, Material.AmbientColor); dColor.add_rgb(Material.EmissiveColor); + // https://www.ozone3d.net/tutorials/glsl_lighting_phong.php - dColor.sat(dest->Color[0], vertexargb); + dColor.sat_alpha_pass(dest->Color[0], vertexColor.a); } @@ -2869,7 +3961,7 @@ CImage* getImage(const video::ITexture* texture) draw2DImage with 4 color scales on destination and cliprect is scissor */ -static const u16 quad_triangle_indexList[6] = { 0,1,2,0,2,3 }; +static const u16 quad_triangle_indexList[6 + 2] = { 0,1,2,0,2,3, 3,3 }; #if defined(SOFTWARE_DRIVER_2_2D_AS_2D) @@ -2907,8 +3999,10 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core //! Draws a part of the texture into the rectangle. -void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect& destRect, - const core::rect& sourceRect, const core::rect* clipRect, +void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, + const core::rect& destRect, + const core::rect& sourceRect, + const core::rect* clipRect, const video::SColor* const colors, bool useAlphaChannelOfTexture) { if (texture) @@ -2924,7 +4018,8 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core (argb == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND) : BLITTER_TEXTURE; StretchBlit(op, RenderTargetSurface, clipRect, &destRect, - ((CSoftwareTexture2*)texture)->getImage(), &sourceRect, &texture->getOriginalSize(), argb); + ((CSoftwareTexture2*)texture)->getImage(), &sourceRect, &texture->getOriginalSize(), argb + ); } } @@ -2947,9 +4042,11 @@ void CBurningVideoDriver::draw2DRectangle(const core::rect& position, void CBurningVideoDriver::enableMaterial2D(bool enable) { CNullDriver::enableMaterial2D(enable); - burning_setbit(TransformationFlag[1][ETS_PROJECTION], 0, ETF_VALID); + //burning_setbit(TransformationFlag[1][ETS_PROJECTION], 0, ETF_VALID); } + +// a != b size_t compare_2d_material(const SMaterial& a, const SMaterial& b) { size_t flag = 0; @@ -2957,11 +4054,12 @@ size_t compare_2d_material(const SMaterial& a, const SMaterial& b) flag |= a.ZBuffer == b.ZBuffer ? 0 : 2; flag |= a.TextureLayer[0].Texture == b.TextureLayer[0].Texture ? 0 : 4; flag |= a.TextureLayer[0].BilinearFilter == b.TextureLayer[0].BilinearFilter ? 0 : 8; - flag |= a.MaterialTypeParam == b.MaterialTypeParam ? 0 : 16; + flag |= a.TextureLayer[0].TextureWrapU == b.TextureLayer[0].TextureWrapU ? 0 : 16; + flag |= a.MaterialTypeParam == b.MaterialTypeParam ? 0 : 32; if (flag) return flag; - flag |= a.TextureLayer[1].Texture == b.TextureLayer[1].Texture ? 0 : 32; - flag |= a.ZWriteEnable == b.ZWriteEnable ? 0 : 64; + flag |= a.TextureLayer[1].Texture == b.TextureLayer[1].Texture ? 0 : 64; + flag |= a.ZWriteEnable == b.ZWriteEnable ? 0 : 128; return flag; } @@ -2996,19 +4094,25 @@ void CBurningVideoDriver::setRenderStates2DMode(const video::SColor& color, cons Material.mat2D.setTexture(0, (video::ITexture*)texture); //used for text. so stay as sharp as possible (like HW Driver) - bool mip = false; + bool filter = false; const SMaterial& currentMaterial = (!OverrideMaterial2DEnabled) ? InitMaterial2D : OverrideMaterial2D; - mip = currentMaterial.TextureLayer[0].Texture && currentMaterial.TextureLayer[0].BilinearFilter; - Material.mat2D.setFlag(video::EMF_BILINEAR_FILTER, mip); + filter = texture && currentMaterial.TextureLayer[0].BilinearFilter; + Material.mat2D.setFlag(video::EMF_BILINEAR_FILTER, filter); + Material.mat2D.TextureLayer[0].TextureWrapU = currentMaterial.TextureLayer[0].TextureWrapU; + Material.mat2D.TextureLayer[0].TextureWrapV = currentMaterial.TextureLayer[0].TextureWrapV; + + //compare + size_t cmp_mat = compare_2d_material(Material.org, Material.mat2D); //switch to 2D Matrix Stack [ Material set Texture Matrix ] - TransformationStack = 1; + //if (TransformationStack != ETF_STACK_2D) cmp_mat |= 256; + TransformationStack = ETF_STACK_2D; //2D GUI Matrix - if (!(TransformationFlag[TransformationStack][ETS_PROJECTION] & ETF_VALID)) + if ((cmp_mat & 256) || !(TransformationFlag[TransformationStack][ETS_PROJECTION] & ETF_VALID)) { const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); core::matrix4 m(core::matrix4::EM4CONST_NOTHING); @@ -3019,20 +4123,26 @@ void CBurningVideoDriver::setRenderStates2DMode(const video::SColor& color, cons m.makeIdentity(); setTransform(ETS_WORLD, m); - if (mip) - m.setTranslation(core::vector3df(IRRLICHT_2D_TEXEL_OFFSET, IRRLICHT_2D_TEXEL_OFFSET, 0.0f)); + // pixel perfect + //if(filter) + //currently done in ndc to dc -0.5f + //m.setTranslation(core::vector3df(-0.5f, -0.5f, 0.0f)); + +#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) + m.setTranslation(core::vector3df(0.375f, 0.375f, 0.0f)); +#endif setTransform(ETS_VIEW, m); + cmp_mat |= 8; - //Tweak 2D Pixel Center for openGL compatibility (guessing) - //buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[TransformationStack], ViewPort, mip ? (IRRLICHT_2D_TEXEL_OFFSET) * 0.5f : 0.f); } //compare - if (compare_2d_material(Material.org, Material.mat2D)) + if (cmp_mat) { setMaterial(Material.mat2D); } + if (CurrentShader) { CurrentShader->setPrimitiveColor(color.color); @@ -3048,7 +4158,7 @@ void CBurningVideoDriver::setRenderStates3DMode() //setMaterial(Material.save3D); //switch to 3D Matrix Stack - TransformationStack = 0; + TransformationStack = ETF_STACK_3D; } //! draws a vertex primitive list in 2d @@ -3084,6 +4194,10 @@ void CBurningVideoDriver::draw2DVertexPrimitiveList(const void* vertices, u32 ve } +//wrapper if both enabled +#if defined(SOFTWARE_DRIVER_2_2D_AS_2D) && defined(SOFTWARE_DRIVER_2_2D_AS_3D) +#endif + //setup a quad #if defined(SOFTWARE_DRIVER_2_2D_AS_3D) @@ -3116,7 +4230,7 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core // ok, we've clipped everything. // now draw it. const core::dimension2d sourceSize(targetRect.getSize()); - const core::position2d sourcePos(sourceRect.UpperLeftCorner + (targetRect.UpperLeftCorner - destPos)); + core::position2d sourcePos(sourceRect.UpperLeftCorner + (targetRect.UpperLeftCorner - destPos)); const core::dimension2d& tex_orgsize = texture->getOriginalSize(); const f32 invW = 1.f / static_cast(tex_orgsize.Width); @@ -3127,7 +4241,6 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core (sourcePos.X + sourceSize.Width) * invW, (sourcePos.Y + sourceSize.Height) * invH); - Quad2DVertices[0].Color = color; Quad2DVertices[1].Color = color; Quad2DVertices[2].Color = color; @@ -3159,6 +4272,9 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core const core::rect& sourceRect, const core::rect* clipRect, const video::SColor* const colors, bool useAlphaChannelOfTexture) { + if (!texture) + return; + const core::dimension2d& st = texture->getOriginalSize(); const f32 invW = 1.f / static_cast(st.Width); const f32 invH = 1.f / static_cast(st.Height); @@ -3209,8 +4325,7 @@ void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core video::SColor alphaTest; alphaTest.color = useColor[0].color & useColor[0].color & useColor[0].color & useColor[0].color; - - setRenderStates2DMode(alphaTest,texture, useAlphaChannelOfTexture); + setRenderStates2DMode(alphaTest, texture, useAlphaChannelOfTexture); drawVertexPrimitiveList(Quad2DVertices, 4, quad_triangle_indexList, 2, @@ -3344,38 +4459,39 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start, { SColor color_end = color_start; - VertexCache.primitiveHasVertex = 2; - VertexCache.vType = E4VT_LINE; + VertexShader.primitiveHasVertex = 2; + VertexShader.vType = E4VT_LINE; s4DVertex* v = Clipper.data; - transform_calc(ETS_PROJ_MODEL_VIEW); + transform_calc(ETS_MODEL_VIEW_PROJ); const core::matrix4* matrix = Transformation[TransformationStack]; - matrix[ETS_PROJ_MODEL_VIEW].transformVect(&v[s4DVertex_ofs(0)].Pos.x, start); - matrix[ETS_PROJ_MODEL_VIEW].transformVect(&v[s4DVertex_ofs(1)].Pos.x, end); + matrix[ETS_MODEL_VIEW_PROJ].transformVect(&v[s4DVertex_ofs(0)].Pos.x, start); + matrix[ETS_MODEL_VIEW_PROJ].transformVect(&v[s4DVertex_ofs(1)].Pos.x, end); + + u32 has_vertex_run; + const u32 flag = (VertexShader.vSize[VertexShader.vType].Format); + for (has_vertex_run = 0; has_vertex_run < VertexShader.primitiveHasVertex; has_vertex_run += 1) + { + v[s4DVertex_ofs(has_vertex_run)].reset_interpolate(); + v[s4DVertex_ofs(has_vertex_run)].flag = flag; + v[s4DVertex_pro(has_vertex_run)].flag = flag; + } #if BURNING_MATERIAL_MAX_COLORS > 0 v[s4DVertex_ofs(0)].Color[0].setA8R8G8B8(color_start.color); v[s4DVertex_ofs(1)].Color[0].setA8R8G8B8(color_end.color); #endif - size_t has_vertex_run; - for (has_vertex_run = 0; has_vertex_run < VertexCache.primitiveHasVertex; has_vertex_run += 1) - { - v[s4DVertex_ofs(has_vertex_run)].flag = (u32)(VertexCache.vSize[VertexCache.vType].Format); - v[s4DVertex_proj(has_vertex_run)].flag = v[s4DVertex_ofs(has_vertex_run)].flag; - } - - - size_t vOut; + u32 vOut; // vertices count per line - vOut = clipToFrustum(VertexCache.primitiveHasVertex); - if (vOut < VertexCache.primitiveHasVertex) + vOut = clipToFrustum(VertexShader.primitiveHasVertex); + if (vOut < VertexShader.primitiveHasVertex) return; // to DC Space, project homogenous vertex - ndc_2_dc_and_project(v + s4DVertex_proj(0), v+ s4DVertex_ofs(0), s4DVertex_ofs(vOut)); + ndc_2_dc_and_project(v, s4DVertex_ofs(vOut), Transformation_ETS_CLIPSCALE[TransformationStack]); // unproject vertex color #if 0 @@ -3387,45 +4503,83 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start, #endif #endif - IBurningShader* shader = 0; - if (CurrentShader && CurrentShader->canWireFrame()) shader = CurrentShader; - else shader = BurningShader[ETR_TEXTURE_GOURAUD_WIRE]; - shader = BurningShader[ETR_TEXTURE_GOURAUD_WIRE]; - - shader->pushEdgeTest(1, 0, 1); - shader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced); - - for (has_vertex_run = 0; (has_vertex_run + VertexCache.primitiveHasVertex) <= vOut; has_vertex_run += 1) + pushShader(scene::EPT_LINES, 0); + for (has_vertex_run = 0; (has_vertex_run + VertexShader.primitiveHasVertex) <= vOut; has_vertex_run += 1) { - shader->drawLine(v + s4DVertex_proj(has_vertex_run), v + s4DVertex_proj(has_vertex_run+1)); + CurrentShader->drawLine(v + s4DVertex_pro(has_vertex_run), v + s4DVertex_pro(has_vertex_run + 1)); } - - shader->popEdgeTest(); - + PushShader.pop(); } +// set Shader Mode based on primitive type +void CBurningVideoDriver::pushShader(scene::E_PRIMITIVE_TYPE pType, int testCurrent) +{ + int wireFrame = 0; + int pointCloud = 0; + + switch (pType) + { + case scene::EPT_POINTS: + case scene::EPT_POINT_SPRITES: + pointCloud = 1; + break; + case scene::EPT_LINE_STRIP: + case scene::EPT_LINE_LOOP: + case scene::EPT_LINES: + wireFrame = 1; + break; + default: + return; + } + + IBurningShader* shader = 0; + if (wireFrame) + { + if (testCurrent && CurrentShader && CurrentShader->canWireFrame()) shader = CurrentShader; + else shader = BurningShader[ETR_TEXTURE_GOURAUD_WIRE]; + } + if (pointCloud) + { + if (testCurrent && CurrentShader && CurrentShader->canPointCloud()) shader = CurrentShader; + else shader = BurningShader[ETR_TEXTURE_GOURAUD_WIRE]; + } + + if (shader) + { + if (shader != CurrentShader) + { + PushShader.push(CurrentShader); + CurrentShader = shader; + shader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced); + shader->OnSetMaterial(Material); + } + shader->setEdgeTest(wireFrame, pointCloud); + } +} //! \return Returns the name of the video driver. Example: In case of the DirectX8 //! driver, it would return "Direct3D8.1". const wchar_t* CBurningVideoDriver::getName() const { #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL - return L"Burning's Video 0.52 beautiful"; + return L"Burning's Video 0.53 beautiful"; +#elif defined(PATCH_SUPERTUX_8_0_1_with_1_9_0) + return L"Burning's Video 0.53 STK"; #elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST ) - return L"Burning's Video 0.52 ultra fast"; + return L"Burning's Video 0.53 ultra fast"; #elif defined ( BURNINGVIDEO_RENDERER_FAST ) - return L"Burning's Video 0.52 fast"; + return L"Burning's Video 0.53 fast"; #elif defined ( BURNINGVIDEO_RENDERER_CE ) - return L"Burning's Video 0.52 CE"; + return L"Burning's Video 0.53 CE"; #else - return L"Burning's Video 0.52"; + return L"Burning's Video 0.53"; #endif } //! Returns the graphics card vendor name. core::stringc CBurningVideoDriver::getVendorInfo() { - return "Burning's Video: Ing. Thomas Alten (c) 2006-2020"; + return "Burning's Video: Ing. Thomas Alten (c) 2006-2022"; } @@ -3451,11 +4605,14 @@ ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2ddrop(); + if (img) img->drop(); addTexture(tex); tex->drop(); return tex; @@ -3555,7 +4712,7 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::arraysetRenderTarget(RenderTargetSurface, ViewPort, Interlaced); - CurrentShader->pushEdgeTest(Material.org.Wireframe, 0, 0); + CurrentShader->setEdgeTest(Material.org.Wireframe, 0); //setMaterial EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP); @@ -3572,14 +4729,14 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::arraysetStencilOp(StencilOp_KEEP, StencilOp_INCR, StencilOp_KEEP); - drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE); + drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE)E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE)E4IT_NONE); Material.org.BackfaceCulling = true; Material.org.FrontfaceCulling = false; Material.CullFlag = CULL_BACK | CULL_INVISIBLE; CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_DECR, StencilOp_KEEP); - drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE); + drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE)E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE)E4IT_NONE); } else // zpass { @@ -3588,14 +4745,14 @@ void CBurningVideoDriver::drawStencilShadowVolume(const core::arraysetStencilOp(StencilOp_KEEP, StencilOp_KEEP, StencilOp_INCR); - drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE); + drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE)E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE)E4IT_NONE); Material.org.BackfaceCulling = false; Material.org.FrontfaceCulling = true; Material.CullFlag = CULL_FRONT | CULL_INVISIBLE; CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_KEEP, StencilOp_DECR); - drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE); + drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE)E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE)E4IT_NONE); } //glDisable(GL_DEPTH_CLAMP); @@ -3621,7 +4778,7 @@ void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SCol interlace_scanline_data line; for (line.y = 0; line.y < h; line.y += SOFTWARE_DRIVER_2_STEP_Y) { - interlace_scanline + if_interlace_scanline { tVideoSample * dst = (tVideoSample*)RenderTargetSurface->getData() + (line.y * w); const tStencilSample* stencil = (tStencilSample*)StencilBuffer->lock() + (line.y * w); @@ -3725,10 +4882,11 @@ s32 CBurningVideoDriver::addHighLevelShaderMaterial( } -void CBurningVideoDriver::setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType) +void CBurningVideoDriver::setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType, eBurningVertexShader vertexShader) { //this should be in material.... Material.Fallback_MaterialType = fallback_MaterialType; + Material.VertexShader = vertexShader; } void CBurningVideoDriver::setBasicRenderStates(const SMaterial& material, @@ -3741,26 +4899,31 @@ void CBurningVideoDriver::setBasicRenderStates(const SMaterial& material, //! Return an index constant for the vertex shader based on a name. s32 CBurningVideoDriver::getVertexShaderConstantID(const c8* name) { - return -1; + return getPixelShaderConstantID(name); } bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const f32* floats, int count) { - return true; + return setPixelShaderConstant(index, floats, count); } bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const s32* ints, int count) { - return true; + return setPixelShaderConstant(index, ints, count); } bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const u32* ints, int count) { - return true; + return setPixelShaderConstant(index, ints, count); } void CBurningVideoDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) { + //used? + if (CurrentShader) + { + CurrentShader->setVertexShaderConstant(data, startRegister, constantAmount); + } } //! Return an index constant for the pixel shader based on a name. @@ -3786,6 +4949,11 @@ bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const u32* ints, int void CBurningVideoDriver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) { + //used? + if (CurrentShader) + { + CurrentShader->setPixelShaderConstant(data, startRegister, constantAmount); + } } //! Get pointer to the IVideoDriver interface @@ -3795,16 +4963,52 @@ IVideoDriver* CBurningVideoDriver::getVideoDriver() return this; } -} // end namespace video -} // end namespace irr + +//! 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. */ +void CBurningVideoDriver::runOcclusionQuery(scene::ISceneNode* node, bool visible) +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index != -1) + { + //extGlBeginQuery(GL_SAMPLES_PASSED_ARB, OcclusionQueries[index].UID); + samples_passed = 0; + CNullDriver::runOcclusionQuery(node, visible); + //extGlEndQuery(GL_SAMPLES_PASSED_ARB); + } +} + + +//! 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 */ +void CBurningVideoDriver::updateOcclusionQuery(scene::ISceneNode* node, bool block) +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + if (index < 0) return; + + OcclusionQueries[index].Result = samples_passed; + +} + + +//! Return query result. +/** Return value is the number of visible pixels/fragments. +The value is a safe approximation, i.e. can be larger than the +actual value of pixels. */ +u32 CBurningVideoDriver::getOcclusionQueryResult(scene::ISceneNode* node) const +{ + const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); + return index < 0 ? ~0 : OcclusionQueries[index].Result; +} + +burning_namespace_end #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ -namespace irr -{ -namespace video -{ +burning_namespace_start //! creates a video driver IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter) @@ -3816,8 +5020,5 @@ IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& p #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ } - - -} // end namespace video -} // end namespace irr +burning_namespace_end diff --git a/source/Irrlicht/CSoftwareDriver2.h b/source/Irrlicht/CSoftwareDriver2.h index 53634b74..ae645c7a 100644 --- a/source/Irrlicht/CSoftwareDriver2.h +++ b/source/Irrlicht/CSoftwareDriver2.h @@ -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 RenderTargets; diff --git a/source/Irrlicht/CSoftwareTexture2.cpp b/source/Irrlicht/CSoftwareTexture2.cpp index 1dff8c5c..9b266bc5 100644 --- a/source/Irrlicht/CSoftwareTexture2.cpp +++ b/source/Irrlicht/CSoftwareTexture2.cpp @@ -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* dstRect, const video::IImage* src, const core::rect* srcRect, size_t flags); //nearest pow of 2 ( 257 will be 256 not 512 ) -static inline core::dimension2d getOptimalSize(const core::dimension2d& original, const u32 allowNonPowerOfTwo, const u32 maxSize) +static inline core::dimension2d getOptimalSize(const core::dimension2d& original, + const u32 allowNonPowerOfTwo, const u32 maxSize + , const interlaced_control& interlace) { u32 w, h; if (allowNonPowerOfTwo) @@ -29,7 +28,17 @@ static inline core::dimension2d getOptimalSize(const core::dimension2d 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 getOptimalSize(const core::dimension2d 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(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 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 optSize(getOptimalSize(OriginalSize, Flags & ALLOW_NPOT, maxTexSize)); + + //thread-local storage if needed + original_mip0 = 0; + + const interlaced_control& interlaced = Driver->getInterlace(); + core::dimension2d 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 p(0, 0, d.Width, d.Height); - SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000); + SColor c((color[i & 15] & 0x00FFFFFF) | 0x7F000000); core::rect 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(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 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 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 } 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 } } } - +#undef ft } -} // end namespace video -} // end namespace irr +burning_namespace_end #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_ diff --git a/source/Irrlicht/CSoftwareTexture2.h b/source/Irrlicht/CSoftwareTexture2.h index d625fb10..a5689425 100644 --- a/source/Irrlicht/CSoftwareTexture2.h +++ b/source/Irrlicht/CSoftwareTexture2.h @@ -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& getOriginalSize() const { return OriginalSize; }; - const core::dimension2d& 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& getOriginalSize() const { return OriginalSize; } + const core::dimension2d& 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 OriginalSize; core::dimension2d 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 Texture; + core::array Textures; + ITexture* DepthStencil; #endif protected: diff --git a/source/Irrlicht/CTRGouraud2.cpp b/source/Irrlicht/CTRGouraud2.cpp index f08a9352..2a272e9c 100644 --- a/source/Irrlicht/CTRGouraud2.cpp +++ b/source/Irrlicht/CTRGouraud2.cpp @@ -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]; diff --git a/source/Irrlicht/CTRGouraudAlpha2.cpp b/source/Irrlicht/CTRGouraudAlpha2.cpp index 118859d8..77028e6e 100644 --- a/source/Irrlicht/CTRGouraudAlpha2.cpp +++ b/source/Irrlicht/CTRGouraudAlpha2.cpp @@ -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]; diff --git a/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp b/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp index 6a9633e5..ee4188d4 100644 --- a/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp +++ b/source/Irrlicht/CTRGouraudAlphaNoZ2.cpp @@ -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 diff --git a/source/Irrlicht/CTRGouraudNoZ2.cpp b/source/Irrlicht/CTRGouraudNoZ2.cpp index b59a489d..9bc9c16a 100644 --- a/source/Irrlicht/CTRGouraudNoZ2.cpp +++ b/source/Irrlicht/CTRGouraudNoZ2.cpp @@ -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]; diff --git a/source/Irrlicht/CTRNormalMap.cpp b/source/Irrlicht/CTRNormalMap.cpp index 284c2d7f..e833729a 100644 --- a/source/Irrlicht/CTRNormalMap.cpp +++ b/source/Irrlicht/CTRNormalMap.cpp @@ -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 diff --git a/source/Irrlicht/CTRStencilShadow.cpp b/source/Irrlicht/CTRStencilShadow.cpp index 38f4ef51..804ed128 100644 --- a/source/Irrlicht/CTRStencilShadow.cpp +++ b/source/Irrlicht/CTRStencilShadow.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureBlend.cpp b/source/Irrlicht/CTRTextureBlend.cpp index 18492307..592ec1f1 100644 --- a/source/Irrlicht/CTRTextureBlend.cpp +++ b/source/Irrlicht/CTRTextureBlend.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureDetailMap2.cpp b/source/Irrlicht/CTRTextureDetailMap2.cpp index ab4f0286..22da5094 100644 --- a/source/Irrlicht/CTRTextureDetailMap2.cpp +++ b/source/Irrlicht/CTRTextureDetailMap2.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureGouraud2.cpp b/source/Irrlicht/CTRTextureGouraud2.cpp index 6d8f9e84..3b8761b9 100644 --- a/source/Irrlicht/CTRTextureGouraud2.cpp +++ b/source/Irrlicht/CTRTextureGouraud2.cpp @@ -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 - - diff --git a/source/Irrlicht/CTRTextureGouraudAdd2.cpp b/source/Irrlicht/CTRTextureGouraudAdd2.cpp index 4ba23cfa..0cc2f17d 100644 --- a/source/Irrlicht/CTRTextureGouraudAdd2.cpp +++ b/source/Irrlicht/CTRTextureGouraudAdd2.cpp @@ -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 diff --git a/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp b/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp index 475b8551..78008f77 100644 --- a/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp +++ b/source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureGouraudAlpha.cpp b/source/Irrlicht/CTRTextureGouraudAlpha.cpp index eab57006..4a0d45a4 100644 --- a/source/Irrlicht/CTRTextureGouraudAlpha.cpp +++ b/source/Irrlicht/CTRTextureGouraudAlpha.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp index 2079c317..4c724de8 100644 --- a/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp +++ b/source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp @@ -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 diff --git a/source/Irrlicht/CTRTextureGouraudNoZ2.cpp b/source/Irrlicht/CTRTextureGouraudNoZ2.cpp index 94b9418b..85d96e65 100644 --- a/source/Irrlicht/CTRTextureGouraudNoZ2.cpp +++ b/source/Irrlicht/CTRTextureGouraudNoZ2.cpp @@ -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 diff --git a/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp b/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp index d49311a1..e90e752f 100644 --- a/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp +++ b/source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureLightMap2_Add.cpp b/source/Irrlicht/CTRTextureLightMap2_Add.cpp index 3b96c715..5f53a9b9 100644 --- a/source/Irrlicht/CTRTextureLightMap2_Add.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_Add.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureLightMap2_M1.cpp b/source/Irrlicht/CTRTextureLightMap2_M1.cpp index c8ebfbc5..aea774ec 100644 --- a/source/Irrlicht/CTRTextureLightMap2_M1.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_M1.cpp @@ -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 diff --git a/source/Irrlicht/CTRTextureLightMap2_M2.cpp b/source/Irrlicht/CTRTextureLightMap2_M2.cpp index ce906f91..56d0ccd5 100644 --- a/source/Irrlicht/CTRTextureLightMap2_M2.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_M2.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureLightMap2_M4.cpp b/source/Irrlicht/CTRTextureLightMap2_M4.cpp index d0a7af5c..0e0620e9 100644 --- a/source/Irrlicht/CTRTextureLightMap2_M4.cpp +++ b/source/Irrlicht/CTRTextureLightMap2_M4.cpp @@ -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 diff --git a/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp b/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp index 9fd93f85..cc634e02 100644 --- a/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp +++ b/source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp @@ -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]; diff --git a/source/Irrlicht/CTRTextureWire2.cpp b/source/Irrlicht/CTRTextureWire2.cpp index 63e590bd..a33454d0 100644 --- a/source/Irrlicht/CTRTextureWire2.cpp +++ b/source/Irrlicht/CTRTextureWire2.cpp @@ -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 diff --git a/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp b/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp index 05a1b5c1..4e209a2b 100644 --- a/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp +++ b/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp @@ -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 diff --git a/source/Irrlicht/IBurningShader.cpp b/source/Irrlicht/IBurningShader.cpp index 640bf9b2..b0e5eaca 100644 --- a/source/Irrlicht/IBurningShader.cpp +++ b/source/Irrlicht/IBurningShader.cpp @@ -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::rectdrop(); - 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_ diff --git a/source/Irrlicht/IBurningShader.h b/source/Irrlicht/IBurningShader.h index 155b94da..d35bea1c 100644 --- a/source/Irrlicht/IBurningShader.h +++ b/source/Irrlicht/IBurningShader.h @@ -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 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 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& 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& 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 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 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 diff --git a/source/Irrlicht/S4DVertex.h b/source/Irrlicht/S4DVertex.h index 2057a893..a1d972ea 100644 --- a/source/Irrlicht/S4DVertex.h +++ b/source/Irrlicht/S4DVertex.h @@ -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 diff --git a/source/Irrlicht/SoftwareDriver2_compile_config.h b/source/Irrlicht/SoftwareDriver2_compile_config.h index 968a2d50..c401428a 100644 --- a/source/Irrlicht/SoftwareDriver2_compile_config.h +++ b/source/Irrlicht/SoftwareDriver2_compile_config.h @@ -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) ) & 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 diff --git a/source/Irrlicht/SoftwareDriver2_helper.h b/source/Irrlicht/SoftwareDriver2_helper.h index 54cd8d3a..5e38d990 100644 --- a/source/Irrlicht/SoftwareDriver2_helper.h +++ b/source/Irrlicht/SoftwareDriver2_helper.h @@ -3,16 +3,14 @@ // For conditions of distribution and use, see copyright notice in irrlicht.h /* - History: - - changed behavior for log2 textures ( replaced multiplies by shift ) +History: +- changed behavior for log2 textures ( replaced multiplies by shift ) */ #ifndef S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED #define S_VIDEO_2_SOFTWARE_HELPER_H_INCLUDED #include "SoftwareDriver2_compile_config.h" -#include "irrMath.h" -#include "irrMathFastCompat.h" #include "CSoftwareTexture2.h" #include "SMaterial.h" @@ -23,44 +21,44 @@ namespace irr // supporting different packed pixel needs many defines... #if defined(SOFTWARE_DRIVER_2_32BIT) - typedef u32 tVideoSample; - typedef u32 tStencilSample; +typedef u32 tVideoSample; +typedef u32 tStencilSample; - #define MASK_A 0xFF000000 - #define MASK_R 0x00FF0000 - #define MASK_G 0x0000FF00 - #define MASK_B 0x000000FF +#define MASK_A 0xFF000000 +#define MASK_R 0x00FF0000 +#define MASK_G 0x0000FF00 +#define MASK_B 0x000000FF - #define SHIFT_A (unsigned)24 - #define SHIFT_R (unsigned)16 - #define SHIFT_G (unsigned)8 - #define SHIFT_B (unsigned)0 +#define SHIFT_A (unsigned)24 +#define SHIFT_R (unsigned)16 +#define SHIFT_G (unsigned)8 +#define SHIFT_B (unsigned)0 - #define COLOR_MAX 0xFF - #define COLOR_MAX_LOG2 8 - #define COLOR_BRIGHT_WHITE 0xFFFFFFFF +#define COLOR_MAX 0xFF +#define COLOR_MAX_LOG2 8 +#define COLOR_BRIGHT_WHITE 0xFFFFFFFF - #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)2 - #define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)2 +#define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)2 +#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)2 #else - typedef u16 tVideoSample; - typedef u8 tStencilSample; +typedef u16 tVideoSample; +typedef u8 tStencilSample; - #define MASK_A 0x8000 - #define MASK_R 0x7C00 - #define MASK_G 0x03E0 - #define MASK_B 0x001F +#define MASK_A 0x8000 +#define MASK_R 0x7C00 +#define MASK_G 0x03E0 +#define MASK_B 0x001F - #define SHIFT_A (unsigned)15 - #define SHIFT_R (unsigned)10 - #define SHIFT_G (unsigned)5 - #define SHIFT_B (unsigned)0 +#define SHIFT_A (unsigned)15 +#define SHIFT_R (unsigned)10 +#define SHIFT_G (unsigned)5 +#define SHIFT_B (unsigned)0 - #define COLOR_MAX 0x1F - #define COLOR_MAX_LOG2 5 - #define COLOR_BRIGHT_WHITE 0xFFFF - #define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)1 - #define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)1 +#define COLOR_MAX 0x1F +#define COLOR_MAX_LOG2 5 +#define COLOR_BRIGHT_WHITE 0xFFFF +#define SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY (unsigned)1 +#define SOFTWARE_DRIVER_2_RENDERTARGET_GRANULARITY (unsigned)1 #endif @@ -73,9 +71,9 @@ namespace irr //! a more useful memset for pixel. dest must be aligned at least to 4 byte // (standard memset only works with 8-bit values) -inline void memset32(void * dest, const u32 value, size_t bytesize) +static inline void memset32(void* dest, const u32 value, size_t bytesize) { - u32 * d = (u32*) dest; + u32* d = (u32*)dest; size_t i; @@ -97,7 +95,7 @@ inline void memset32(void * dest, const u32 value, size_t bytesize) i -= 1; } - i = (bytesize >> 2 ) & 7; + i = (bytesize >> 2) & 7; while (i) { d[0] = value; @@ -108,9 +106,9 @@ inline void memset32(void * dest, const u32 value, size_t bytesize) //! a more useful memset for pixel. dest must be aligned at least to 2 byte // (standard memset only works with 8-bit values) -inline void memset16(void * dest, const u16 value, size_t bytesize) +static inline void memset16(void* dest, const u16 value, size_t bytesize) { - u16 * d = (u16*) dest; + u16* d = (u16*)dest; size_t i; @@ -132,7 +130,7 @@ inline void memset16(void * dest, const u16 value, size_t bytesize) --i; } - i = (bytesize >> 1 ) & 7; + i = (bytesize >> 1) & 7; while (i) { d[0] = value; @@ -142,7 +140,7 @@ inline void memset16(void * dest, const u16 value, size_t bytesize) } //! memset interleaved -inline void memset32_interlaced(void* dest, const u32 value, size_t pitch,u32 height,const interlaced_control Interlaced) +static inline void memset32_interlaced(void* dest, const u32 value, size_t pitch, u32 height, const interlaced_control Interlaced) { if (Interlaced.bypass) return memset32(dest, value, pitch * height); @@ -150,7 +148,7 @@ inline void memset32_interlaced(void* dest, const u32 value, size_t pitch,u32 he interlace_scanline_data line; for (line.y = 0; line.y < height; line.y += SOFTWARE_DRIVER_2_STEP_Y) { - interlace_scanline_enabled memset32(dst, value, pitch); + if_interlace_scanline_active memset32(dst, value, pitch); dst += pitch; } } @@ -162,8 +160,8 @@ inline void memset32_interlaced(void* dest, const u32 value, size_t pitch,u32 he typedef union { float f; unsigned int u; - struct { unsigned int frac:23; unsigned exp:8; unsigned int sign:1; } fields; - struct { unsigned int frac_exp:31; } abs; + struct { unsigned int frac : 23; unsigned exp : 8; unsigned int sign : 1; } fields; + struct { unsigned int frac_exp : 31; } abs; } PACK_STRUCT ieee754; // Default alignment @@ -176,7 +174,7 @@ typedef union { #if 0 // integer log2 of a float ieee 754. [not used anymore] -static inline s32 s32_log2_f32( f32 f) +static inline s32 s32_log2_f32(f32 f) { //u32 x = IR ( f ); return ((x & 0x7F800000) >> 23) - 127; ieee754 _log2; @@ -203,14 +201,14 @@ static inline s32 s32_log2_s32(u32 in) static inline s32 s32_abs(s32 x) { s32 b = x >> 31; - return (x ^ b ) - b; + return (x ^ b) - b; } //! conditional set based on mask and arithmetic shift -REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b ) +REALINLINE u32 if_mask_a_else_b(const u32 mask, const u32 a, const u32 b) { - return ( mask & ( a ^ b ) ) ^ b; + return (mask & (a ^ b)) ^ b; } #endif @@ -219,7 +217,7 @@ REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b ) Pixel = dest * ( 1 - alpha ) + source * alpha alpha [0;256] */ -REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, const u32 alpha ) +REALINLINE u32 PixelBlend32(const u32 c2, const u32 c1, const u32 alpha) { u32 srcRB = c1 & 0x00FF00FF; u32 srcXG = c1 & 0x0000FF00; @@ -249,7 +247,7 @@ REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, const u32 alpha ) Pixel = dest * ( 1 - alpha ) + source * alpha alpha [0;32] */ -inline u16 PixelBlend16 ( const u16 c2, const u16 c1, const u16 alpha ) +inline u16 PixelBlend16(const u16 c2, const u16 c1, const u16 alpha) { const u16 srcRB = c1 & 0x7C1F; const u16 srcXG = c1 & 0x03E0; @@ -277,103 +275,103 @@ inline u16 PixelBlend16 ( const u16 c2, const u16 c1, const u16 alpha ) /* Pixel = c0 * (c1/31). c0 Alpha retain */ -inline u16 PixelMul16 ( const u16 c0, const u16 c1) +inline u16 PixelMul16(const u16 c0, const u16 c1) { - return (u16)((( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 ) | - (( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 ) | - (( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 ) | - (c0 & 0x8000)); + return (u16)(((((c0 & 0x7C00) * (c1 & 0x7C00)) & 0x3E000000) >> 15) | + ((((c0 & 0x03E0) * (c1 & 0x03E0)) & 0x000F8000) >> 10) | + ((((c0 & 0x001F) * (c1 & 0x001F)) & 0x000003E0) >> 5) | + (c0 & 0x8000)); } /* Pixel = c0 * (c1/31). */ -inline u16 PixelMul16_2 ( u16 c0, u16 c1) +inline u16 PixelMul16_2(u16 c0, u16 c1) { - return (u16)(( ( (c0 & 0x7C00) * (c1 & 0x7C00) ) & 0x3E000000 ) >> 15 | - ( ( (c0 & 0x03E0) * (c1 & 0x03E0) ) & 0x000F8000 ) >> 10 | - ( ( (c0 & 0x001F) * (c1 & 0x001F) ) & 0x000003E0 ) >> 5 | - ( c0 & c1 & 0x8000)); + return (u16)((((c0 & 0x7C00) * (c1 & 0x7C00)) & 0x3E000000) >> 15 | + (((c0 & 0x03E0) * (c1 & 0x03E0)) & 0x000F8000) >> 10 | + (((c0 & 0x001F) * (c1 & 0x001F)) & 0x000003E0) >> 5 | + (c0 & c1 & 0x8000)); } /* Pixel = c0 * (c1/255). c0 Alpha Retain */ -REALINLINE u32 PixelMul32 ( const u32 c0, const u32 c1) +REALINLINE u32 PixelMul32(const u32 c0, const u32 c1) { return (c0 & 0xFF000000) | - (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) | - (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) | - (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF); + ((((c0 & 0x00FF0000) >> 12) * ((c1 & 0x00FF0000) >> 12)) & 0x00FF0000) | + ((((c0 & 0x0000FF00) * (c1 & 0x0000FF00)) >> 16) & 0x0000FF00) | + ((((c0 & 0x000000FF) * (c1 & 0x000000FF)) >> 8) & 0x000000FF); } /* Pixel = c0 * (c1/255). */ -REALINLINE u32 PixelMul32_2 ( const u32 c0, const u32 c1) +REALINLINE u32 PixelMul32_2(const u32 c0, const u32 c1) { - return (( ( (c0 & 0xFF000000) >> 16 ) * ( (c1 & 0xFF000000) >> 16 ) ) & 0xFF000000 ) | - (( ( (c0 & 0x00FF0000) >> 12 ) * ( (c1 & 0x00FF0000) >> 12 ) ) & 0x00FF0000 ) | - (( ( (c0 & 0x0000FF00) * (c1 & 0x0000FF00) ) >> 16 ) & 0x0000FF00 ) | - (( ( (c0 & 0x000000FF) * (c1 & 0x000000FF) ) >> 8 ) & 0x000000FF); + return ((((c0 & 0xFF000000) >> 16) * ((c1 & 0xFF000000) >> 16)) & 0xFF000000) | + ((((c0 & 0x00FF0000) >> 12) * ((c1 & 0x00FF0000) >> 12)) & 0x00FF0000) | + ((((c0 & 0x0000FF00) * (c1 & 0x0000FF00)) >> 16) & 0x0000FF00) | + ((((c0 & 0x000000FF) * (c1 & 0x000000FF)) >> 8) & 0x000000FF); } /* Pixel = clamp ( c0 + c1, 0, 255 ) */ -REALINLINE u32 PixelAdd32 ( const u32 c2, const u32 c1) +REALINLINE u32 PixelAdd32(const u32 c2, const u32 c1) { - u32 sum = ( c2 & 0x00FFFFFF ) + ( c1 & 0x00FFFFFF ); - u32 low_bits = ( c2 ^ c1 ) & 0x00010101; - s32 carries = ( sum - low_bits ) & 0x01010100; + u32 sum = (c2 & 0x00FFFFFF) + (c1 & 0x00FFFFFF); + u32 low_bits = (c2 ^ c1) & 0x00010101; + s32 carries = (sum - low_bits) & 0x01010100; u32 modulo = sum - carries; - u32 clamp = carries - ( carries >> 8 ); + u32 clamp = carries - (carries >> 8); return modulo | clamp; } #if 0 // 1 - Bit Alpha Blending -inline u16 PixelBlend16 ( const u16 destination, const u16 source ) +inline u16 PixelBlend16(const u16 destination, const u16 source) { - if((source & 0x8000) == 0x8000) + if ((source & 0x8000) == 0x8000) return source; // The source is visible, so use it. else return destination; // The source is transparent, so use the destination. } // 1 - Bit Alpha Blending 16Bit SIMD -inline u32 PixelBlend16_simd ( const u32 destination, const u32 source ) +inline u32 PixelBlend16_simd(const u32 destination, const u32 source) { - switch(source & 0x80008000) + switch (source & 0x80008000) { - case 0x80008000: // Both source pixels are visible - return source; + case 0x80008000: // Both source pixels are visible + return source; - case 0x80000000: // Only the first source pixel is visible - return (source & 0xFFFF0000) | (destination & 0x0000FFFF); + case 0x80000000: // Only the first source pixel is visible + return (source & 0xFFFF0000) | (destination & 0x0000FFFF); - case 0x00008000: // Only the second source pixel is visible. - return (destination & 0xFFFF0000) | (source & 0x0000FFFF); + case 0x00008000: // Only the second source pixel is visible. + return (destination & 0xFFFF0000) | (source & 0x0000FFFF); - default: // Neither source pixel is visible. - return destination; + default: // Neither source pixel is visible. + return destination; } } #else // 1 - Bit Alpha Blending -inline u16 PixelBlend16 ( const u16 c2, const u16 c1 ) +inline u16 PixelBlend16(const u16 c2, const u16 c1) { - u16 mask = ((c1 & 0x8000) >> 15 ) + 0x7fff; - return (c2 & mask ) | ( c1 & ~mask ); + u16 mask = ((c1 & 0x8000) >> 15) + 0x7fff; + return (c2 & mask) | (c1 & ~mask); } // 1 - Bit Alpha Blending 16Bit SIMD -inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 ) +inline u32 PixelBlend16_simd(const u32 c2, const u32 c1) { - u32 mask = ((c1 & 0x80008000) >> 15 ) + 0x7fff7fff; - return (c2 & mask ) | ( c1 & ~mask ); + u32 mask = ((c1 & 0x80008000) >> 15) + 0x7fff7fff; + return (c2 & mask) | (c1 & ~mask); } #endif @@ -381,14 +379,14 @@ inline u32 PixelBlend16_simd ( const u32 c2, const u32 c1 ) /*! Pixel = dest * ( 1 - SourceAlpha ) + source * SourceAlpha (OpenGL blending) */ -inline u32 PixelBlend32 ( const u32 c2, const u32 c1 ) +inline u32 PixelBlend32(const u32 c2, const u32 c1) { // alpha test u32 alpha = c1 & 0xFF000000; - if ( 0 == alpha ) + if (0 == alpha) return c2; - if ( 0xFF000000 == alpha ) + if (0xFF000000 == alpha) { return c1; } @@ -396,7 +394,7 @@ inline u32 PixelBlend32 ( const u32 c2, const u32 c1 ) alpha >>= 24; // add highbit alpha, if ( alpha > 127 ) alpha += 1; - alpha += ( alpha >> 7); + alpha += (alpha >> 7); u32 srcRB = c1 & 0x00FF00FF; u32 srcXG = c1 & 0x0000FF00; @@ -436,87 +434,93 @@ typedef u32 tFixPointu; // Fix Point 12 (overflow on s32) #if 0 - #define FIX_POINT_PRE 12 - #define FIX_POINT_FRACT_MASK 0xFFF - #define FIX_POINT_UNSIGNED_MASK 0x7FFFF000 - #define FIX_POINT_ONE 0x1000 - #define FIX_POINT_ZERO_DOT_FIVE 0x0800 - #define FIX_POINT_F32_MUL 4096.f +#define FIX_POINT_PRE 12 +#define FIX_POINT_FRACT_MASK 0xFFF +#define FIX_POINT_UNSIGNED_MASK 0x7FFFF000 +#define FIX_POINT_ONE 0x1000 +#define FIX_POINT_ZERO_DOT_FIVE 0x0800 +#define FIX_POINT_F32_MUL 4096.f #endif // Fix Point 11 (overflow on s32) #if 0 - #define FIX_POINT_PRE 11 - #define FIX_POINT_FRACT_MASK 0x7FF - #define FIX_POINT_UNSIGNED_MASK 0xFFFFF800 - #define FIX_POINT_ONE 0x800 - #define FIX_POINT_ZERO_DOT_FIVE 0x400 - #define FIX_POINT_F32_MUL 2048.f +#define FIX_POINT_PRE 11 +#define FIX_POINT_FRACT_MASK 0x7FF +#define FIX_POINT_UNSIGNED_MASK 0xFFFFF800 +#define FIX_POINT_ONE 0x800 +#define FIX_POINT_ZERO_DOT_FIVE 0x400 +#define FIX_POINT_F32_MUL 2048.f #endif // Fix Point 10 #if 1 - #define FIX_POINT_PRE 10 - #define FIX_POINT_FRACT_MASK 0x000003FF - #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00 - #define FIX_POINT_ONE 0x00000400 - #define FIX_POINT_ZERO_DOT_FIVE 0x00000200 - #define FIX_POINT_F32_MUL 1024.f +#define FIX_POINT_PRE 10 +#define FIX_POINT_FRACT_MASK 0x000003FF +#define FIX_POINT_UNSIGNED_MASK 0x7FFFFC00 +#define FIX_POINT_ONE 0x00000400 +#define FIX_POINT_ZERO_DOT_FIVE 0x00000200 +#define FIX_POINT_F32_MUL 1024.f #endif // Fix Point 9 #if 0 - #define FIX_POINT_PRE 9 - #define FIX_POINT_FRACT_MASK 0x1FF - #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00 - #define FIX_POINT_ONE 0x200 - #define FIX_POINT_ZERO_DOT_FIVE 0x100 - #define FIX_POINT_F32_MUL 512.f +#define FIX_POINT_PRE 9 +#define FIX_POINT_FRACT_MASK 0x1FF +#define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00 +#define FIX_POINT_ONE 0x200 +#define FIX_POINT_ZERO_DOT_FIVE 0x100 +#define FIX_POINT_F32_MUL 512.f #endif // Fix Point 7 #if 0 - #define FIX_POINT_PRE 7 - #define FIX_POINT_FRACT_MASK 0x7F - #define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80 - #define FIX_POINT_ONE 0x80 - #define FIX_POINT_ZERO_DOT_FIVE 0x40 - #define FIX_POINT_F32_MUL 128.f +#define FIX_POINT_PRE 7 +#define FIX_POINT_FRACT_MASK 0x7F +#define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80 +#define FIX_POINT_ONE 0x80 +#define FIX_POINT_ZERO_DOT_FIVE 0x40 +#define FIX_POINT_F32_MUL 128.f #endif -#define FIXPOINT_COLOR_MAX ( COLOR_MAX << FIX_POINT_PRE ) +#define FIX_POINT_COLOR_MAX ( COLOR_MAX << FIX_POINT_PRE ) +#define FIX_POINT_EPSILON 1 + +#define FIX_POINT_COLOR_FLOAT_MIN -0.5f +//#define FIX_POINT_COLOR_FLOAT_MAX (FIX_POINT_F32_MUL- ((FIX_POINT_F32_MUL-0.5.f)/(f32) COLOR_MAX)) +#define FIX_POINT_COLOR_MAX_CENTER (COLOR_MAX * FIX_POINT_F32_MUL) #if FIX_POINT_PRE == 10 && COLOR_MAX == 255 - #define FIX_POINT_HALF_COLOR 0x1FE00 - #define FIX_POINT_COLOR_ERROR 4 +#define FIX_POINT_HALF_COLOR 0x1FE00 +#define FIX_POINT_COLOR_ERROR 4 + #elif FIX_POINT_PRE == 12 && COLOR_MAX == 255 - #define FIX_POINT_HALF_COLOR 0x7F800 - #define FIX_POINT_COLOR_ERROR 16 +#define FIX_POINT_HALF_COLOR 0x7F800 +#define FIX_POINT_COLOR_ERROR 16 #elif FIX_POINT_PRE == 10 && COLOR_MAX == 31 - #define FIX_POINT_HALF_COLOR 0x3E00 - #define FIX_POINT_COLOR_ERROR 32 +#define FIX_POINT_HALF_COLOR 0x3E00 +#define FIX_POINT_COLOR_ERROR 32 #else - #define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) ) - #define FIX_POINT_COLOR_ERROR (1<<(FIX_POINT_PRE-COLOR_MAX_LOG2)) +#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) ) +#define FIX_POINT_COLOR_ERROR (1<<(FIX_POINT_PRE-COLOR_MAX_LOG2)) #endif /* - convert signed integer to fixpoint +convert signed integer to fixpoint */ -inline tFixPoint s32_to_fixPoint (const s32 x) +inline tFixPoint s32_to_fixPoint(const s32 x) { return x << FIX_POINT_PRE; } #if 0 -inline tFixPointu u32_to_fixPoint (const u32 x) +inline tFixPointu u32_to_fixPoint(const u32 x) { return x << FIX_POINT_PRE; } #endif -inline u32 fixPointu_to_u32 (const tFixPointu x) +inline u32 fixPointu_to_u32(const tFixPointu x) { return (u32)(x >> FIX_POINT_PRE); } @@ -528,15 +532,15 @@ inline u32 fixPointu_to_u32 (const tFixPointu x) /* - convert float to fixpoint - fast convert (fistp on x86) HAS to be used.. - hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different - others should use their favourite assembler.. +convert float to fixpoint +fast convert (fistp on x86) HAS to be used.. +hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different +others should use their favourite assembler.. */ #if 0 static inline int f_round2(f32 f) { - f += (3<<22); + f += (3 << 22); return IR(f) - 0x4b400000; } #endif @@ -582,19 +586,19 @@ REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y) */ REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y) { - return ( x * y) >> ( FIX_POINT_PRE -1 ); + return (x * y) >> (FIX_POINT_PRE - 1); } #endif /* - Multiply x * y * 1 FIXPOINT_COLOR_MAX + Multiply x * y * 1 FIX_POINT_COLOR_MAX */ REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y) { #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8 - return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4); + return (((tFixPointu)x >> 2) * (((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 4); #else - return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5); + return (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5); #endif } @@ -603,7 +607,7 @@ REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y) */ REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y) { - return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 3 ); + return (((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 3); } /* @@ -613,44 +617,44 @@ REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y) REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y) { #if SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT == ECF_A8R8G8B8 - tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2); + tFixPoint a = (((tFixPointu)x >> 2) * (((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2); #else tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3); #endif - tFixPoint mask = (a - FIXPOINT_COLOR_MAX) >> 31; - return (a & mask) | (FIXPOINT_COLOR_MAX & ~mask); + tFixPoint mask = (a - FIX_POINT_COLOR_MAX) >> 31; + return (a & mask) | (FIX_POINT_COLOR_MAX & ~mask); } /*! clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX) */ -REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a) +REALINLINE tFixPoint clampfix_maxcolor(const tFixPoint a) { - tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31; - return (a & c) | ( FIXPOINT_COLOR_MAX & ~c); + tFixPoint c = (a - FIX_POINT_COLOR_MAX) >> 31; + return (a & c) | (FIX_POINT_COLOR_MAX & ~c); } /*! clamp FixPoint to 0 in FixPoint, max(a,0) */ -REALINLINE tFixPoint clampfix_mincolor ( const tFixPoint a) +REALINLINE tFixPoint clampfix_mincolor(const tFixPoint a) { - return a - ( a & ( a >> 31 ) ); + return a - (a & (a >> 31)); } -REALINLINE tFixPoint saturateFix ( const tFixPoint a) +REALINLINE tFixPoint saturateFix(const tFixPoint a) { - return clampfix_mincolor ( clampfix_maxcolor ( a ) ); + return clampfix_mincolor(clampfix_maxcolor(a)); } #if 0 // rount fixpoint to int -inline s32 roundFix ( const tFixPoint x ) +inline s32 roundFix(const tFixPoint x) { - return (s32)(( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE); + return (s32)((x + FIX_POINT_ZERO_DOT_FIVE) >> FIX_POINT_PRE); } #endif @@ -666,12 +670,21 @@ inline s32 f32_to_23Bits(const f32 x) /*! fixpoint in [0..Fixpoint_color] to VideoSample xrgb */ -REALINLINE tVideoSample fix_to_sample ( const tFixPoint r, const tFixPoint g, const tFixPoint b ) +REALINLINE tVideoSample fix_to_sample(const tFixPoint r, const tFixPoint g, const tFixPoint b) { - return ( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) | - ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) | - ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) | - ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B ); + return (FIX_POINT_COLOR_MAX & FIX_POINT_COLOR_MAX) << (SHIFT_A - FIX_POINT_PRE) | + (r & FIX_POINT_COLOR_MAX) << (SHIFT_R - FIX_POINT_PRE) | + (g & FIX_POINT_COLOR_MAX) >> (FIX_POINT_PRE - SHIFT_G) | + (b & FIX_POINT_COLOR_MAX) >> (FIX_POINT_PRE - SHIFT_B); +} + +REALINLINE tVideoSample fix_to_sample_nearest(const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b) +{ + return + ((a + FIX_POINT_ZERO_DOT_FIVE) & FIX_POINT_COLOR_MAX) << (SHIFT_A - FIX_POINT_PRE) | + ((r + FIX_POINT_ZERO_DOT_FIVE) & FIX_POINT_COLOR_MAX) << (SHIFT_R - FIX_POINT_PRE) | + ((g + FIX_POINT_ZERO_DOT_FIVE) & FIX_POINT_COLOR_MAX) >> (FIX_POINT_PRE - SHIFT_G) | + ((b + FIX_POINT_ZERO_DOT_FIVE) & FIX_POINT_COLOR_MAX) >> (FIX_POINT_PRE - SHIFT_B); } @@ -680,43 +693,43 @@ REALINLINE tVideoSample fix_to_sample ( const tFixPoint r, const tFixPoint g, co a in [0;1] rgb in [0;255] colormax */ -REALINLINE tVideoSample fix4_to_sample ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b ) +REALINLINE tVideoSample fix4_to_sample(const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b) { - return ( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) | - ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) | - ( g & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_G ) | - ( b & FIXPOINT_COLOR_MAX) >> ( FIX_POINT_PRE - SHIFT_B ); + return (a & (FIX_POINT_FRACT_MASK - 1)) << (SHIFT_A - 1) | + (r & FIX_POINT_COLOR_MAX) << (SHIFT_R - FIX_POINT_PRE) | + (g & FIX_POINT_COLOR_MAX) >> (FIX_POINT_PRE - SHIFT_G) | + (b & FIX_POINT_COLOR_MAX) >> (FIX_POINT_PRE - SHIFT_B); } /*! - return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX + return fixpoint from VideoSample granularity FIX_POINT_COLOR_MAX */ -inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +inline void color_to_fix(tFixPoint& r, tFixPoint& g, tFixPoint& b, const tVideoSample t00) { - (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE ); - (tFixPointu&) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); - (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); + (tFixPointu&)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE); + (tFixPointu&)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G); + (tFixPointu&)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B); } /*! - return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX + return fixpoint from VideoSample granularity FIX_POINT_COLOR_MAX */ -inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +inline void color_to_fix(tFixPoint& a, tFixPoint& r, tFixPoint& g, tFixPoint& b, const tVideoSample t00) { - (tFixPointu&) a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE ); - (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE ); - (tFixPointu&) g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); - (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); + (tFixPointu&)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE); + (tFixPointu&)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE); + (tFixPointu&)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G); + (tFixPointu&)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B); } /*! return fixpoint from VideoSample granularity 0..FIX_POINT_ONE */ -inline void color_to_fix1 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +inline void color_to_fix1(tFixPoint& r, tFixPoint& g, tFixPoint& b, const tVideoSample t00) { - (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE ); - (tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE ); - (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 ); + (tFixPointu&)r = (t00 & MASK_R) >> (SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE); + (tFixPointu&)g = (t00 & MASK_G) >> (SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE); + (tFixPointu&)b = (t00 & MASK_B) << (FIX_POINT_PRE - COLOR_MAX_LOG2); //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0 r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0; @@ -727,12 +740,12 @@ inline void color_to_fix1 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVid /*! return fixpoint from VideoSample granularity 0..FIX_POINT_ONE */ -inline void color_to_fix1 ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 ) +inline void color_to_fix1(tFixPoint& a, tFixPoint& r, tFixPoint& g, tFixPoint& b, const tVideoSample t00) { - (tFixPointu&) a = (t00 & MASK_A) >> ( SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE ); - (tFixPointu&) r = (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE ); - (tFixPointu&) g = (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE ); - (tFixPointu&) b = (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 ); + (tFixPointu&)a = (t00 & MASK_A) >> (SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE); + (tFixPointu&)r = (t00 & MASK_R) >> (SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE); + (tFixPointu&)g = (t00 & MASK_G) >> (SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE); + (tFixPointu&)b = (t00 & MASK_B) << (FIX_POINT_PRE - COLOR_MAX_LOG2); //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0 a += (a & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0; @@ -743,7 +756,7 @@ inline void color_to_fix1 ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint } /*! - return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX + return fixpoint from VideoSample granularity FIX_POINT_COLOR_MAX */ inline void color_to_fix(tFixPoint c[4], const tVideoSample t00) { @@ -784,26 +797,26 @@ struct fp24 fp24() {} - fp24 ( const f32 f ) + fp24(const f32 f) { f32 y = f + 1.f; v = ((u32&)y) & 0x7FFFFF; // last 23 bits } - void operator=(const f32 f ) + void operator=(const f32 f) { - f32 y = f + 1.f; + f32 y = f + 1.f; v = ((u32&)y) & 0x7FFFFF; // last 23 bits - } + } - void operator+=(const fp24 &other ) + void operator+=(const fp24& other) { v += other.v; } operator f32 () const { - f32 r = FR ( v ); + f32 r = FR(v); return r + 1.f; } @@ -822,53 +835,53 @@ struct sInternalTexture size_t pitchlog2; - video::CSoftwareTexture2 *Texture; + video::CSoftwareTexture2* Texture; s32 lodFactor; // magnify/minify }; // get video sample plain -static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty ) +static inline tVideoSample getTexel_plain(const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty) { size_t ofs; - ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; - ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY ); + ofs = ((ty & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; + ofs |= (tx & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); // texel - return *((tVideoSample*)( (u8*) t->data + ofs )); + return *((tVideoSample*)((u8*)t->data + ofs)); } // get video sample to fix -inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, - const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty - ) -{ - size_t ofs; - - ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; - ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY ); - - // texel - tVideoSample t00; - t00 = *((tVideoSample*)( (u8*) t->data + ofs )); - - r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE); - g = (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G ); - b = (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B ); - -} - -// get video sample to fixpoint colormax -inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, +inline void getTexel_fix(tFixPoint& r, tFixPoint& g, tFixPoint& b, const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty ) { size_t ofs; - ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; - ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); + ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; + ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); + + // texel + tVideoSample t00; + t00 = *((tVideoSample*)((u8*)t->data + ofs)); + + r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE); + g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G); + b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B); + +} + +// get video sample to fixpoint colormax +inline void getTexel_fix(tFixPoint& a, tFixPoint& r, tFixPoint& g, tFixPoint& b, + const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty +) +{ + size_t ofs; + + ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; + ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); // texel tVideoSample t00; @@ -883,19 +896,19 @@ inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, #if 0 // get video sample to fixpoint -static REALINLINE void getTexel_fix ( tFixPoint &a, - const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty) +static REALINLINE void getTexel_fix(tFixPoint& a, + const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty) { size_t ofs; - ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2; - ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY ); + ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; + ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); // texel tVideoSample t00; - t00 = *((tVideoSample*)( (u8*) t->data + ofs )); + t00 = *((tVideoSample*)((u8*)t->data + ofs)); - a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE); + a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE); } #endif @@ -906,7 +919,7 @@ static REALINLINE void getTexel_fix ( tFixPoint &a, #if 0 // texture2D in fixpoint color range bilinear -static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b, +static REALINLINE void getSample_texture(tFixPoint& r, tFixPoint& g, tFixPoint& b, const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty ) { @@ -938,9 +951,9 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint & tVideoSample t00; //wraps positive (ignoring negative) - o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; + o0 = (((ty)&t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2; - o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); + o2 = ((tx)&t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2))); @@ -994,7 +1007,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint & #else // texture2D in fixpoint color range bilinear -static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b, +static REALINLINE void getSample_texture(tFixPoint& r, tFixPoint& g, tFixPoint& b, const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty ) { @@ -1015,6 +1028,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint & return; } #endif + //w00 w01 w10 w11 tFixPointu w[4]; { @@ -1030,9 +1044,12 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint & tVideoSample t[4]; { size_t o0, o1, o2, o3; - o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; + + // #if FIX_POINT_PRE > SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE_LOG2 >> FIX_POINT_PRE - tex->pitchlog2 + + o0 = (((ty)&tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; - o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); + o2 = ((tx)&tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2))); @@ -1060,7 +1077,7 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint & #endif // get Sample bilinear -static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, +static REALINLINE void getSample_texture(tFixPoint& a, tFixPoint& r, tFixPoint& g, tFixPoint& b, const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty ) { @@ -1073,9 +1090,9 @@ static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint & size_t o0, o1, o2, o3; tVideoSample t00; - o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; + o0 = (((ty)&tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2; - o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); + o2 = ((tx)&tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - SOFTWARE_DRIVER_2_TEXTURE_GRANULARITY); t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2))); @@ -1141,7 +1158,7 @@ static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint & // get Sample linear == getSample_fixpoint -static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b, +static REALINLINE void getSample_texture(tFixPoint& r, tFixPoint& g, tFixPoint& b, const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty ) { @@ -1152,12 +1169,12 @@ static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint & // texel const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs)); - (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE); - (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G); - (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B); + (tFixPointu&)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE); + (tFixPointu&)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G); + (tFixPointu&)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B); } -static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, +static REALINLINE void getSample_texture(tFixPoint& a, tFixPoint& r, tFixPoint& g, tFixPoint& b, const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty ) { @@ -1168,11 +1185,11 @@ static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint & // texel const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs)); - (tFixPointu &)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE); + (tFixPointu&)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE); fix_alpha_color_max(a); - (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE); - (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G); - (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B); + (tFixPointu&)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE); + (tFixPointu&)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G); + (tFixPointu&)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B); } @@ -1189,13 +1206,13 @@ struct AbsRectangle }; //! 2D Intersection test -inline bool intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRectangle& b) +inline bool intersect(AbsRectangle& dest, const AbsRectangle& a, const AbsRectangle& b) { - dest.x0 = core::s32_max( a.x0, b.x0 ); - dest.y0 = core::s32_max( a.y0, b.y0 ); - dest.x1 = core::s32_min( a.x1, b.x1 ); - dest.y1 = core::s32_min( a.y1, b.y1 ); - return dest.x0 < dest.x1 && dest.y0 < dest.y1; + dest.x0 = core::s32_max(a.x0, b.x0); + dest.y0 = core::s32_max(a.y0, b.y0); + dest.x1 = core::s32_min(a.x1, b.x1); + dest.y1 = core::s32_min(a.y1, b.y1); + return dest.x0 < dest.x1&& dest.y0 < dest.y1; } #if 0 @@ -1207,9 +1224,9 @@ struct sIntervall }; // returning intersection width -inline s32 intervall_intersect_test( const sIntervall& a, const sIntervall& b) +inline s32 intervall_intersect_test(const sIntervall& a, const sIntervall& b) { - return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start ); + return core::s32_min(a.end, b.end) - core::s32_max(a.start, b.start); } #endif @@ -1225,7 +1242,7 @@ static inline void tiny_strncpy(char* to, const char* from, const size_t count) // tiny_isequal = !strncmp(a,b,sizeof(a)-1) -static inline int tiny_isequal(const char *s1, const char *s2, size_t n) +static inline int tiny_isequal(const char* s1, const char* s2, size_t n) { do { if (*s1 != *s2++) return 0; diff --git a/source/Irrlicht/burning_shader_color.cpp b/source/Irrlicht/burning_shader_color.cpp index 3af52abc..8c3657d4 100644 --- a/source/Irrlicht/burning_shader_color.cpp +++ b/source/Irrlicht/burning_shader_color.cpp @@ -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)*/ diff --git a/source/Irrlicht/burning_shader_color_fraq.h b/source/Irrlicht/burning_shader_color_fraq.h index f9efae2d..ad0c1971 100644 --- a/source/Irrlicht/burning_shader_color_fraq.h +++ b/source/Irrlicht/burning_shader_color_fraq.h @@ -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 diff --git a/source/Irrlicht/burning_shader_compile_fragment_default.h b/source/Irrlicht/burning_shader_compile_fragment_default.h index c6d06ca6..eeae3d32 100644 --- a/source/Irrlicht/burning_shader_compile_fragment_default.h +++ b/source/Irrlicht/burning_shader_compile_fragment_default.h @@ -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" diff --git a/source/Irrlicht/burning_shader_compile_fragment_end.h b/source/Irrlicht/burning_shader_compile_fragment_end.h index 8e4719e7..c6311009 100644 --- a/source/Irrlicht/burning_shader_compile_fragment_end.h +++ b/source/Irrlicht/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]; diff --git a/source/Irrlicht/burning_shader_compile_fragment_start.h b/source/Irrlicht/burning_shader_compile_fragment_start.h index 15306449..8a5cb15d 100644 --- a/source/Irrlicht/burning_shader_compile_fragment_start.h +++ b/source/Irrlicht/burning_shader_compile_fragment_start.h @@ -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 diff --git a/source/Irrlicht/burning_shader_compile_start.h b/source/Irrlicht/burning_shader_compile_start.h index 0d8a5f77..d11b5dd9 100644 --- a/source/Irrlicht/burning_shader_compile_start.h +++ b/source/Irrlicht/burning_shader_compile_start.h @@ -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 \ No newline at end of file diff --git a/source/Irrlicht/burning_shader_compile_triangle.h b/source/Irrlicht/burning_shader_compile_triangle.h index 5594b989..02940f3b 100644 --- a/source/Irrlicht/burning_shader_compile_triangle.h +++ b/source/Irrlicht/burning_shader_compile_triangle.h @@ -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]; diff --git a/tests/draw2DImage.cpp b/tests/draw2DImage.cpp index 1d80c041..7983e3ea 100644 --- a/tests/draw2DImage.cpp +++ b/tests/draw2DImage.cpp @@ -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(); diff --git a/tests/drawVertexPrimitive.cpp b/tests/drawVertexPrimitive.cpp index 825e6134..78d40042 100644 --- a/tests/drawVertexPrimitive.cpp +++ b/tests/drawVertexPrimitive.cpp @@ -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(), diff --git a/tests/media/Burning's Video-2dmatFilter.png b/tests/media/Burning's Video-2dmatFilter.png index 09891c8e..cba9be3d 100644 Binary files a/tests/media/Burning's Video-2dmatFilter.png and b/tests/media/Burning's Video-2dmatFilter.png differ diff --git a/tests/media/Burning's Video-addBlend2D.png b/tests/media/Burning's Video-addBlend2D.png index 2122aa35..c3cc5207 100644 Binary files a/tests/media/Burning's Video-addBlend2D.png and b/tests/media/Burning's Video-addBlend2D.png differ diff --git a/tests/media/Burning's Video-ambient-lighting.png b/tests/media/Burning's Video-ambient-lighting.png index 242d8d75..61fb0110 100644 Binary files a/tests/media/Burning's Video-ambient-lighting.png and b/tests/media/Burning's Video-ambient-lighting.png differ diff --git a/tests/media/Burning's Video-b3dAnimation.png b/tests/media/Burning's Video-b3dAnimation.png index d16e689a..1a59710e 100644 Binary files a/tests/media/Burning's Video-b3dAnimation.png and b/tests/media/Burning's Video-b3dAnimation.png differ diff --git a/tests/media/Burning's Video-b3dJointPosition.png b/tests/media/Burning's Video-b3dJointPosition.png index b669f8f8..fdeabd10 100644 Binary files a/tests/media/Burning's Video-b3dJointPosition.png and b/tests/media/Burning's Video-b3dJointPosition.png differ diff --git a/tests/media/Burning's Video-billboard.png b/tests/media/Burning's Video-billboard.png index 59f36c1d..3de13f32 100644 Binary files a/tests/media/Burning's Video-billboard.png and b/tests/media/Burning's Video-billboard.png differ diff --git a/tests/media/Burning's Video-billboardOrientation.png b/tests/media/Burning's Video-billboardOrientation.png index 2805aed8..b59d5f63 100644 Binary files a/tests/media/Burning's Video-billboardOrientation.png and b/tests/media/Burning's Video-billboardOrientation.png differ diff --git a/tests/media/Burning's Video-draw2DImage4cFilter.png b/tests/media/Burning's Video-draw2DImage4cFilter.png index b0629d89..c62028f6 100644 Binary files a/tests/media/Burning's Video-draw2DImage4cFilter.png and b/tests/media/Burning's Video-draw2DImage4cFilter.png differ diff --git a/tests/media/Burning's Video-draw2DImagePNG.png b/tests/media/Burning's Video-draw2DImagePNG.png new file mode 100644 index 00000000..e0e58016 Binary files /dev/null and b/tests/media/Burning's Video-draw2DImagePNG.png differ diff --git a/tests/media/Burning's Video-draw2DImageRTT.png b/tests/media/Burning's Video-draw2DImageRTT.png index dde350ff..7d22d8c7 100644 Binary files a/tests/media/Burning's Video-draw2DImageRTT.png and b/tests/media/Burning's Video-draw2DImageRTT.png differ diff --git a/tests/media/Burning's Video-draw2DImageRect.png b/tests/media/Burning's Video-draw2DImageRect.png index 652e784a..a3b2d8fe 100644 Binary files a/tests/media/Burning's Video-draw2DImageRect.png and b/tests/media/Burning's Video-draw2DImageRect.png differ diff --git a/tests/media/Burning's Video-drawPixel.png b/tests/media/Burning's Video-drawPixel.png index acded3e4..4318df1f 100644 Binary files a/tests/media/Burning's Video-drawPixel.png and b/tests/media/Burning's Video-drawPixel.png differ diff --git a/tests/media/Burning's Video-drawRectOutline.png b/tests/media/Burning's Video-drawRectOutline.png index ab97c508..59145613 100644 Binary files a/tests/media/Burning's Video-drawRectOutline.png and b/tests/media/Burning's Video-drawRectOutline.png differ diff --git a/tests/media/Burning's Video-drawVPL_a.png b/tests/media/Burning's Video-drawVPL_a.png index a5666b7c..296c3bfb 100644 Binary files a/tests/media/Burning's Video-drawVPL_a.png and b/tests/media/Burning's Video-drawVPL_a.png differ diff --git a/tests/media/Burning's Video-drawVPL_b.png b/tests/media/Burning's Video-drawVPL_b.png index a5666b7c..f467f0a9 100644 Binary files a/tests/media/Burning's Video-drawVPL_b.png and b/tests/media/Burning's Video-drawVPL_b.png differ diff --git a/tests/media/Burning's Video-drawVPL_c.png b/tests/media/Burning's Video-drawVPL_c.png index a5666b7c..f467f0a9 100644 Binary files a/tests/media/Burning's Video-drawVPL_c.png and b/tests/media/Burning's Video-drawVPL_c.png differ diff --git a/tests/media/Burning's Video-drawVPL_d.png b/tests/media/Burning's Video-drawVPL_d.png index a5666b7c..e5d91734 100644 Binary files a/tests/media/Burning's Video-drawVPL_d.png and b/tests/media/Burning's Video-drawVPL_d.png differ diff --git a/tests/media/Burning's Video-drawVPL_e.png b/tests/media/Burning's Video-drawVPL_e.png index bc839920..584b1b10 100644 Binary files a/tests/media/Burning's Video-drawVPL_e.png and b/tests/media/Burning's Video-drawVPL_e.png differ diff --git a/tests/media/Burning's Video-drawVPL_f.png b/tests/media/Burning's Video-drawVPL_f.png index a5666b7c..d9b057b6 100644 Binary files a/tests/media/Burning's Video-drawVPL_f.png and b/tests/media/Burning's Video-drawVPL_f.png differ diff --git a/tests/media/Burning's Video-drawVPL_g.png b/tests/media/Burning's Video-drawVPL_g.png index 438941d1..eae51524 100644 Binary files a/tests/media/Burning's Video-drawVPL_g.png and b/tests/media/Burning's Video-drawVPL_g.png differ diff --git a/tests/media/Burning's Video-drawVPL_h.png b/tests/media/Burning's Video-drawVPL_h.png index 8ed44557..8052e5a7 100644 Binary files a/tests/media/Burning's Video-drawVPL_h.png and b/tests/media/Burning's Video-drawVPL_h.png differ diff --git a/tests/media/Burning's Video-drawVPL_i.png b/tests/media/Burning's Video-drawVPL_i.png index e344631b..7ddbdad6 100644 Binary files a/tests/media/Burning's Video-drawVPL_i.png and b/tests/media/Burning's Video-drawVPL_i.png differ diff --git a/tests/media/Burning's Video-drawVPL_j.png b/tests/media/Burning's Video-drawVPL_j.png index a5666b7c..8121deb8 100644 Binary files a/tests/media/Burning's Video-drawVPL_j.png and b/tests/media/Burning's Video-drawVPL_j.png differ diff --git a/tests/media/Burning's Video-drawVPL_k.png b/tests/media/Burning's Video-drawVPL_k.png index a5666b7c..296c3bfb 100644 Binary files a/tests/media/Burning's Video-drawVPL_k.png and b/tests/media/Burning's Video-drawVPL_k.png differ diff --git a/tests/media/Burning's Video-fireball.png b/tests/media/Burning's Video-fireball.png new file mode 100644 index 00000000..f93d10e4 Binary files /dev/null and b/tests/media/Burning's Video-fireball.png differ diff --git a/tests/media/Burning's Video-flyCircleAnimator.png b/tests/media/Burning's Video-flyCircleAnimator.png index 218af2a7..7931bc84 100644 Binary files a/tests/media/Burning's Video-flyCircleAnimator.png and b/tests/media/Burning's Video-flyCircleAnimator.png differ diff --git a/tests/media/Burning's Video-guiDisabledMenu.png b/tests/media/Burning's Video-guiDisabledMenu.png index b25bb937..8412dea3 100644 Binary files a/tests/media/Burning's Video-guiDisabledMenu.png and b/tests/media/Burning's Video-guiDisabledMenu.png differ diff --git a/tests/media/Burning's Video-lightType.png b/tests/media/Burning's Video-lightType.png index 446cc6dd..4cd7b908 100644 Binary files a/tests/media/Burning's Video-lightType.png and b/tests/media/Burning's Video-lightType.png differ diff --git a/tests/media/Burning's Video-lightmaps.png b/tests/media/Burning's Video-lightmaps.png index f53a7e36..813125ea 100644 Binary files a/tests/media/Burning's Video-lightmaps.png and b/tests/media/Burning's Video-lightmaps.png differ diff --git a/tests/media/Burning's Video-loadScene.png b/tests/media/Burning's Video-loadScene.png index 00e08b11..505e4cc7 100644 Binary files a/tests/media/Burning's Video-loadScene.png and b/tests/media/Burning's Video-loadScene.png differ diff --git a/tests/media/Burning's Video-makeColorKeyTexture-new.png b/tests/media/Burning's Video-makeColorKeyTexture-new.png index a49dfbfa..07f600b2 100644 Binary files a/tests/media/Burning's Video-makeColorKeyTexture-new.png and b/tests/media/Burning's Video-makeColorKeyTexture-new.png differ diff --git a/tests/media/Burning's Video-makeColorKeyTexture-old.png b/tests/media/Burning's Video-makeColorKeyTexture-old.png index d584cd41..d87d7f75 100644 Binary files a/tests/media/Burning's Video-makeColorKeyTexture-old.png and b/tests/media/Burning's Video-makeColorKeyTexture-old.png differ diff --git a/tests/media/Burning's Video-md2Animation.png b/tests/media/Burning's Video-md2Animation.png index b9c5be6c..86e75148 100644 Binary files a/tests/media/Burning's Video-md2Animation.png and b/tests/media/Burning's Video-md2Animation.png differ diff --git a/tests/media/Burning's Video-md2Normals.png b/tests/media/Burning's Video-md2Normals.png index 302b9b3d..055d536e 100644 Binary files a/tests/media/Burning's Video-md2Normals.png and b/tests/media/Burning's Video-md2Normals.png differ diff --git a/tests/media/Burning's Video-meshTransform.png b/tests/media/Burning's Video-meshTransform.png index e8abb00a..8715cf0b 100644 Binary files a/tests/media/Burning's Video-meshTransform.png and b/tests/media/Burning's Video-meshTransform.png differ diff --git a/tests/media/Burning's Video-multiTexture.png b/tests/media/Burning's Video-multiTexture.png index e02176b0..68209acf 100644 Binary files a/tests/media/Burning's Video-multiTexture.png and b/tests/media/Burning's Video-multiTexture.png differ diff --git a/tests/media/Burning's Video-orthoCam.png b/tests/media/Burning's Video-orthoCam.png index 099f9b71..1d4411fc 100644 Binary files a/tests/media/Burning's Video-orthoCam.png and b/tests/media/Burning's Video-orthoCam.png differ diff --git a/tests/media/Burning's Video-planeMatrix-scaledClip.png b/tests/media/Burning's Video-planeMatrix-scaledClip.png index 36d6cb9d..813125ea 100644 Binary files a/tests/media/Burning's Video-planeMatrix-scaledClip.png and b/tests/media/Burning's Video-planeMatrix-scaledClip.png differ diff --git a/tests/media/Burning's Video-projMat.png b/tests/media/Burning's Video-projMat.png index c1ff258a..13c3b7ef 100644 Binary files a/tests/media/Burning's Video-projMat.png and b/tests/media/Burning's Video-projMat.png differ diff --git a/tests/media/Burning's Video-renderMipmap.png b/tests/media/Burning's Video-renderMipmap.png index 74b8e7f1..10e66a39 100644 Binary files a/tests/media/Burning's Video-renderMipmap.png and b/tests/media/Burning's Video-renderMipmap.png differ diff --git a/tests/media/Burning's Video-rttAndText.png b/tests/media/Burning's Video-rttAndText.png index cf7eaf18..42666d7a 100644 Binary files a/tests/media/Burning's Video-rttAndText.png and b/tests/media/Burning's Video-rttAndText.png differ diff --git a/tests/media/Burning's Video-rttWith2DImage.png b/tests/media/Burning's Video-rttWith2DImage.png index 6fedf81d..bda4efb9 100644 Binary files a/tests/media/Burning's Video-rttWith2DImage.png and b/tests/media/Burning's Video-rttWith2DImage.png differ diff --git a/tests/media/Burning's Video-shotsInShots0.png b/tests/media/Burning's Video-shotsInShots0.png index 7bf1d55c..44c3d07b 100644 Binary files a/tests/media/Burning's Video-shotsInShots0.png and b/tests/media/Burning's Video-shotsInShots0.png differ diff --git a/tests/media/Burning's Video-shotsInShots2.png b/tests/media/Burning's Video-shotsInShots2.png index 7bf1d55c..44c3d07b 100644 Binary files a/tests/media/Burning's Video-shotsInShots2.png and b/tests/media/Burning's Video-shotsInShots2.png differ diff --git a/tests/media/Burning's Video-stencilSelfShadow.png b/tests/media/Burning's Video-stencilSelfShadow.png index 2bd6eecf..2d745247 100644 Binary files a/tests/media/Burning's Video-stencilSelfShadow.png and b/tests/media/Burning's Video-stencilSelfShadow.png differ diff --git a/tests/media/Burning's Video-stencilShadow.png b/tests/media/Burning's Video-stencilShadow.png index 0186a74a..23c257b5 100644 Binary files a/tests/media/Burning's Video-stencilShadow.png and b/tests/media/Burning's Video-stencilShadow.png differ diff --git a/tests/media/Burning's Video-terrainGap.png b/tests/media/Burning's Video-terrainGap.png index 66480ba5..3761d37a 100644 Binary files a/tests/media/Burning's Video-terrainGap.png and b/tests/media/Burning's Video-terrainGap.png differ diff --git a/tests/media/Burning's Video-terrainSceneNode-1.png b/tests/media/Burning's Video-terrainSceneNode-1.png index d105e824..f69b8582 100644 Binary files a/tests/media/Burning's Video-terrainSceneNode-1.png and b/tests/media/Burning's Video-terrainSceneNode-1.png differ diff --git a/tests/media/Burning's Video-terrainSceneNode-2.png b/tests/media/Burning's Video-terrainSceneNode-2.png index 63facea4..63a19a91 100644 Binary files a/tests/media/Burning's Video-terrainSceneNode-2.png and b/tests/media/Burning's Video-terrainSceneNode-2.png differ diff --git a/tests/media/Burning's Video-testGeometryCreator.png b/tests/media/Burning's Video-testGeometryCreator.png index b4aeab60..99866377 100644 Binary files a/tests/media/Burning's Video-testGeometryCreator.png and b/tests/media/Burning's Video-testGeometryCreator.png differ diff --git a/tests/media/Burning's Video-testTerrainMesh.png b/tests/media/Burning's Video-testTerrainMesh.png index 98a7c0d2..9b798704 100644 Binary files a/tests/media/Burning's Video-testTerrainMesh.png and b/tests/media/Burning's Video-testTerrainMesh.png differ diff --git a/tests/media/Burning's Video-textureMatrix.png b/tests/media/Burning's Video-textureMatrix.png index 26afc9e7..462d7693 100644 Binary files a/tests/media/Burning's Video-textureMatrix.png and b/tests/media/Burning's Video-textureMatrix.png differ diff --git a/tests/media/Burning's Video-textureMatrix2.png b/tests/media/Burning's Video-textureMatrix2.png index f1875230..069b2ec5 100644 Binary files a/tests/media/Burning's Video-textureMatrix2.png and b/tests/media/Burning's Video-textureMatrix2.png differ diff --git a/tests/media/Burning's Video-textureMatrixInMixedScenes.png b/tests/media/Burning's Video-textureMatrixInMixedScenes.png index e5cdeb2c..d3215220 100644 Binary files a/tests/media/Burning's Video-textureMatrixInMixedScenes.png and b/tests/media/Burning's Video-textureMatrixInMixedScenes.png differ diff --git a/tests/media/Burning's Video-transparentAddColor.png b/tests/media/Burning's Video-transparentAddColor.png index 59374484..e05a00af 100644 Binary files a/tests/media/Burning's Video-transparentAddColor.png and b/tests/media/Burning's Video-transparentAddColor.png differ diff --git a/tests/media/Burning's Video-transparentAlphaChannel.png b/tests/media/Burning's Video-transparentAlphaChannel.png index 358455d3..4d40afbd 100644 Binary files a/tests/media/Burning's Video-transparentAlphaChannel.png and b/tests/media/Burning's Video-transparentAlphaChannel.png differ diff --git a/tests/media/Burning's Video-transparentAlphaChannelRef.png b/tests/media/Burning's Video-transparentAlphaChannelRef.png index 21844ab2..ff9d4116 100644 Binary files a/tests/media/Burning's Video-transparentAlphaChannelRef.png and b/tests/media/Burning's Video-transparentAlphaChannelRef.png differ diff --git a/tests/media/Burning's Video-transparentReflection2Layer.png b/tests/media/Burning's Video-transparentReflection2Layer.png index 926d189a..5039269d 100644 Binary files a/tests/media/Burning's Video-transparentReflection2Layer.png and b/tests/media/Burning's Video-transparentReflection2Layer.png differ diff --git a/tests/media/Burning's Video-transparentVertexAlpha.png b/tests/media/Burning's Video-transparentVertexAlpha.png index aef6dbd7..f0565b2a 100644 Binary files a/tests/media/Burning's Video-transparentVertexAlpha.png and b/tests/media/Burning's Video-transparentVertexAlpha.png differ diff --git a/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png b/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png index 666b8145..066bcb7a 100644 Binary files a/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png and b/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png differ diff --git a/tests/media/Burning's Video-viewPortText.png b/tests/media/Burning's Video-viewPortText.png index 56e30650..80cfef7b 100644 Binary files a/tests/media/Burning's Video-viewPortText.png and b/tests/media/Burning's Video-viewPortText.png differ diff --git a/tests/media/Burning's Video-writeImageToFile.png b/tests/media/Burning's Video-writeImageToFile.png index acded3e4..4318df1f 100644 Binary files a/tests/media/Burning's Video-writeImageToFile.png and b/tests/media/Burning's Video-writeImageToFile.png differ diff --git a/tests/tests-last-passed-at.txt b/tests/tests-last-passed-at.txt index 75697720..60d5a963 100644 --- a/tests/tests-last-passed-at.txt +++ b/tests/tests-last-passed-at.txt @@ -1,4 +1,4 @@ Tests finished. 72 tests of 72 passed. -Compiled as DEBUG -Test suite pass at GMT Tue Apr 26 19:16:37 2022 +Compiled as RELEASE +Test suite pass at GMT Sat Apr 30 22:54:30 2022