]> git.lizzy.rs Git - irrlicht.git/blobdiff - source/Irrlicht/CSoftwareDriver2.cpp
Delete lots of unused features (#48)
[irrlicht.git] / source / Irrlicht / CSoftwareDriver2.cpp
diff --git a/source/Irrlicht/CSoftwareDriver2.cpp b/source/Irrlicht/CSoftwareDriver2.cpp
deleted file mode 100644 (file)
index 8fa5a9d..0000000
+++ /dev/null
@@ -1,3821 +0,0 @@
-// Copyright (C) 2002-2012 Nikolaus Gebhardt / Thomas Alten\r
-// This file is part of the "Irrlicht Engine".\r
-// For conditions of distribution and use, see copyright notice in irrlicht.h\r
-\r
-#include "IrrCompileConfig.h"\r
-#include "CSoftwareDriver2.h"\r
-\r
-#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
-\r
-#include "SoftwareDriver2_helper.h"\r
-#include "CSoftwareTexture.h"\r
-#include "CSoftwareTexture2.h"\r
-#include "CSoftware2MaterialRenderer.h"\r
-#include "S3DVertex.h"\r
-#include "S4DVertex.h"\r
-#include "CBlit.h"\r
-\r
-\r
-// Matrix now here\r
-\r
-template <class T>\r
-bool mat44_transposed_inverse(irr::core::CMatrix4<T>& out, const irr::core::CMatrix4<T>& M)\r
-{\r
-       const T* burning_restrict m = M.pointer();\r
-\r
-       double d =\r
-               (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -\r
-               (m[0] * m[6] - m[2] * m[4]) * (m[9] * m[15] - m[11] * m[13]) +\r
-               (m[0] * m[7] - m[3] * m[4]) * (m[9] * m[14] - m[10] * m[13]) +\r
-               (m[1] * m[6] - m[2] * m[5]) * (m[8] * m[15] - m[11] * m[12]) -\r
-               (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +\r
-               (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);\r
-\r
-       if (fabs(d) < DBL_MIN)\r
-       {\r
-               out.makeIdentity();\r
-               return false;\r
-       }\r
-\r
-       d = 1.0 / d;\r
-       T* burning_restrict o = out.pointer();\r
-       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])));\r
-       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])));\r
-       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])));\r
-       o[12] = (T)(d * (m[1] * (m[7] * m[10] - m[6] * m[11]) + m[2] * (m[5] * m[11] - m[7] * m[9]) + m[3] * (m[6] * m[9] - m[5] * m[10])));\r
-\r
-       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])));\r
-       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])));\r
-       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])));\r
-       o[13] = (T)(d * (m[2] * (m[7] * m[8] - m[4] * m[11]) + m[3] * (m[4] * m[10] - m[6] * m[8]) + m[0] * (m[6] * m[11] - m[7] * m[10])));\r
-\r
-       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])));\r
-       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])));\r
-       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])));\r
-       o[14] = (T)(d * (m[3] * (m[5] * m[8] - m[4] * m[9]) + m[0] * (m[7] * m[9] - m[5] * m[11]) + m[1] * (m[4] * m[11] - m[7] * m[8])));\r
-\r
-       o[3] = (T)(d * (m[4] * (m[10] * m[13] - m[9] * m[14]) + m[5] * (m[8] * m[14] - m[10] * m[12]) + m[6] * (m[9] * m[12] - m[8] * m[13])));\r
-       o[7] = (T)(d * (m[8] * (m[2] * m[13] - m[1] * m[14]) + m[9] * (m[0] * m[14] - m[2] * m[12]) + m[10] * (m[1] * m[12] - m[0] * m[13])));\r
-       o[11] = (T)(d * (m[12] * (m[2] * m[5] - m[1] * m[6]) + m[13] * (m[0] * m[6] - m[2] * m[4]) + m[14] * (m[1] * m[4] - m[0] * m[5])));\r
-       o[15] = (T)(d * (m[0] * (m[5] * m[10] - m[6] * m[9]) + m[1] * (m[6] * m[8] - m[4] * m[10]) + m[2] * (m[4] * m[9] - m[5] * m[8])));\r
-\r
-       return true;\r
-}\r
-\r
-#if 0\r
-// difference to CMatrix4<T>::getInverse . higher precision in determinant. return identity on failure\r
-template <class T>\r
-bool mat44_inverse(CMatrix4<T>& out, const CMatrix4<T>& M)\r
-{\r
-       const T* m = M.pointer();\r
-\r
-       double d =\r
-               (m[0] * m[5] - m[1] * m[4]) * (m[10] * m[15] - m[11] * m[14]) -\r
-               (m[0] * m[6] - m[2] * m[4]) * (m[9] * m[15] - m[11] * m[13]) +\r
-               (m[0] * m[7] - m[3] * m[4]) * (m[9] * m[14] - m[10] * m[13]) +\r
-               (m[1] * m[6] - m[2] * m[5]) * (m[8] * m[15] - m[11] * m[12]) -\r
-               (m[1] * m[7] - m[3] * m[5]) * (m[8] * m[14] - m[10] * m[12]) +\r
-               (m[2] * m[7] - m[3] * m[6]) * (m[8] * m[13] - m[9] * m[12]);\r
-\r
-       if (fabs(d) < DBL_MIN)\r
-       {\r
-               out.makeIdentity();\r
-               return false;\r
-       }\r
-\r
-       d = 1.0 / d;\r
-       T* o = out.pointer();\r
-       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])));\r
-       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])));\r
-       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])));\r
-       o[3] = (T)(d * (m[1] * (m[7] * m[10] - m[6] * m[11]) + m[2] * (m[5] * m[11] - m[7] * m[9]) + m[3] * (m[6] * m[9] - m[5] * m[10])));\r
-\r
-       o[4] = (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])));\r
-       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])));\r
-       o[6] = (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])));\r
-       o[7] = (T)(d * (m[2] * (m[7] * m[8] - m[4] * m[11]) + m[3] * (m[4] * m[10] - m[6] * m[8]) + m[0] * (m[6] * m[11] - m[7] * m[10])));\r
-\r
-       o[8] = (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])));\r
-       o[9] = (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])));\r
-       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])));\r
-       o[11] = (T)(d * (m[3] * (m[5] * m[8] - m[4] * m[9]) + m[0] * (m[7] * m[9] - m[5] * m[11]) + m[1] * (m[4] * m[11] - m[7] * m[8])));\r
-\r
-       o[12] = (T)(d * (m[4] * (m[10] * m[13] - m[9] * m[14]) + m[5] * (m[8] * m[14] - m[10] * m[12]) + m[6] * (m[9] * m[12] - m[8] * m[13])));\r
-       o[13] = (T)(d * (m[8] * (m[2] * m[13] - m[1] * m[14]) + m[9] * (m[0] * m[14] - m[2] * m[12]) + m[10] * (m[1] * m[12] - m[0] * m[13])));\r
-       o[14] = (T)(d * (m[12] * (m[2] * m[5] - m[1] * m[6]) + m[13] * (m[0] * m[6] - m[2] * m[4]) + m[14] * (m[1] * m[4] - m[0] * m[5])));\r
-       o[15] = (T)(d * (m[0] * (m[5] * m[10] - m[6] * m[9]) + m[1] * (m[6] * m[8] - m[4] * m[10]) + m[2] * (m[4] * m[9] - m[5] * m[8])));\r
-\r
-       return true;\r
-}\r
-#endif\r
-\r
-// void CMatrix4<T>::transformVec4(T *out, const T * in) const\r
-template <class T>\r
-inline void transformVec4Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict out, const T* burning_restrict in)\r
-{\r
-       const T* burning_restrict M = m.pointer();\r
-\r
-       out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8] + in[3] * M[12];\r
-       out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9] + in[3] * M[13];\r
-       out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10] + in[3] * M[14];\r
-       out[3] = in[0] * M[3] + in[1] * M[7] + in[2] * M[11] + in[3] * M[15];\r
-}\r
-\r
-#if 0\r
-// void CMatrix4<T>::transformVect(T *out, const core::vector3df &in) const\r
-template <class T>\r
-inline void transformVec3Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict out, const core::vector3df& in)\r
-{\r
-       const T* burning_restrict M = m.pointer();\r
-       out[0] = in.X * M[0] + in.Y * M[4] + in.Z * M[8] + M[12];\r
-       out[1] = in.X * M[1] + in.Y * M[5] + in.Z * M[9] + M[13];\r
-       out[2] = in.X * M[2] + in.Y * M[6] + in.Z * M[10] + M[14];\r
-       out[3] = in.X * M[3] + in.Y * M[7] + in.Z * M[11] + M[15];\r
-}\r
-#endif\r
-\r
-template <class T>\r
-inline void rotateVec3Vec4(const irr::core::CMatrix4<T>& m, T* burning_restrict out, const T* burning_restrict in)\r
-{\r
-       const T* burning_restrict M = m.pointer();\r
-\r
-       out[0] = in[0] * M[0] + in[1] * M[4] + in[2] * M[8];\r
-       out[1] = in[0] * M[1] + in[1] * M[5] + in[2] * M[9];\r
-       out[2] = in[0] * M[2] + in[1] * M[6] + in[2] * M[10];\r
-       out[3] = 0.f;\r
-}\r
-\r
-//based on https://github.com/ekmett/approximate/blob/master/cbits/fast.c powf_fast_precise\r
-static inline float powf_limit(const float a, const float b)\r
-{\r
-       if (a <= 0.0000001f) return 0.f;\r
-       else if (a >= 1.f) return 1.f;\r
-\r
-       /* calculate approximation with fraction of the exponent */\r
-       int e = (int)b;\r
-       union { float f; int x; } u = { a };\r
-       u.x = (int)((b - e) * (u.x - 1065353216) + 1065353216);\r
-\r
-       float r = 1.0f;\r
-       float ua = a;\r
-       while (e) {\r
-               if (e & 1) {\r
-                       r *= ua;\r
-               }\r
-               if (ua < 0.00000001f)\r
-                       break;\r
-               ua *= ua;\r
-               e >>= 1;\r
-       }\r
-\r
-       r *= u.f;\r
-       return r;\r
-}\r
-\r
-//! clamp(value,0,1)\r
-static inline const float clampf01(const float v)\r
-{\r
-       return v < 0.f ? 0.f : v > 1.f ? 1.f : v;\r
-}\r
-\r
-// IImage::fill\r
-static void image_fill(irr::video::IImage* image, const irr::video::SColor& color, const interlaced_control interlaced)\r
-{\r
-       if (0 == image)\r
-               return;\r
-\r
-       unsigned int c = color.color;\r
-\r
-       switch (image->getColorFormat())\r
-       {\r
-       case irr::video::ECF_A1R5G5B5:\r
-               c = color.toA1R5G5B5();\r
-               c |= c << 16;\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-       irr::memset32_interlaced(image->getData(), c, image->getPitch(), image->getDimension().Height, interlaced);\r
-}\r
-\r
-\r
-union scale_setup\r
-{\r
-       struct\r
-       {\r
-               unsigned char x : 3;\r
-               unsigned char y : 3;\r
-               unsigned char i : 2;\r
-       };\r
-       unsigned char v;\r
-};\r
-\r
-//setup Antialias. v0.52 uses as Interlaced\r
-void get_scale(scale_setup& s, const irr::SIrrlichtCreationParameters& params)\r
-{\r
-       s.x = 1;\r
-       s.y = 1;\r
-       s.i = 0;\r
-       if (params.AntiAlias && params.WindowSize.Width <= 160 && params.WindowSize.Height <= 120)\r
-       {\r
-               return;\r
-       }\r
-\r
-       switch (params.AntiAlias)\r
-       {\r
-       case 2: s.x = 1; s.y = 1; s.i = 1; break;\r
-       case 4: s.x = 2; s.y = 2; s.i = 0; break;\r
-       case 8: s.x = 2; s.y = 2; s.i = 1; break;\r
-       case 16:s.x = 4; s.y = 4; s.i = 0; break;\r
-       case 32:s.x = 4; s.y = 4; s.i = 1; break;\r
-\r
-       case 3: s.x = 3; s.y = 3; s.i = 0; break;\r
-       case 5: s.x = 3; s.y = 3; s.i = 1; break;\r
-       }\r
-}\r
-\r
-//turn on/off fpu exception\r
-void fpu_exception(int on)\r
-{\r
-       return;\r
-#if defined(_WIN32)\r
-       _clearfp();\r
-       _controlfp(on ? _EM_INEXACT : -1, _MCW_EM);\r
-#endif\r
-}\r
-\r
-namespace irr\r
-{\r
-namespace video\r
-{\r
-\r
-//! constructor\r
-CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter)\r
-       : CNullDriver(io, params.WindowSize), BackBuffer(0), Presenter(presenter),\r
-       WindowId(0), SceneSourceRect(0),\r
-       RenderTargetTexture(0), RenderTargetSurface(0), CurrentShader(0),\r
-       DepthBuffer(0), StencilBuffer(0)\r
-{\r
-       //enable fpu exception\r
-       fpu_exception(1);\r
-\r
-#ifdef _DEBUG\r
-       setDebugName("CBurningVideoDriver");\r
-#endif\r
-\r
-       VertexCache_map_source_format();\r
-\r
-       //Use AntiAlias(hack) to shrink BackBuffer Size and keep ScreenSize the same as Input\r
-       scale_setup scale;\r
-       get_scale(scale, params);\r
-\r
-       //Control Interlaced BackBuffer\r
-       Interlaced.enable = scale.i;\r
-       Interlaced.bypass = !Interlaced.enable;\r
-       Interlaced.nr = 0;\r
-\r
-       // create backbuffer.\r
-       core::dimension2du use(params.WindowSize.Width / scale.x, params.WindowSize.Height / scale.y);\r
-       BackBuffer = new CImage(SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT, use);\r
-       if (BackBuffer)\r
-       {\r
-               //BackBuffer->fill(SColor(0));\r
-               image_fill(BackBuffer, SColor(0), interlace_disabled());\r
-\r
-               // create z buffer\r
-               if (params.ZBufferBits)\r
-                       DepthBuffer = video::createDepthBuffer(BackBuffer->getDimension());\r
-\r
-               // create stencil buffer\r
-               if (params.Stencilbuffer)\r
-                       StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension(), 8);\r
-       }\r
-\r
-       DriverAttributes->setAttribute("MaxIndices", 1 << 16);\r
-       DriverAttributes->setAttribute("MaxTextures", BURNING_MATERIAL_MAX_TEXTURES);\r
-       DriverAttributes->setAttribute("MaxTextureSize", SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE);\r
-       DriverAttributes->setAttribute("MaxLights", 1024); //glsl::gl_MaxLights);\r
-       DriverAttributes->setAttribute("MaxTextureLODBias", 16.f);\r
-       DriverAttributes->setAttribute("Version", 50);\r
-\r
-       // create triangle renderers\r
-\r
-       memset(BurningShader, 0, sizeof(BurningShader));\r
-       //BurningShader[ETR_FLAT] = createTRFlat2(DepthBuffer);\r
-       //BurningShader[ETR_FLAT_WIRE] = createTRFlatWire2(DepthBuffer);\r
-       BurningShader[ETR_GOURAUD] = createTriangleRendererGouraud2(this);\r
-       BurningShader[ETR_GOURAUD_NOZ] = createTriangleRendererGouraudNoZ2(this);\r
-       //BurningShader[ETR_GOURAUD_ALPHA] = createTriangleRendererGouraudAlpha2(this );\r
-       BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(this); // 2D\r
-       //BurningShader[ETR_GOURAUD_WIRE] = createTriangleRendererGouraudWire2(DepthBuffer);\r
-       //BurningShader[ETR_TEXTURE_FLAT] = createTriangleRendererTextureFlat2(DepthBuffer);\r
-       //BurningShader[ETR_TEXTURE_FLAT_WIRE] = createTriangleRendererTextureFlatWire2(DepthBuffer);\r
-       BurningShader[ETR_TEXTURE_GOURAUD] = createTriangleRendererTextureGouraud2(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M1] = createTriangleRendererTextureLightMap2_M1(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M2] = createTriangleRendererTextureLightMap2_M2(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_M4] = createTriangleRendererGTextureLightMap2_M4(this);\r
-       BurningShader[ETR_TEXTURE_LIGHTMAP_M4] = createTriangleRendererTextureLightMap2_M4(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD] = createTriangleRendererTextureLightMap2_Add(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_DETAIL_MAP] = createTriangleRendererTextureDetailMap2(this);\r
-\r
-       BurningShader[ETR_TEXTURE_GOURAUD_WIRE] = createTriangleRendererTextureGouraudWire2(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_NOZ] = createTRTextureGouraudNoZ2(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_ADD] = createTRTextureGouraudAdd2(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_ADD_NO_Z] = createTRTextureGouraudAddNoZ2(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_VERTEX_ALPHA] = createTriangleRendererTextureVertexAlpha2(this);\r
-\r
-       BurningShader[ETR_TEXTURE_GOURAUD_ALPHA] = createTRTextureGouraudAlpha(this);\r
-       BurningShader[ETR_TEXTURE_GOURAUD_ALPHA_NOZ] = createTRTextureGouraudAlphaNoZ(this);\r
-\r
-       BurningShader[ETR_NORMAL_MAP_SOLID] = createTRNormalMap(this);\r
-       BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow(this);\r
-       BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend(this);\r
-\r
-       BurningShader[ETR_TRANSPARENT_REFLECTION_2_LAYER] = createTriangleRendererTexture_transparent_reflection_2_layer(this);\r
-       //BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this );\r
-\r
-       BurningShader[ETR_COLOR] = create_burning_shader_color(this);\r
-\r
-       // add the same renderer for all solid types\r
-       CSoftware2MaterialRenderer_SOLID* smr = new CSoftware2MaterialRenderer_SOLID(this);\r
-       CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR* tmr = new CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR(this);\r
-       //CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this );\r
-\r
-       //!TODO: addMaterialRenderer depends on pushing order....\r
-       addMaterialRenderer(smr); // EMT_SOLID\r
-       addMaterialRenderer(smr); // EMT_SOLID_2_LAYER,\r
-       addMaterialRenderer(smr); // EMT_LIGHTMAP,\r
-       addMaterialRenderer(tmr); // EMT_LIGHTMAP_ADD,\r
-       addMaterialRenderer(smr); // EMT_LIGHTMAP_M2,\r
-       addMaterialRenderer(smr); // EMT_LIGHTMAP_M4,\r
-       addMaterialRenderer(smr); // EMT_LIGHTMAP_LIGHTING,\r
-       addMaterialRenderer(smr); // EMT_LIGHTMAP_LIGHTING_M2,\r
-       addMaterialRenderer(smr); // EMT_LIGHTMAP_LIGHTING_M4,\r
-       addMaterialRenderer(smr); // EMT_DETAIL_MAP,\r
-       addMaterialRenderer(smr); // EMT_SPHERE_MAP,\r
-       addMaterialRenderer(smr); // EMT_REFLECTION_2_LAYER,\r
-       addMaterialRenderer(tmr); // EMT_TRANSPARENT_ADD_COLOR,\r
-       addMaterialRenderer(tmr); // EMT_TRANSPARENT_ALPHA_CHANNEL,\r
-       addMaterialRenderer(tmr); // EMT_TRANSPARENT_ALPHA_CHANNEL_REF,\r
-       addMaterialRenderer(tmr); // EMT_TRANSPARENT_VERTEX_ALPHA,\r
-       addMaterialRenderer(tmr); // EMT_TRANSPARENT_REFLECTION_2_LAYER,\r
-       addMaterialRenderer(smr); // EMT_NORMAL_MAP_SOLID,\r
-       addMaterialRenderer(tmr); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR,\r
-       addMaterialRenderer(tmr); // EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA,\r
-       addMaterialRenderer(smr); // EMT_PARALLAX_MAP_SOLID,\r
-       addMaterialRenderer(tmr); // EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR,\r
-       addMaterialRenderer(tmr); // EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA,\r
-       addMaterialRenderer(tmr); // EMT_ONETEXTURE_BLEND\r
-\r
-       smr->drop();\r
-       tmr->drop();\r
-       //umr->drop ();\r
-\r
-       // select render target\r
-       setRenderTargetImage2(BackBuffer,0, 0);\r
-\r
-       //reset Lightspace\r
-       EyeSpace.reset();\r
-       EyeSpace.resetFog();\r
-\r
-       // select the right renderer\r
-       setMaterial(Material.org);\r
-}\r
-\r
-\r
-//! destructor\r
-CBurningVideoDriver::~CBurningVideoDriver()\r
-{\r
-       // delete Backbuffer\r
-       if (BackBuffer)\r
-       {\r
-               BackBuffer->drop();\r
-               BackBuffer = 0;\r
-       }\r
-\r
-       // delete triangle renderers\r
-       for (s32 i = 0; i < ETR2_COUNT; ++i)\r
-       {\r
-               if (BurningShader[i])\r
-               {\r
-                       BurningShader[i]->drop();\r
-                       BurningShader[i] = 0;\r
-               }\r
-       }\r
-\r
-       // delete Additional buffer\r
-       if (StencilBuffer)\r
-       {\r
-               StencilBuffer->drop();\r
-               StencilBuffer = 0;\r
-       }\r
-\r
-       if (DepthBuffer)\r
-       {\r
-               DepthBuffer->drop();\r
-               DepthBuffer = 0;\r
-       }\r
-\r
-       if (RenderTargetTexture)\r
-       {\r
-               RenderTargetTexture->drop();\r
-               RenderTargetTexture = 0;\r
-       }\r
-\r
-       if (RenderTargetSurface)\r
-       {\r
-               RenderTargetSurface->drop();\r
-               RenderTargetSurface = 0;\r
-       }\r
-\r
-       fpu_exception(0);\r
-\r
-}\r
-\r
-\r
-\r
-//! queries the features of the driver, returns true if feature is available\r
-bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const\r
-{\r
-       int on = 0;\r
-       switch (feature)\r
-       {\r
-#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
-       case EVDF_BILINEAR_FILTER:\r
-               on = 1;\r
-               break;\r
-#endif\r
-#if SOFTWARE_DRIVER_2_MIPMAPPING_MAX > 1\r
-       case EVDF_MIP_MAP:\r
-               on = 1;\r
-               break;\r
-#endif\r
-       case EVDF_STENCIL_BUFFER:\r
-               on = StencilBuffer != 0;\r
-               break;\r
-\r
-       case EVDF_RENDER_TO_TARGET:\r
-       case EVDF_MULTITEXTURE:\r
-       case EVDF_HARDWARE_TL:\r
-       case EVDF_TEXTURE_NSQUARE:\r
-       case EVDF_TEXTURE_MATRIX:\r
-               on = 1;\r
-               break;\r
-\r
-       case EVDF_DEPTH_CLAMP: // shadow\r
-               on = 1;\r
-               break;\r
-\r
-       case EVDF_ARB_FRAGMENT_PROGRAM_1:\r
-       case EVDF_ARB_VERTEX_PROGRAM_1:\r
-               on = 1;\r
-               break;\r
-#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-       case EVDF_TEXTURE_NPOT:\r
-       case EVDF_ARB_GLSL:\r
-               on = 1;\r
-               break;\r
-#else\r
-       case EVDF_TEXTURE_NPOT: // for 2D\r
-               on = 0;\r
-               break;\r
-#endif\r
-\r
-#if defined(SOFTWARE_DRIVER_2_2D_AS_3D)\r
-#if defined(IRRLICHT_FREE_CANVAS)\r
-       case EVDF_VIEWPORT_SCALE_GUI:\r
-               on = 1;\r
-               break;\r
-#endif\r
-#endif\r
-       default:\r
-               on = 0;\r
-               break;\r
-       }\r
-\r
-       return on && FeatureEnabled[feature];\r
-}\r
-\r
-\r
-//matrix multiplication\r
-void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state)\r
-{\r
-       size_t* flag = TransformationFlag[TransformationStack];\r
-       if (flag[state] & ETF_VALID) return;\r
-\r
-       //check\r
-       size_t ok = 0;\r
-       switch (state)\r
-       {\r
-       case ETS_PROJ_MODEL_VIEW:\r
-               if (0 == (flag[ETS_VIEW_PROJECTION] & ETF_VALID)) transform_calc(ETS_VIEW_PROJECTION);\r
-               ok = flag[ETS_WORLD] & flag[ETS_VIEW] & flag[ETS_PROJECTION] & flag[ETS_VIEW_PROJECTION] & ETF_VALID;\r
-               break;\r
-       case ETS_VIEW_PROJECTION:\r
-               ok = flag[ETS_VIEW] & flag[ETS_PROJECTION] & ETF_VALID;\r
-               break;\r
-       case ETS_MODEL_VIEW:\r
-               ok = flag[ETS_WORLD] & flag[ETS_VIEW] & ETF_VALID;\r
-               break;\r
-       case ETS_NORMAL:\r
-               ok = flag[ETS_MODEL_VIEW] & ETF_VALID;\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       if (!ok)\r
-       {\r
-               char buf[256];\r
-               sprintf(buf, "transform_calc not valid for %d\n", state);\r
-               os::Printer::log(buf, ELL_WARNING);\r
-       }\r
-\r
-       core::matrix4* matrix = Transformation[TransformationStack];\r
-\r
-       switch (state)\r
-       {\r
-       case ETS_PROJ_MODEL_VIEW:\r
-               if (flag[ETS_WORLD] & ETF_IDENTITY)\r
-               {\r
-                       matrix[state] = matrix[ETS_VIEW_PROJECTION];\r
-               }\r
-               else\r
-               {\r
-                       matrix[state].setbyproduct_nocheck(matrix[ETS_VIEW_PROJECTION], matrix[ETS_WORLD]);\r
-               }\r
-               break;\r
-\r
-       case ETS_VIEW_PROJECTION:\r
-               matrix[state].setbyproduct_nocheck(matrix[ETS_PROJECTION], matrix[ETS_VIEW]);\r
-               break;\r
-       case ETS_MODEL_VIEW:\r
-               if (flag[ETS_WORLD] & ETF_IDENTITY)\r
-               {\r
-                       matrix[state] = matrix[ETS_VIEW];\r
-               }\r
-               else\r
-               {\r
-                       matrix[state].setbyproduct_nocheck(matrix[ETS_VIEW], matrix[ETS_WORLD]);\r
-               }\r
-               break;\r
-       case ETS_NORMAL:\r
-               mat44_transposed_inverse(matrix[state], matrix[ETS_MODEL_VIEW]);\r
-               break;\r
-\r
-       default:\r
-               break;\r
-       }\r
-       flag[state] |= ETF_VALID;\r
-}\r
-\r
-\r
-//! sets transformation\r
-void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)\r
-{\r
-       size_t* flag = TransformationFlag[TransformationStack];\r
-       core::matrix4* matrix = Transformation[TransformationStack];\r
-\r
-#if 0\r
-       int changed = 1;\r
-       if (flag[state] & ETF_VALID)\r
-       {\r
-               changed = memcmp(mat.pointer(), matrix[state].pointer(), sizeof(mat));\r
-       }\r
-       if (changed)\r
-#endif\r
-       {\r
-               matrix[state] = mat;\r
-               flag[state] |= ETF_VALID;\r
-       }\r
-\r
-       //maybe identity (mostly for texturematrix to avoid costly multiplication)\r
-#if defined ( USE_MATRIX_TEST )\r
-       burning_setbit(TransformationFlag[state], mat.getDefinitelyIdentityMatrix(), ETF_IDENTITY);\r
-#else\r
-       burning_setbit(flag[state],\r
-               !memcmp(mat.pointer(), core::IdentityMatrix.pointer(), sizeof(mat)), ETF_IDENTITY\r
-       );\r
-#endif\r
-\r
-#if 0\r
-       if (changed)\r
-#endif\r
-               switch (state)\r
-               {\r
-               case ETS_PROJECTION:\r
-                       flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;\r
-                       flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID;\r
-                       break;\r
-               case ETS_VIEW:\r
-                       flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;\r
-                       flag[ETS_VIEW_PROJECTION] &= ~ETF_VALID;\r
-                       flag[ETS_MODEL_VIEW] &= ~ETF_VALID;\r
-                       flag[ETS_NORMAL] &= ~ETF_VALID;\r
-                       break;\r
-               case ETS_WORLD:\r
-                       flag[ETS_PROJ_MODEL_VIEW] &= ~ETF_VALID;\r
-                       flag[ETS_MODEL_VIEW] &= ~ETF_VALID;\r
-                       flag[ETS_NORMAL] &= ~ETF_VALID;\r
-                       break;\r
-               case ETS_TEXTURE_0:\r
-               case ETS_TEXTURE_1:\r
-               case ETS_TEXTURE_2:\r
-               case ETS_TEXTURE_3:\r
-#if _IRR_MATERIAL_MAX_TEXTURES_>4\r
-               case ETS_TEXTURE_4:\r
-#endif\r
-#if _IRR_MATERIAL_MAX_TEXTURES_>5\r
-               case ETS_TEXTURE_5:\r
-#endif\r
-#if _IRR_MATERIAL_MAX_TEXTURES_>6\r
-               case ETS_TEXTURE_6:\r
-#endif\r
-#if _IRR_MATERIAL_MAX_TEXTURES_>7\r
-               case ETS_TEXTURE_7:\r
-#endif\r
-                       if (0 == (flag[state] & ETF_IDENTITY))\r
-                       {\r
-                               EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;\r
-                       }\r
-                       break;\r
-               default:\r
-                       break;\r
-               }\r
-\r
-}\r
-\r
-//! Returns the transformation set by setTransform\r
-const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const\r
-{\r
-       return Transformation[TransformationStack][state];\r
-}\r
-\r
-\r
-bool CBurningVideoDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* sourceRect)\r
-{\r
-#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-       CNullDriver::beginScene(clearFlag & ECBF_COLOR, clearFlag & ECBF_DEPTH, clearColor, videoData, sourceRect);\r
-#else\r
-       CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);\r
-#endif\r
-\r
-       Interlaced.nr = (Interlaced.nr + 1) & interlace_control_mask;\r
-       WindowId = videoData.D3D9.HWnd;\r
-       SceneSourceRect = sourceRect;\r
-\r
-       clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);\r
-\r
-       //memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) );\r
-       return true;\r
-}\r
-\r
-bool CBurningVideoDriver::endScene()\r
-{\r
-       CNullDriver::endScene();\r
-\r
-       return Presenter->present(BackBuffer, WindowId, SceneSourceRect);\r
-}\r
-\r
-\r
-//! Create render target.\r
-IRenderTarget* CBurningVideoDriver::addRenderTarget()\r
-{\r
-       CSoftwareRenderTarget2* renderTarget = new CSoftwareRenderTarget2(this);\r
-       RenderTargets.push_back(renderTarget);\r
-\r
-       return renderTarget;\r
-}\r
-\r
-#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-bool CBurningVideoDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, bool clearZBuffer, SColor color)\r
-{\r
-       CSoftwareRenderTarget2 target(this);\r
-       target.RenderTexture = texture;\r
-       target.TargetType = ERT_RENDER_TEXTURE;\r
-       target.Texture[0] = texture;\r
-\r
-       if (texture)\r
-               texture->grab();\r
-\r
-       u16 flag = 0;\r
-       if (clearBackBuffer) flag |= ECBF_COLOR;\r
-       if (clearZBuffer) flag |= ECBF_DEPTH;\r
-\r
-       return setRenderTargetEx(texture ? &target : 0, flag, color, 1.f, true);\r
-}\r
-#endif\r
-\r
-bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)\r
-{\r
-#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-       if (target && target->getDriverType() != EDT_BURNINGSVIDEO)\r
-       {\r
-               os::Printer::log("Fatal Error: Tried to set a render target not owned by this driver.", ELL_ERROR);\r
-               return false;\r
-       }\r
-#endif\r
-       if (RenderTargetTexture)\r
-       {\r
-               //switching from texture to backbuffer\r
-               if (target == 0)\r
-               {\r
-                       RenderTargetTexture->regenerateMipMapLevels();\r
-               }\r
-               RenderTargetTexture->drop();\r
-       }\r
-\r
-#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-       RenderTargetTexture = target ? target->getTexture()[0] : 0;\r
-#else\r
-       RenderTargetTexture = target ? ((CSoftwareRenderTarget2*)target)->Texture[0] : 0;\r
-#endif\r
-\r
-       if (RenderTargetTexture)\r
-       {\r
-               RenderTargetTexture->grab();\r
-               Interlaced.bypass = 1;\r
-               setRenderTargetImage2(((CSoftwareTexture2*)RenderTargetTexture)->getImage());\r
-       }\r
-       else\r
-       {\r
-               Interlaced.bypass = !Interlaced.enable;\r
-               setRenderTargetImage2(BackBuffer);\r
-       }\r
-\r
-       clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);\r
-\r
-       return true;\r
-}\r
-\r
-static inline f32 map_value(f32 x, f32 in_min, f32 in_max, f32 out_min, f32 out_max) {\r
-       return (x - in_min) * (out_max - out_min) / (f32)(in_max - in_min) + out_min;\r
-}\r
-\r
-//! sets a render target\r
-void CBurningVideoDriver::setRenderTargetImage2(video::IImage* color, video::IImage* depth, video::IImage* stencil)\r
-{\r
-       if (RenderTargetSurface)\r
-               RenderTargetSurface->drop();\r
-\r
-       core::dimension2d<u32> current = RenderTargetSize;\r
-       RenderTargetSurface = color;\r
-       RenderTargetSize.Width = 0;\r
-       RenderTargetSize.Height = 0;\r
-\r
-       if (RenderTargetSurface)\r
-       {\r
-               RenderTargetSurface->grab();\r
-               RenderTargetSize = RenderTargetSurface->getDimension();\r
-       }\r
-\r
-       RatioRenderTargetScreen.x = ScreenSize.Width ? (f32)RenderTargetSize.Width / ScreenSize.Width : 1.f;\r
-       RatioRenderTargetScreen.y = ScreenSize.Height ? (f32)RenderTargetSize.Height / ScreenSize.Height : 1.f;\r
-\r
-       int not_changed = current == RenderTargetSize;\r
-       burning_setbit(TransformationFlag[0][ETS_PROJECTION], not_changed, ETF_VALID);\r
-       burning_setbit(TransformationFlag[1][ETS_PROJECTION], not_changed, ETF_VALID);\r
-\r
-       setViewPort(core::recti(RenderTargetSize));\r
-\r
-       if (DepthBuffer)\r
-               DepthBuffer->setSize(RenderTargetSize);\r
-\r
-       if (StencilBuffer)\r
-               StencilBuffer->setSize(RenderTargetSize);\r
-}\r
-\r
-\r
-//--------- Transform from NDC to DC, transform TexCoo ----------------------------------------------\r
-\r
-\r
-//! Blur 2D Image with PixelOffset. (default 0.375f for OpenGL and Burning)\r
-/** SideEffects:\r
-* if IRRLICHT_2D_TEXEL_OFFSET > 0 is applied to OpenGL/Burning, Pixel-exact Texture Coordinates do not match.\r
-* Currently Version 1.8,1.9 has that in the Irrlicht 2D Examples where you get a Magenta Border on the Sprites\r
-* and in the draw2DImage4cFilter Tests\r
-*/\r
-#define IRRLICHT_2D_TEXEL_OFFSET 0.f\r
-\r
-\r
-//--------- Transform from NDC to DC ----------------------------------------------\r
-\r
-// used to scale <-1,-1><1,1> to viewport [center,scale]\r
-// controls subtexel and fill convention.\r
-// Don't tweak SOFTWARE_DRIVER_2_SUBTEXEL (-0.5f in m[1]) anymore to control texture blur effect, it's used for viewport scaling. \r
-// naming is misleading. it will write outside memory location..\r
-\r
-void buildNDCToDCMatrix(f32* m, const core::rect<s32>& viewport, f32 tx)\r
-{\r
-       m[0] = (viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X + tx) * 0.5f;\r
-       m[1] = (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X-1) * 0.5f;\r
-\r
-       m[2] = (viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y + tx) * -0.5f;\r
-       m[3] = (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y-1) * 0.5f;\r
-}\r
-\r
-\r
-\r
-//! sets a viewport\r
-void CBurningVideoDriver::setViewPort(const core::rect<s32>& area)\r
-{\r
-       ViewPort = area;\r
-\r
-       core::rect<s32> rendert(0, 0, RenderTargetSize.Width, RenderTargetSize.Height);\r
-       ViewPort.clipAgainst(rendert);\r
-\r
-       buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[0], ViewPort, 1.f/2048.f); //SkyBox,Billboard 90° problem\r
-       buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[1], ViewPort, 0.f); // OverrideMaterial2DEnabled ? -IRRLICHT_2D_TEXEL_OFFSET : 0.f);\r
-\r
-       if (CurrentShader)\r
-               CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced);\r
-}\r
-\r
-void CBurningVideoDriver::setScissor(int x, int y, int width, int height)\r
-{\r
-       //openGL\r
-       //y = rt.Height - y - height;\r
-\r
-       //coming from GUI\r
-       AbsRectangle v0;\r
-       v0.x0 = core::floor32(x * RatioRenderTargetScreen.x);\r
-       v0.y0 = core::floor32(y * RatioRenderTargetScreen.y);\r
-       v0.x1 = core::floor32((x + width) * RatioRenderTargetScreen.x);\r
-       v0.y1 = core::floor32((y + height) * RatioRenderTargetScreen.y);\r
-\r
-       AbsRectangle v1;\r
-       v1.x0 = 0;\r
-       v1.y0 = 0;\r
-       v1.x1 = RenderTargetSize.Width;\r
-       v1.y1 = RenderTargetSize.Height;\r
-\r
-       intersect(Scissor, v0, v1);\r
-}\r
-\r
-/*\r
-       generic plane clipping in homogenous coordinates\r
-       special case ndc frustum <-w,w>,<-w,w>,<-w,w>\r
-       can be rewritten with compares e.q near plane, a.z < -a.w and b.z < -b.w\r
-\r
-       cam is (0,0,-1)\r
-*/\r
-\r
-const sVec4 CBurningVideoDriver::NDCPlane[6 + 2] =\r
-{\r
-       sVec4(0.f,  0.f, -1.f, -1.f),   // near\r
-       sVec4(0.f,  0.f,  1.f, -1.f),   // far\r
-       sVec4(1.f,  0.f,  0.f, -1.f),   // left\r
-       sVec4(-1.f,  0.f,  0.f, -1.f),  // right\r
-       sVec4(0.f,  1.f,  0.f, -1.f),   // bottom\r
-       sVec4(0.f, -1.f,  0.f, -1.f)            // top\r
-};\r
-\r
-\r
-/*\r
-       test a vertex if it's inside the standard frustum\r
-\r
-       this is the generic one..\r
-\r
-       f32 dotPlane;\r
-       for ( u32 i = 0; i!= 6; ++i )\r
-       {\r
-               dotPlane = v->Pos.dotProduct ( NDCPlane[i] );\r
-               burning_setbit32( flag, dotPlane <= 0.f, 1 << i );\r
-       }\r
-\r
-       // this is the base for ndc frustum <-w,w>,<-w,w>,<-w,w>\r
-       burning_setbit32( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );\r
-       burning_setbit32( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );\r
-       burning_setbit32( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );\r
-       burning_setbit32( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );\r
-       burning_setbit32( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );\r
-       burning_setbit32( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );\r
-\r
-*/\r
-#ifdef IRRLICHT_FAST_MATH\r
-\r
-REALINLINE size_t CBurningVideoDriver::clipToFrustumTest(const s4DVertex* v) const\r
-{\r
-       size_t flag;\r
-       f32 test[8];\r
-       const f32 w = -v->Pos.w;\r
-\r
-       // a conditional move is needed....FCOMI ( but we don't have it )\r
-       // so let the fpu calculate and write it back.\r
-       // cpu makes the compare, interleaving\r
-\r
-       test[0] = v->Pos.z + w;\r
-       test[1] = -v->Pos.z + w;\r
-       test[2] = v->Pos.x + w;\r
-       test[3] = -v->Pos.x + w;\r
-       test[4] = v->Pos.y + w;\r
-       test[5] = -v->Pos.y + w;\r
-\r
-       const u32* a = F32_AS_U32_POINTER(test);\r
-       flag = (a[0]) >> 31;\r
-       flag |= (a[1] & 0x80000000) >> 30;\r
-       flag |= (a[2] & 0x80000000) >> 29;\r
-       flag |= (a[3] & 0x80000000) >> 28;\r
-       flag |= (a[4] & 0x80000000) >> 27;\r
-       flag |= (a[5] & 0x80000000) >> 26;\r
-\r
-       /*\r
-               flag  = (IR ( test[0] )              ) >> 31;\r
-               flag |= (IR ( test[1] ) & 0x80000000 ) >> 30;\r
-               flag |= (IR ( test[2] ) & 0x80000000 ) >> 29;\r
-               flag |= (IR ( test[3] ) & 0x80000000 ) >> 28;\r
-               flag |= (IR ( test[4] ) & 0x80000000 ) >> 27;\r
-               flag |= (IR ( test[5] ) & 0x80000000 ) >> 26;\r
-       */\r
-       /*\r
-               flag  = F32_LOWER_EQUAL_0 ( test[0] );\r
-               flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1;\r
-               flag |= F32_LOWER_EQUAL_0 ( test[2] ) << 2;\r
-               flag |= F32_LOWER_EQUAL_0 ( test[3] ) << 3;\r
-               flag |= F32_LOWER_EQUAL_0 ( test[4] ) << 4;\r
-               flag |= F32_LOWER_EQUAL_0 ( test[5] ) << 5;\r
-       */\r
-       return flag;\r
-}\r
-\r
-#else\r
-\r
-\r
-REALINLINE size_t clipToFrustumTest(const s4DVertex* v)\r
-{\r
-       size_t flag = 0;\r
-\r
-       flag |= v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_NEAR : 0;\r
-       flag |= -v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_FAR : 0;\r
-\r
-       flag |= v->Pos.x <= v->Pos.w ? VERTEX4D_CLIP_LEFT : 0;\r
-       flag |= -v->Pos.x <= v->Pos.w ? VERTEX4D_CLIP_RIGHT : 0;\r
-\r
-       flag |= v->Pos.y <= v->Pos.w ? VERTEX4D_CLIP_BOTTOM : 0;\r
-       flag |= -v->Pos.y <= v->Pos.w ? VERTEX4D_CLIP_TOP : 0;\r
-\r
-\r
-       /*\r
-               for ( u32 i = 0; i <= 6; ++i )\r
-               {\r
-                       if (v->Pos.dot_xyzw(NDCPlane[i]) <= 0.f) flag |= ((size_t)1) << i;\r
-               }\r
-       */\r
-       return flag;\r
-}\r
-\r
-#endif // _MSC_VER\r
-\r
-\r
-size_t clipToHyperPlane(\r
-       s4DVertexPair* burning_restrict dest,\r
-       const s4DVertexPair* burning_restrict source,\r
-       const size_t inCount,\r
-       const sVec4& plane\r
-)\r
-{\r
-       size_t outCount = 0;\r
-       s4DVertexPair* out = dest;\r
-\r
-       const s4DVertex* a;\r
-       const s4DVertex* b = source;\r
-\r
-       ipoltype bDotPlane;\r
-       bDotPlane = b->Pos.dot_xyzw(plane);\r
-\r
-       /*\r
-               for( u32 i = 1; i < inCount + 1; ++i)\r
-               {\r
-       #if 0\r
-                       a = source + (i%inCount)*2;\r
-       #else\r
-                       const s32 condition = i - inCount;\r
-                       const s32 index = (( ( condition >> 31 ) & ( i ^ condition ) ) ^ condition ) << 1;\r
-                       a = source + index;\r
-       #endif\r
-       */\r
-       //Sutherland\96Hodgman\r
-       for (size_t i = 0; i < inCount; ++i)\r
-       {\r
-               a = source + (i == inCount - 1 ? 0 : s4DVertex_ofs(i + 1));\r
-\r
-               // current point inside\r
-               if (ipol_lower_equal_0(a->Pos.dot_xyzw(plane)))\r
-               {\r
-                       // last point outside\r
-                       if (ipol_greater_0(bDotPlane))\r
-                       {\r
-                               // intersect line segment with plane\r
-                               out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane));\r
-                               out += sizeof_s4DVertexPairRel;\r
-                               outCount += 1;\r
-                       }\r
-\r
-                       // copy current to out\r
-                       //*out = *a;\r
-                       memcpy_s4DVertexPair(out, a);\r
-                       b = out;\r
-\r
-                       out += sizeof_s4DVertexPairRel;\r
-                       outCount += 1;\r
-               }\r
-               else\r
-               {\r
-                       // current point outside\r
-                       if (ipol_lower_equal_0(bDotPlane))\r
-                       {\r
-                               // previous was inside\r
-                               // intersect line segment with plane\r
-                               out->interpolate(*b, *a, bDotPlane / (b->Pos - a->Pos).dot_xyzw(plane));\r
-                               out += sizeof_s4DVertexPairRel;\r
-                               outCount += 1;\r
-                       }\r
-                       // pointer\r
-                       b = a;\r
-               }\r
-\r
-               bDotPlane = b->Pos.dot_xyzw(plane);\r
-       }\r
-\r
-       return outCount;\r
-}\r
-\r
-\r
-/*\r
-       Clip on all planes. Clipper.data\r
-       clipmask per face\r
-*/\r
-size_t CBurningVideoDriver::clipToFrustum(const size_t vIn /*, const size_t clipmask_for_face*/)\r
-{\r
-       s4DVertexPair* v0 = Clipper.data;\r
-       s4DVertexPair* v1 = Clipper_temp.data;\r
-       size_t vOut = vIn;\r
-\r
-       //clear all clipping & projected flags\r
-       const u32 flag = v0[0].flag & VERTEX4D_FORMAT_MASK;\r
-       for (size_t g = 0; g != Clipper.ElementSize; ++g)\r
-       {\r
-               v0[g].flag = flag;\r
-               v1[g].flag = flag;\r
-       }\r
-\r
-#if 0\r
-       for (size_t i = 0; i < 6; ++i)\r
-       {\r
-               v0 = i & 1 ? Clipper_temp.data : Clipper.data;\r
-               v1 = i & 1 ? Clipper.data : Clipper_temp.data;\r
-\r
-               //clipMask checked outside - always clip all planes\r
-#if 0\r
-               if (0 == (clipMask & ((size_t)1 << i)))\r
-               {\r
-                       vOut = vIn;\r
-                       memcpy_s4DVertexPair(v1, v0);\r
-               }\r
-               else\r
-#endif\r
-               {\r
-                       vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[i]);\r
-                       if (vOut < vIn) return vOut;\r
-               }\r
-       }\r
-#endif\r
-\r
-\r
-       vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[0]); if (vOut < vIn) return  vOut;\r
-       vOut = clipToHyperPlane(v0, v1, vOut, NDCPlane[1]); if (vOut < vIn) return vOut;\r
-       vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[2]); if (vOut < vIn) return vOut;\r
-       vOut = clipToHyperPlane(v0, v1, vOut, NDCPlane[3]); if (vOut < vIn) return vOut;\r
-       vOut = clipToHyperPlane(v1, v0, vOut, NDCPlane[4]); if (vOut < vIn) return vOut;\r
-       vOut = clipToHyperPlane(v0, v1, vOut, NDCPlane[5]);\r
-\r
-       return vOut;\r
-}\r
-\r
-/*!\r
-       Part I:\r
-       apply Clip Scale matrix\r
-       From Normalized Device Coordiante ( NDC ) Space to Device Coordinate ( DC ) Space\r
-\r
-       Part II:\r
-       Project homogeneous vector\r
-       homogeneous to non-homogenous coordinates ( dividebyW )\r
-\r
-       Incoming: ( xw, yw, zw, w, u, v, 1, R, G, B, A )\r
-       Outgoing: ( xw/w, yw/w, zw/w, w/w, u/w, v/w, 1/w, R/w, G/w, B/w, A/w )\r
-\r
-       replace w/w by 1/w\r
-*/\r
-//aliasing problems! [dest = source + 1]\r
-inline void CBurningVideoDriver::ndc_2_dc_and_project(s4DVertexPair* dest, const s4DVertexPair* source, const size_t vIn) const\r
-{\r
-       const f32* dc = Transformation_ETS_CLIPSCALE[TransformationStack];\r
-\r
-       for (size_t g = 0; g != vIn; g += sizeof_s4DVertexPairRel)\r
-       {\r
-               //cache doesn't work anymore?\r
-               //if ( dest[g].flag & VERTEX4D_PROJECTED )\r
-               //      continue;\r
-               //dest[g].flag = source[g].flag | VERTEX4D_PROJECTED;\r
-\r
-               const f32 iw = reciprocal_zero(source[g].Pos.w);\r
-\r
-               // to device coordinates\r
-               dest[g].Pos.x = iw * source[g].Pos.x * dc[0] + dc[1];\r
-               dest[g].Pos.y = iw * source[g].Pos.y * dc[2] + dc[3];\r
-\r
-               //burning uses direct Z. for OpenGL it should be -Z,[-1;1] and texture flip\r
-#if !defined(SOFTWARE_DRIVER_2_USE_WBUFFER) || 1\r
-               dest[g].Pos.z = -iw * source[g].Pos.z * 0.5f + 0.5f;\r
-#endif\r
-               dest[g].Pos.w = iw;\r
-\r
-               // Texture Coordinates will be projected after mipmap selection\r
-               // satisfy write-combiner\r
-#if 1\r
-#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
-               dest[g].Tex[0] = source[g].Tex[0];\r
-#endif\r
-#if BURNING_MATERIAL_MAX_TEXTURES > 1\r
-               dest[g].Tex[1] = source[g].Tex[1];\r
-#endif\r
-#if BURNING_MATERIAL_MAX_TEXTURES > 2\r
-               dest[g].Tex[2] = source[g].Tex[2];\r
-#endif\r
-#if BURNING_MATERIAL_MAX_TEXTURES > 3\r
-               dest[g].Tex[3] = source[g].Tex[3];\r
-#endif\r
-\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 0\r
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-               dest[g].Color[0] = source[g].Color[0] * iw; // alpha?\r
-#else\r
-               dest[g].Color[0] = source[g].Color[0];\r
-#endif\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 1\r
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-               dest[g].Color[1] = source[g].Color[1] * iw; // alpha?\r
-#else\r
-               dest[g].Color[1] = source[g].Color[1];\r
-#endif\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 2\r
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-               dest[g].Color[2] = source[g].Color[2] * iw; // alpha?\r
-#else\r
-               dest[g].Color[2] = source[g].Color[2];\r
-#endif\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 3\r
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-               dest[g].Color[3] = source[g].Color[3] * iw; // alpha?\r
-#else\r
-               dest[g].Color[3] = source[g].Color[3];\r
-#endif\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
-               dest[g].LightTangent[0] = source[g].LightTangent[0] * iw;\r
-#endif\r
-\r
-       }\r
-}\r
-\r
-\r
-\r
-#if 0\r
-/*!\r
-       crossproduct in projected 2D, face\r
-*/\r
-REALINLINE f32 CBurningVideoDriver::screenarea_inside(const s4DVertexPair* burning_restrict const face[]) const\r
-{\r
-       return  (((face[1] + 1)->Pos.x - (face[0] + 1)->Pos.x) * ((face[2] + 1)->Pos.y - (face[0] + 1)->Pos.y)) -\r
-               (((face[2] + 1)->Pos.x - (face[0] + 1)->Pos.x) * ((face[1] + 1)->Pos.y - (face[0] + 1)->Pos.y));\r
-       /*\r
-               float signedArea = 0;\r
-               for (int k = 1; k < output->count; k++) {\r
-                       signedArea += (output->vertices[k - 1].values[0] * output->vertices[k - 0].values[1]);\r
-                       signedArea -= (output->vertices[k - 0].values[0] * output->vertices[k - 1].values[1]);\r
-               }\r
-       */\r
-}\r
-\r
-\r
-static inline f32 dot(const sVec2& a, const sVec2& b) { return a.x * b.x + a.y * b.y; }\r
-sVec2 dFdx(const sVec2& v) { return v; }\r
-sVec2 dFdy(const sVec2& v) { return v; }\r
-\r
-f32 MipmapLevel(const sVec2& uv, const sVec2& textureSize)\r
-{\r
-       sVec2 dx = dFdx(uv * textureSize.x);\r
-       sVec2 dy = dFdy(uv * textureSize.y);\r
-       f32 d = core::max_(dot(dx, dx), dot(dy, dy));\r
-       return log2f(sqrtf(d));\r
-}\r
-#endif\r
-\r
-//#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( (u32)tex ) )\r
-#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.TextureLayer[tex].Texture )\r
-\r
-/*!\r
-       calculate from unprojected.\r
-       attribute need not to follow winding rule from position.\r
-       Edge-walking problem\r
-       Texture Wrapping problem\r
-       Atlas problem\r
-*/\r
-REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burning_restrict const face[],\r
-       const size_t m, const f32 dc_area, const f32 lod_bias) const\r
-{\r
-       /*\r
-               sVec2 a(v[1]->Tex[tex].x - v[0]->Tex[tex].x,v[1]->Tex[tex].y - v[0]->Tex[tex].y);\r
-               sVec2 b(v[2]->Tex[tex].x - v[0]->Tex[tex].x,v[2]->Tex[tex].y - v[0]->Tex[tex].y);\r
-               f32 area = a.x * b.y - b.x * a.y;\r
-       */\r
-\r
-\r
-       /*\r
-               degenerate(A, B, C, minarea) = ((B - A).cross(C - A)).lengthSquared() < (4.0f * minarea * minarea);\r
-               check for collapsed or "long thin triangles"\r
-       */\r
-       ieee754 signedArea;\r
-\r
-       ieee754 t[4];\r
-       t[0].f = face[1]->Tex[m].x - face[0]->Tex[m].x;\r
-       t[1].f = face[1]->Tex[m].y - face[0]->Tex[m].y;\r
-\r
-       t[2].f = face[2]->Tex[m].x - face[0]->Tex[m].x;\r
-       t[3].f = face[2]->Tex[m].y - face[0]->Tex[m].y;\r
-\r
-       //crossproduct in projected 2D -> screen area triangle\r
-       signedArea.f = t[0].f * t[3].f - t[2].f * t[1].f;\r
-\r
-       //signedArea =\r
-       //        ((face[1]->Tex[m].x - face[0]->Tex[m].x) * (face[2]->Tex[m].y - face[0]->Tex[m].y))\r
-       //      - ((face[2]->Tex[m].x - face[0]->Tex[m].x) * (face[1]->Tex[m].y - face[0]->Tex[m].y));\r
-\r
-       //if (signedArea*signedArea <= 0.00000000001f)\r
-       if (signedArea.fields.exp == 0)\r
-       {\r
-               ieee754 _max;\r
-               _max.u = t[0].abs.frac_exp;\r
-               if (t[1].abs.frac_exp > _max.u) _max.u = t[1].abs.frac_exp;\r
-               if (t[2].abs.frac_exp > _max.u) _max.u = t[2].abs.frac_exp;\r
-               if (t[3].abs.frac_exp > _max.u) _max.u = t[3].abs.frac_exp;\r
-\r
-               signedArea.u = _max.fields.exp ? _max.u : ieee754_one;\r
-\r
-               /*\r
-                               //dot,length\r
-                               ieee754 v[2];\r
-                               v[0].f = t[0] * t[2];\r
-                               v[1].f = t[1] * t[3];\r
-\r
-                               //signedArea.f = t[4] > t[5] ? t[4] : t[5];\r
-                               signedArea.u = v[0].fields.frac > v[1].fields.frac ? v[0].u : v[1].u;\r
-                               if (signedArea.fields.exp == 0)\r
-                               {\r
-                                       return -1;\r
-                               }\r
-               */\r
-       }\r
-\r
-       //only guessing: take more detail (lower mipmap) in light+bump textures\r
-       //assume transparent add is ~50% transparent -> more detail\r
-\r
-       // 2.f from dc_area, 2.f from tex triangle ( parallelogram area)\r
-       const u32* d = MAT_TEXTURE(m)->getMipMap0_Area();\r
-       f32 texelspace = d[0] * d[1] * lod_bias; //(m ? 0.5f : 0.5f);\r
-\r
-       ieee754 ratio;\r
-       ratio.f = (signedArea.f * texelspace) * dc_area;\r
-       ratio.fields.sign = 0;\r
-\r
-       //log2(0)==denormal [ use high lod] [ only if dc_area == 0 checked outside ]\r
-       return (ratio.fields.exp & 0x80) ? ratio.fields.exp - 127 : 0; /*denormal very high lod*/\r
-\r
-}\r
-\r
-\r
-/*!\r
-       texcoo in current mipmap dimension (face, already clipped)\r
-       -> want to help fixpoint\r
-*/\r
-inline void CBurningVideoDriver::select_polygon_mipmap_inside(s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b) const\r
-{\r
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-       (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * (face[0] + 1)->Pos.w * b.w + b.cx;\r
-       (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * (face[0] + 1)->Pos.w * b.h + b.cy;\r
-\r
-       (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * (face[1] + 1)->Pos.w * b.w + b.cx;\r
-       (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * (face[1] + 1)->Pos.w * b.h + b.cy;\r
-\r
-       (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * (face[2] + 1)->Pos.w * b.w + b.cx;\r
-       (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * (face[2] + 1)->Pos.w * b.h + b.cy;\r
-#else\r
-       (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * b.w;\r
-       (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * b.h;\r
-\r
-       (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * b.w;\r
-       (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * b.h;\r
-\r
-       (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * b.w;\r
-       (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * b.h;\r
-#endif\r
-\r
-}\r
-\r
-\r
-// Vertex Cache\r
-\r
-//! setup Vertex Format\r
-void CBurningVideoDriver::VertexCache_map_source_format()\r
-{\r
-       u32 s0 = sizeof(s4DVertex);\r
-       u32 s1 = sizeof(s4DVertex_proxy);\r
-\r
-       if (s1 <= sizeof_s4DVertex / 2)\r
-       {\r
-               os::Printer::log("BurningVideo vertex format unnecessary to large", ELL_WARNING);\r
-       }\r
-\r
-       //memcpy_vertex\r
-       if (s0 != sizeof_s4DVertex || ((sizeof_s4DVertex * sizeof_s4DVertexPairRel) & 31))\r
-       {\r
-               os::Printer::log("BurningVideo vertex format compile problem", ELL_ERROR);\r
-               _IRR_DEBUG_BREAK_IF(1);\r
-       }\r
-\r
-#if defined(ENV64BIT)\r
-       if (sizeof(void*) != 8)\r
-       {\r
-               os::Printer::log("BurningVideo pointer should be 8 bytes", ELL_ERROR);\r
-               _IRR_DEBUG_BREAK_IF(1);\r
-       }\r
-\r
-       if (((unsigned long long)Transformation&15) || ((unsigned long long)TransformationFlag & 15))\r
-       {\r
-               os::Printer::log("BurningVideo Matrix Stack not 16 byte aligned", ELL_ERROR);\r
-               _IRR_DEBUG_BREAK_IF(1);\r
-       }\r
-#endif\r
-\r
-\r
-       SVSize* vSize = VertexCache.vSize;\r
-       //vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_SPECULAR;\r
-       vSize[E4VT_STANDARD].Format = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_2_FOG;\r
-       vSize[E4VT_STANDARD].Pitch = sizeof(S3DVertex);\r
-       vSize[E4VT_STANDARD].TexSize = 1;\r
-       vSize[E4VT_STANDARD].TexCooSize = 1;\r
-\r
-       vSize[E4VT_2TCOORDS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1;\r
-       vSize[E4VT_2TCOORDS].Pitch = sizeof(S3DVertex2TCoords);\r
-       vSize[E4VT_2TCOORDS].TexSize = 2;\r
-       vSize[E4VT_2TCOORDS].TexCooSize = 2;\r
-\r
-       //vSize[E4VT_TANGENTS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_BUMP_DOT3;\r
-       vSize[E4VT_TANGENTS].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_2_FOG | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_BUMP_DOT3;\r
-       vSize[E4VT_TANGENTS].Pitch = sizeof(S3DVertexTangents);\r
-       vSize[E4VT_TANGENTS].TexSize = 2;\r
-       vSize[E4VT_TANGENTS].TexCooSize = 2;\r
-\r
-       // reflection map\r
-       vSize[E4VT_REFLECTION_MAP].Format = VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1;\r
-       vSize[E4VT_REFLECTION_MAP].Pitch = sizeof(S3DVertex);\r
-       vSize[E4VT_REFLECTION_MAP].TexSize = 2;\r
-       vSize[E4VT_REFLECTION_MAP].TexCooSize = 1; //TexCoo2 generated\r
-\r
-       // shadow\r
-       vSize[E4VT_SHADOW].Format = 0;\r
-       vSize[E4VT_SHADOW].Pitch = sizeof(f32) * 3; // core::vector3df*\r
-       vSize[E4VT_SHADOW].TexSize = 0;\r
-       vSize[E4VT_SHADOW].TexCooSize = 0;\r
-\r
-       // color shading only (no texture)\r
-       vSize[E4VT_NO_TEXTURE].Format = VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_LIGHT_1 | VERTEX4D_FORMAT_SPECULAR;\r
-       vSize[E4VT_NO_TEXTURE].Pitch = sizeof(S3DVertex);\r
-       vSize[E4VT_NO_TEXTURE].TexSize = 0;\r
-       vSize[E4VT_NO_TEXTURE].TexCooSize = 0;\r
-\r
-       //Line\r
-       vSize[E4VT_LINE].Format = VERTEX4D_FORMAT_COLOR_1;\r
-       vSize[E4VT_LINE].Pitch = sizeof(S3DVertex);\r
-       vSize[E4VT_LINE].TexSize = 0;\r
-       vSize[E4VT_LINE].TexCooSize = 0;\r
-\r
-       size_t size;\r
-       for (size_t i = 0; i < E4VT_COUNT; ++i)\r
-       {\r
-               size_t& flag = vSize[i].Format;\r
-\r
-#if !defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR)\r
-               flag &= ~VERTEX4D_FORMAT_SPECULAR;\r
-#endif\r
-               if (vSize[i].TexSize > BURNING_MATERIAL_MAX_TEXTURES)\r
-                       vSize[i].TexSize = BURNING_MATERIAL_MAX_TEXTURES;\r
-\r
-               size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;\r
-               if (size > BURNING_MATERIAL_MAX_TEXTURES)\r
-               {\r
-                       flag = (flag & ~VERTEX4D_FORMAT_MASK_TEXTURE) | (BURNING_MATERIAL_MAX_TEXTURES << 16);\r
-               }\r
-\r
-               size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;\r
-               if (size > BURNING_MATERIAL_MAX_COLORS)\r
-               {\r
-                       flag = (flag & ~VERTEX4D_FORMAT_MASK_COLOR) | (BURNING_MATERIAL_MAX_COLORS << 20);\r
-               }\r
-\r
-               size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;\r
-               if (size > BURNING_MATERIAL_MAX_LIGHT_TANGENT)\r
-               {\r
-                       flag = (flag & ~VERTEX4D_FORMAT_MASK_LIGHT) | (BURNING_MATERIAL_MAX_LIGHT_TANGENT << 24);\r
-               }\r
-       }\r
-\r
-       VertexCache.mem.resize(VERTEXCACHE_ELEMENT * 2);\r
-       VertexCache.vType = E4VT_STANDARD;\r
-\r
-       Clipper.resize(VERTEXCACHE_ELEMENT * 2);\r
-       Clipper_temp.resize(VERTEXCACHE_ELEMENT * 2);\r
-\r
-       TransformationStack = 0;\r
-       memset(TransformationFlag, 0, sizeof(TransformationFlag));\r
-       memset(Transformation_ETS_CLIPSCALE, 0, sizeof(Transformation_ETS_CLIPSCALE));\r
-\r
-       Material.resetRenderStates = true;\r
-       Material.Fallback_MaterialType = EMT_SOLID;\r
-}\r
-\r
-\r
-\r
-/*!\r
-       fill a cache line with transformed, light and clip test triangles\r
-       overhead - if primitive is outside or culled, vertexLighting and TextureTransform is still done\r
-*/\r
-void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex)\r
-{\r
-       u8* burning_restrict source;\r
-       s4DVertex* burning_restrict dest;\r
-\r
-       source = (u8*)VertexCache.vertices + (sourceIndex * VertexCache.vSize[VertexCache.vType].Pitch);\r
-\r
-       // it's a look ahead so we never hit it..\r
-       // but give priority...\r
-       //VertexCache.info[ destIndex ].hit = hitCount;\r
-\r
-       // store info\r
-       VertexCache.info[destIndex].index = sourceIndex;\r
-       VertexCache.info[destIndex].hit = 0;\r
-\r
-       // destination Vertex\r
-       dest = VertexCache.mem.data + s4DVertex_ofs(destIndex);\r
-\r
-       //Irrlicht S3DVertex,S3DVertex2TCoords,S3DVertexTangents\r
-       const S3DVertex* base = ((S3DVertex*)source);\r
-\r
-       // transform Model * World * Camera * Projection * NDCSpace matrix\r
-       const core::matrix4* matrix = Transformation[TransformationStack];\r
-       matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, base->Pos);\r
-\r
-       //mhm ... maybe no goto\r
-       if (VertexCache.vType == E4VT_SHADOW)\r
-       {\r
-               //core::vector3df i = base->Pos;\r
-               //i.Z -= 0.5f;\r
-               //matrix[ETS_PROJ_MODEL_VIEW].transformVect(&dest->Pos.x, i);\r
-\r
-               //GL_DEPTH_CLAMP,EVDF_DEPTH_CLAMP\r
-               //if ( dest->Pos.z < dest->Pos.w)\r
-               //      dest->Pos.z = dest->Pos.w*0.99f;\r
-\r
-               //glPolygonOffset // self shadow wanted or not?\r
-               dest->Pos.w *= 1.005f;\r
-\r
-               //flag |= v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_NEAR : 0;\r
-               //flag |= -v->Pos.z <= v->Pos.w ? VERTEX4D_CLIP_FAR : 0;\r
-\r
-               goto clipandproject;\r
-       }\r
-\r
-\r
-#if defined (SOFTWARE_DRIVER_2_LIGHTING) || defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
-\r
-       // vertex, normal in light(eye) space\r
-       if (Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG)))\r
-       {\r
-               sVec4 vertex4; //eye coordinate position of vertex\r
-               matrix[ETS_MODEL_VIEW].transformVect(&vertex4.x, base->Pos);\r
-\r
-               const f32 iw = reciprocal_zero(vertex4.w);\r
-               EyeSpace.vertex.x = vertex4.x * iw;\r
-               EyeSpace.vertex.y = vertex4.y * iw;\r
-               EyeSpace.vertex.z = vertex4.z * iw;\r
-               EyeSpace.vertex.w = iw;\r
-\r
-               //EyeSpace.cam_distance = EyeSpace.vertex.length_xyz();\r
-               EyeSpace.cam_dir = EyeSpace.vertex;\r
-               EyeSpace.cam_dir.normalize_dir_xyz();\r
-\r
-               matrix[ETS_NORMAL].rotateVect(&EyeSpace.normal.x, base->Normal);\r
-               if (EyeSpace.TL_Flag & TL_NORMALIZE_NORMALS)\r
-                       EyeSpace.normal.normalize_dir_xyz();\r
-\r
-       }\r
-\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 1\r
-       dest->Color[1].a = 1.f;\r
-       dest->Color[1].r = 0.f;\r
-       dest->Color[1].g = 0.f;\r
-       dest->Color[1].b = 0.f;\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 2\r
-       dest->Color[2].a = 1.f;\r
-       dest->Color[2].r = 0.f;\r
-       dest->Color[2].g = 0.f;\r
-       dest->Color[2].b = 0.f;\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 3\r
-       dest->Color[3].a = 1.f;\r
-       dest->Color[3].r = 0.f;\r
-       dest->Color[3].g = 0.f;\r
-       dest->Color[3].b = 0.f;\r
-#endif\r
-\r
-#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
-       dest->LightTangent[0].x = 0.f;\r
-       dest->LightTangent[0].y = 0.f;\r
-       dest->LightTangent[0].z = 0.f;\r
-#endif\r
-\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 0\r
-       // apply lighting model\r
-#if defined (SOFTWARE_DRIVER_2_LIGHTING)\r
-       if (Material.org.Lighting)\r
-       {\r
-               lightVertex_eye(dest, base->Color.color);\r
-       }\r
-       else\r
-       {\r
-               dest->Color[0].setA8R8G8B8(base->Color.color);\r
-       }\r
-#else\r
-       dest->Color[0].setA8R8G8B8(base->Color.color);\r
-#endif\r
-#endif\r
-\r
-       //vertex fog\r
-       if (EyeSpace.TL_Flag & TL_FOG) //Material.org.FogEnable\r
-       {\r
-               f32 fog_factor = 1.f;\r
-\r
-               // GL_FRAGMENT_DEPTH -> abs(EyeSpace.vertex.z)\r
-               ieee754 fog_frag_coord;\r
-               fog_frag_coord.f = EyeSpace.vertex.z;\r
-               fog_frag_coord.fields.sign = 0;\r
-\r
-               switch (FogType)\r
-               {\r
-               case EFT_FOG_LINEAR:\r
-                       fog_factor = (FogEnd - fog_frag_coord.f) * EyeSpace.fog_scale;\r
-                       break;\r
-               case EFT_FOG_EXP:\r
-                       fog_factor = (f32)exp(-FogDensity * fog_frag_coord.f);\r
-                       break;\r
-               case EFT_FOG_EXP2:\r
-                       fog_factor = (f32)exp(-FogDensity * FogDensity * fog_frag_coord.f * fog_frag_coord.f);\r
-                       break;\r
-               }\r
-\r
-               sVec4* a = dest->Color + ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG) ? 1 : 0);\r
-               a->a = clampf01(fog_factor);\r
-       }\r
-\r
-       // Texture Coo Transform\r
-       // Always set all internal uv (v1.9 SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM always on) \r
-       for (size_t t = 0; t < BURNING_MATERIAL_MAX_TEXTURES; ++t)\r
-       {\r
-               sVec4 r;\r
-               f32 tx, ty;\r
-\r
-               // texgen\r
-               const size_t flag = TransformationFlag[TransformationStack][ETS_TEXTURE_0 + t];\r
-               if (flag & ETF_TEXGEN_CAMERA_SPHERE)\r
-               {\r
-                       //reflect(u,N) u - 2.0 * dot(N, u) * N\r
-                       // cam is (0,0,-1), tex flipped\r
-\r
-                       const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized\r
-                       const sVec4& n = EyeSpace.normal;\r
-\r
-                       f32 dot = -2.f * n.dot_xyz(u);\r
-                       r.x = u.x + dot * n.x;\r
-                       r.y = u.y + dot * n.y;\r
-                       r.z = u.z + dot * n.z;\r
-\r
-                       //openGL\r
-                       f32 m = 2.f * sqrtf(r.x * r.x + r.y * r.y + (r.z + 1.f) * (r.z + 1.f));\r
-                       tx = r.x / m + 0.5f;\r
-                       ty = -r.y / m + 0.5f;\r
-\r
-                       /*\r
-                       //~d3d with spheremap scale\r
-                       f32 m = 0.25f / (0.00001f + sqrtf(r.x*r.x+r.y*r.y+r.z*r.z));\r
-                       dest[0].Tex[t].x =  r.x * m + 0.5f;\r
-                       dest[0].Tex[t].y = -r.y * m + 0.5f;\r
-                       */\r
-               }\r
-               else if (flag & ETF_TEXGEN_CAMERA_REFLECTION)\r
-               {\r
-                       //reflect(u,N) u - 2.0 * dot(N, u) * N\r
-                       // cam is (0,0,-1), tex flipped\r
-\r
-                       const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized\r
-                       const sVec4& n = EyeSpace.normal;\r
-\r
-                       f32 dot = -2.f * n.dot_xyz(u);\r
-                       r.x = u.x + dot * n.x;\r
-                       r.y = u.y + dot * n.y;\r
-                       r.z = u.z + dot * n.z;\r
-\r
-                       //openGL\r
-                       tx = r.x;\r
-                       ty = -r.y;\r
-                       /*\r
-                               //~d3d with spheremap scale\r
-                               dest[0].Tex[t].x = r.x;\r
-                               dest[0].Tex[t].y = r.y;\r
-                       */\r
-               }\r
-               else\r
-               if (t < VertexCache.vSize[VertexCache.vType].TexCooSize)\r
-               {\r
-                       // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address!\r
-                       const sVec2Pack* baseTCoord = (const sVec2Pack*)&base->TCoords.X;\r
-\r
-                       tx = baseTCoord[t].x;\r
-                       ty = baseTCoord[t].y;\r
-               }\r
-               else\r
-               {\r
-                       tx = 0.f;\r
-                       ty = 0.f;\r
-               }\r
-\r
-               //transform\r
-               if (!(flag & ETF_IDENTITY))\r
-               {\r
-                       /*\r
-                               Generate texture coordinates as linear functions so that:\r
-                                       u = Ux*x + Uy*y + Uz*z + Uw\r
-                                       v = Vx*x + Vy*y + Vz*z + Vw\r
-                               The matrix M for this case is:\r
-                                       Ux  Vx  0  0\r
-                                       Uy  Vy  0  0\r
-                                       Uz  Vz  0  0\r
-                                       Uw  Vw  0  0\r
-                       */\r
-\r
-                       const f32* M = matrix[ETS_TEXTURE_0 + t].pointer();\r
-\r
-                       f32 _tx = tx;\r
-                       f32 _ty = ty;\r
-                       tx = M[0] * _tx + M[4] * _ty + M[8];\r
-                       ty = M[1] * _tx + M[5] * _ty + M[9];\r
-               }\r
-\r
-               switch (Material.org.TextureLayer[t].TextureWrapU)\r
-               {\r
-               case ETC_CLAMP:\r
-               case ETC_CLAMP_TO_EDGE:\r
-               case ETC_CLAMP_TO_BORDER:\r
-                       tx = clampf01(tx);\r
-                       break;\r
-               case ETC_MIRROR:\r
-                       if (core::fract(tx) > 0.5f)\r
-                               tx = 1.f - tx;\r
-                       break;\r
-               case ETC_MIRROR_CLAMP:\r
-               case ETC_MIRROR_CLAMP_TO_EDGE:\r
-               case ETC_MIRROR_CLAMP_TO_BORDER:\r
-                       tx = clampf01(tx);\r
-                       if (core::fract(tx) > 0.5f)\r
-                               tx = 1.f - tx;\r
-                       break;\r
-               case ETC_REPEAT:\r
-                       // texel access is always modulo\r
-               default:\r
-                       break;\r
-               }\r
-               switch (Material.org.TextureLayer[t].TextureWrapV)\r
-               {\r
-               case ETC_CLAMP:\r
-               case ETC_CLAMP_TO_EDGE:\r
-               case ETC_CLAMP_TO_BORDER:\r
-                       ty = clampf01(ty);\r
-                       break;\r
-               case ETC_MIRROR:\r
-                       if (core::fract(ty) > 0.5f)\r
-                               ty = 1.f - ty;\r
-                       break;\r
-               case ETC_MIRROR_CLAMP:\r
-               case ETC_MIRROR_CLAMP_TO_EDGE:\r
-               case ETC_MIRROR_CLAMP_TO_BORDER:\r
-                       ty = clampf01(ty);\r
-                       if (core::fract(ty) > 0.5f)\r
-                               ty = 1.f - ty;\r
-                       break;\r
-               case ETC_REPEAT:\r
-                       // texel access is always modulo\r
-               default:\r
-                       break;\r
-               }\r
-\r
-               dest->Tex[t].x = tx;\r
-               dest->Tex[t].y = ty;\r
-       }\r
-\r
-\r
-#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
-       if ((EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) &&\r
-               ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_TANGENT) == VERTEX4D_FORMAT_BUMP_DOT3)\r
-               )\r
-       {\r
-               const S3DVertexTangents* tangent = ((S3DVertexTangents*)source);\r
-\r
-               sVec4 vp;\r
-               sVec4 light_accu;\r
-               light_accu.x = 0.f;\r
-               light_accu.y = 0.f;\r
-               light_accu.z = 0.f;\r
-               light_accu.w = 0.f;\r
-               for (u32 i = 0; i < 2 && i < EyeSpace.Light.size(); ++i)\r
-               {\r
-                       const SBurningShaderLight& light = EyeSpace.Light[i];\r
-                       if (!light.LightIsOn)\r
-                               continue;\r
-\r
-                       // lightcolor with standard model\r
-                       // but shader is different. treating light and vertex in same space\r
-#if 1\r
-                       vp.x = light.pos.x - base->Pos.X;\r
-                       vp.y = light.pos.y - base->Pos.Y;\r
-                       vp.z = light.pos.z - base->Pos.Z;\r
-#else\r
-                       vp.x = light.pos4.x - EyeSpace.vertex.x;\r
-                       vp.y = light.pos4.y - EyeSpace.vertex.y;\r
-                       vp.z = light.pos4.z - EyeSpace.vertex.z;\r
-#endif\r
-\r
-                       // transform by tangent matrix\r
-                       light_accu.x += (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z);\r
-                       light_accu.y += (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z);\r
-                       light_accu.z += (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z);\r
-               }\r
-               //normalize [-1,+1] to [0,1] -> obsolete\r
-               light_accu.normalize_pack_xyz(dest->LightTangent[0], 1.f, 0.f);\r
-               dest->Tex[1].x = dest->Tex[0].x;\r
-               dest->Tex[1].y = dest->Tex[0].y;\r
-\r
-       }\r
-       else if (Material.org.Lighting)\r
-       {\r
-               //dest->LightTangent[0].x = 0.f;\r
-               //dest->LightTangent[0].y = 0.f;\r
-               //dest->LightTangent[0].z = 0.f;\r
-       }\r
-#endif //if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
-\r
-//#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
-\r
-clipandproject:\r
-\r
-       // test vertex visible\r
-       dest[0].flag = (u32)(clipToFrustumTest(dest) | VertexCache.vSize[VertexCache.vType].Format);\r
-       dest[1].flag = dest[0].flag;\r
-\r
-       // to DC Space, project homogenous vertex\r
-       if ((dest[0].flag & VERTEX4D_CLIPMASK) == VERTEX4D_INSIDE)\r
-       {\r
-               ndc_2_dc_and_project(dest + s4DVertex_proj(0), dest + s4DVertex_ofs(0), s4DVertex_ofs(1));\r
-       }\r
-\r
-}\r
-\r
-\r
-//todo: this should return only index\r
-s4DVertexPair* CBurningVideoDriver::VertexCache_getVertex(const u32 sourceIndex) const\r
-{\r
-       for (size_t i = 0; i < VERTEXCACHE_ELEMENT; ++i)\r
-       {\r
-               if (VertexCache.info[i].index == sourceIndex)\r
-               {\r
-                       return VertexCache.mem.data + s4DVertex_ofs(i);\r
-               }\r
-       }\r
-       return VertexCache.mem.data; //error\r
-}\r
-\r
-\r
-/*\r
-       Cache based on linear walk indices\r
-       fill blockwise on the next 16(Cache_Size) unique vertices in indexlist\r
-       merge the next 16 vertices with the current\r
-*/\r
-void CBurningVideoDriver::VertexCache_get(s4DVertexPair* face[4])\r
-{\r
-       // next primitive must be complete in cache\r
-       if (VertexCache.indicesIndex - VertexCache.indicesRun < VertexCache.primitiveHasVertex &&\r
-               VertexCache.indicesIndex < VertexCache.indexCount\r
-               )\r
-       {\r
-\r
-               size_t i;\r
-               //memset(info, VERTEXCACHE_MISS, sizeof(info));\r
-               for (i = 0; i != VERTEXCACHE_ELEMENT; ++i)\r
-               {\r
-                       VertexCache.info_temp[i].hit = VERTEXCACHE_MISS;\r
-                       VertexCache.info_temp[i].index = VERTEXCACHE_MISS;\r
-               }\r
-\r
-               // rewind to start of primitive\r
-               VertexCache.indicesIndex = VertexCache.indicesRun;\r
-\r
-\r
-               // get the next unique vertices cache line\r
-               u32 fillIndex = 0;\r
-               u32 dIndex = 0;\r
-               u32 sourceIndex = 0;\r
-\r
-               while (VertexCache.indicesIndex < VertexCache.indexCount &&\r
-                       fillIndex < VERTEXCACHE_ELEMENT\r
-                       )\r
-               {\r
-                       switch (VertexCache.iType)\r
-                       {\r
-                       case E4IT_16BIT:\r
-                               sourceIndex = ((u16*)VertexCache.indices)[VertexCache.indicesIndex];\r
-                               break;\r
-                       case E4IT_32BIT:\r
-                               sourceIndex = ((u32*)VertexCache.indices)[VertexCache.indicesIndex];\r
-                               break;\r
-                       default:\r
-                       case E4IT_NONE:\r
-                               sourceIndex = VertexCache.indicesIndex;\r
-                               break;\r
-                       }\r
-\r
-                       VertexCache.indicesIndex += 1;\r
-\r
-                       // if not exist, push back\r
-                       s32 exist = 0;\r
-                       for (dIndex = 0; dIndex < fillIndex; ++dIndex)\r
-                       {\r
-                               if (VertexCache.info_temp[dIndex].index == sourceIndex)\r
-                               {\r
-                                       exist = 1;\r
-                                       break;\r
-                               }\r
-                       }\r
-\r
-                       if (0 == exist)\r
-                       {\r
-                               VertexCache.info_temp[fillIndex++].index = sourceIndex;\r
-                       }\r
-               }\r
-\r
-               // clear marks\r
-               for (i = 0; i != VERTEXCACHE_ELEMENT; ++i)\r
-               {\r
-                       VertexCache.info[i].hit = 0;\r
-               }\r
-\r
-               // mark all existing\r
-               for (i = 0; i != fillIndex; ++i)\r
-               {\r
-                       for (dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex)\r
-                       {\r
-                               if (VertexCache.info[dIndex].index == VertexCache.info_temp[i].index)\r
-                               {\r
-                                       VertexCache.info_temp[i].hit = dIndex;\r
-                                       VertexCache.info[dIndex].hit = 1;\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-\r
-               // fill new\r
-               for (i = 0; i != fillIndex; ++i)\r
-               {\r
-                       if (VertexCache.info_temp[i].hit != VERTEXCACHE_MISS)\r
-                               continue;\r
-\r
-                       for (dIndex = 0; dIndex < VERTEXCACHE_ELEMENT; ++dIndex)\r
-                       {\r
-                               if (0 == VertexCache.info[dIndex].hit)\r
-                               {\r
-                                       VertexCache_fill(VertexCache.info_temp[i].index, dIndex);\r
-                                       VertexCache.info[dIndex].hit += 1;\r
-                                       VertexCache.info_temp[i].hit = dIndex;\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-\r
-       //const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );\r
-       const u32 i0 = VertexCache.pType != scene::EPT_TRIANGLE_FAN ? VertexCache.indicesRun : 0;\r
-\r
-       switch (VertexCache.iType)\r
-       {\r
-       case E4IT_16BIT:\r
-       {\r
-               const u16* p = (const u16*)VertexCache.indices;\r
-               face[0] = VertexCache_getVertex(p[i0]);\r
-               face[1] = VertexCache_getVertex(p[VertexCache.indicesRun + 1]);\r
-               face[2] = VertexCache_getVertex(p[VertexCache.indicesRun + 2]);\r
-       }\r
-       break;\r
-\r
-       case E4IT_32BIT:\r
-       {\r
-               const u32* p = (const u32*)VertexCache.indices;\r
-               face[0] = VertexCache_getVertex(p[i0]);\r
-               face[1] = VertexCache_getVertex(p[VertexCache.indicesRun + 1]);\r
-               face[2] = VertexCache_getVertex(p[VertexCache.indicesRun + 2]);\r
-       }\r
-       break;\r
-\r
-       case E4IT_NONE:\r
-               face[0] = VertexCache_getVertex(VertexCache.indicesRun + 0);\r
-               face[1] = VertexCache_getVertex(VertexCache.indicesRun + 1);\r
-               face[2] = VertexCache_getVertex(VertexCache.indicesRun + 2);\r
-               break;\r
-       default:\r
-               face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0);\r
-               break;\r
-       }\r
-       face[3] = face[0]; // quad unsupported\r
-       VertexCache.indicesRun += VertexCache.indicesPitch;\r
-}\r
-\r
-\r
-/*!\r
-*/\r
-int CBurningVideoDriver::VertexCache_reset(const void* vertices, u32 vertexCount,\r
-       const void* indices, u32 primitiveCount,\r
-       E_VERTEX_TYPE vType,\r
-       scene::E_PRIMITIVE_TYPE pType,\r
-       E_INDEX_TYPE iType)\r
-{\r
-\r
-       // These calls would lead to crashes due to wrong index usage.\r
-       // The vertex cache needs to be rewritten for these primitives.\r
-       if (0 == CurrentShader ||\r
-               pType == scene::EPT_POINTS || pType == scene::EPT_LINE_STRIP ||\r
-               pType == scene::EPT_LINE_LOOP || pType == scene::EPT_LINES ||\r
-               pType == scene::EPT_POLYGON ||\r
-               pType == scene::EPT_POINT_SPRITES)\r
-       {\r
-               return 1;\r
-       }\r
-\r
-       VertexCache.vertices = vertices;\r
-       VertexCache.vertexCount = vertexCount;\r
-\r
-       switch (Material.org.MaterialType) // (Material.Fallback_MaterialType)\r
-       {\r
-       case EMT_REFLECTION_2_LAYER:\r
-       case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
-               VertexCache.vType = E4VT_REFLECTION_MAP;\r
-               break;\r
-       default:\r
-               VertexCache.vType = (e4DVertexType)vType;\r
-               break;\r
-       }\r
-\r
-       //check material\r
-       SVSize* vSize = VertexCache.vSize;\r
-       for (int m = (int)vSize[VertexCache.vType].TexSize - 1; m >= 0; --m)\r
-       {\r
-               ITexture* tex = MAT_TEXTURE(m);\r
-               if (!tex)\r
-               {\r
-                       vSize[E4VT_NO_TEXTURE] = vSize[VertexCache.vType];\r
-                       vSize[E4VT_NO_TEXTURE].TexSize = m;\r
-                       vSize[E4VT_NO_TEXTURE].TexCooSize = m;\r
-                       VertexCache.vType = E4VT_NO_TEXTURE;\r
-                       //flags downconvert?\r
-               }\r
-       }\r
-\r
-       VertexCache.indices = indices;\r
-       VertexCache.indicesIndex = 0;\r
-       VertexCache.indicesRun = 0;\r
-\r
-       switch (iType)\r
-       {\r
-       case EIT_16BIT: VertexCache.iType = E4IT_16BIT; break;\r
-       case EIT_32BIT: VertexCache.iType = E4IT_32BIT; break;\r
-       default:\r
-               VertexCache.iType = (e4DIndexType)iType; break;\r
-       }\r
-       if (!VertexCache.indices)\r
-               VertexCache.iType = E4IT_NONE;\r
-\r
-       VertexCache.pType = pType;\r
-       VertexCache.primitiveHasVertex = 3;\r
-       VertexCache.indicesPitch = 1;\r
-       switch (VertexCache.pType)\r
-       {\r
-               // most types here will not work as expected, only triangles/triangle_fan\r
-               // is known to work.\r
-       case scene::EPT_POINTS:\r
-               VertexCache.indexCount = primitiveCount;\r
-               VertexCache.indicesPitch = 1;\r
-               VertexCache.primitiveHasVertex = 1;\r
-               break;\r
-       case scene::EPT_LINE_STRIP:\r
-               VertexCache.indexCount = primitiveCount + 1;\r
-               VertexCache.indicesPitch = 1;\r
-               VertexCache.primitiveHasVertex = 2;\r
-               break;\r
-       case scene::EPT_LINE_LOOP:\r
-               VertexCache.indexCount = primitiveCount + 1;\r
-               VertexCache.indicesPitch = 1;\r
-               VertexCache.primitiveHasVertex = 2;\r
-               break;\r
-       case scene::EPT_LINES:\r
-               VertexCache.indexCount = 2 * primitiveCount;\r
-               VertexCache.indicesPitch = 2;\r
-               VertexCache.primitiveHasVertex = 2;\r
-               break;\r
-       case scene::EPT_TRIANGLE_STRIP:\r
-               VertexCache.indexCount = primitiveCount + 2;\r
-               VertexCache.indicesPitch = 1;\r
-               VertexCache.primitiveHasVertex = 3;\r
-               break;\r
-       case scene::EPT_TRIANGLES:\r
-               VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount;\r
-               VertexCache.indicesPitch = 3;\r
-               VertexCache.primitiveHasVertex = 3;\r
-               break;\r
-       case scene::EPT_TRIANGLE_FAN:\r
-               VertexCache.indexCount = primitiveCount + 2;\r
-               VertexCache.indicesPitch = 1;\r
-               VertexCache.primitiveHasVertex = 3;\r
-               break;\r
-       case scene::EPT_QUAD_STRIP:\r
-               VertexCache.indexCount = 2 * primitiveCount + 2;\r
-               VertexCache.indicesPitch = 2;\r
-               VertexCache.primitiveHasVertex = 4;\r
-               break;\r
-       case scene::EPT_QUADS:\r
-               VertexCache.indexCount = 4 * primitiveCount;\r
-               VertexCache.indicesPitch = 4;\r
-               VertexCache.primitiveHasVertex = 4;\r
-               break;\r
-       case scene::EPT_POLYGON:\r
-               VertexCache.indexCount = primitiveCount + 1;\r
-               VertexCache.indicesPitch = 1;\r
-               VertexCache.primitiveHasVertex = primitiveCount;\r
-               break;\r
-       case scene::EPT_POINT_SPRITES:\r
-               VertexCache.indexCount = primitiveCount;\r
-               VertexCache.indicesPitch = 1;\r
-               VertexCache.primitiveHasVertex = 1;\r
-               break;\r
-       }\r
-\r
-       //memset( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) );\r
-       for (size_t i = 0; i != VERTEXCACHE_ELEMENT; ++i)\r
-       {\r
-               VertexCache.info[i].hit = VERTEXCACHE_MISS;\r
-               VertexCache.info[i].index = VERTEXCACHE_MISS;\r
-       }\r
-       return 0;\r
-}\r
-\r
-\r
-//! draws a vertex primitive list\r
-void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vertexCount,\r
-       const void* indexList, u32 primitiveCount,\r
-       E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)\r
-\r
-{\r
-       if (!checkPrimitiveCount(primitiveCount))\r
-               return;\r
-\r
-       CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);\r
-\r
-       if (VertexCache_reset(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType))\r
-               return;\r
-\r
-       if ((u32)Material.org.MaterialType < MaterialRenderers.size())\r
-       {\r
-               MaterialRenderers[Material.org.MaterialType].Renderer->OnRender(this, vType);\r
-       }\r
-\r
-       //Matrices needed for this primitive\r
-       transform_calc(ETS_PROJ_MODEL_VIEW);\r
-       if (Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM | TL_FOG)))\r
-       {\r
-               transform_calc(ETS_MODEL_VIEW);\r
-               transform_calc(ETS_NORMAL);\r
-       }\r
-\r
-\r
-       s4DVertexPair* face[4];\r
-\r
-       size_t vOut;\r
-       size_t vertex_from_clipper; // from VertexCache or CurrentOut\r
-       size_t has_vertex_run;\r
-\r
-       for (size_t primitive_run = 0; primitive_run < primitiveCount; ++primitive_run)\r
-       {\r
-               //collect pointer to face vertices\r
-               VertexCache_get(face);\r
-\r
-               size_t clipMask_i;\r
-               size_t clipMask_o;\r
-\r
-               clipMask_i = face[0]->flag;\r
-               clipMask_o = face[0]->flag;\r
-\r
-               for (has_vertex_run = 1; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run)\r
-               {\r
-                       clipMask_i |= face[has_vertex_run]->flag; // if fully outside or outside on same side\r
-                       clipMask_o &= face[has_vertex_run]->flag; // if fully inside\r
-               }\r
-\r
-               clipMask_i &= VERTEX4D_CLIPMASK;\r
-               clipMask_o &= VERTEX4D_CLIPMASK;\r
-\r
-               if (clipMask_i != VERTEX4D_INSIDE)\r
-               {\r
-                       // if primitive fully outside or outside on same side\r
-                       continue;\r
-                       vOut = 0;\r
-                       vertex_from_clipper = 0;\r
-               }\r
-               else if (clipMask_o == VERTEX4D_INSIDE)\r
-               {\r
-                       // if primitive fully inside\r
-                       vOut = VertexCache.primitiveHasVertex;\r
-                       vertex_from_clipper = 0;\r
-               }\r
-               else\r
-#if defined(SOFTWARE_DRIVER_2_CLIPPING)\r
-               {\r
-                       // else if not complete inside clipping necessary\r
-                       // check: clipping should reuse vertexcache (try to minimize clipping)\r
-                       for (has_vertex_run = 0; has_vertex_run < VertexCache.primitiveHasVertex; ++has_vertex_run)\r
-                       {\r
-                               memcpy_s4DVertexPair(Clipper.data + s4DVertex_ofs(has_vertex_run), face[has_vertex_run]);\r
-                       }\r
-\r
-                       vOut = clipToFrustum(VertexCache.primitiveHasVertex);\r
-                       vertex_from_clipper = 1;\r
-\r
-                       // to DC Space, project homogenous vertex\r
-                       ndc_2_dc_and_project(Clipper.data + s4DVertex_proj(0), Clipper.data + s4DVertex_ofs(0), s4DVertex_ofs(vOut));\r
-               }\r
-#else\r
-               {\r
-                       continue;\r
-                       vOut = 0;\r
-                       vertex_from_clipper = 0;\r
-               }\r
-#endif\r
-               // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )\r
-               for (has_vertex_run = 0; (has_vertex_run + VertexCache.primitiveHasVertex) <= vOut; has_vertex_run += 1)\r
-               {\r
-                       // set from clipped geometry\r
-                       if (vertex_from_clipper)\r
-                       {\r
-                               face[0] = Clipper.data + s4DVertex_ofs(0);\r
-                               face[1] = Clipper.data + s4DVertex_ofs(has_vertex_run + 1);\r
-                               face[2] = Clipper.data + s4DVertex_ofs(has_vertex_run + 2);\r
-                       }\r
-\r
-                       //area of primitive in device space\r
-                       // projected triangle screen area is used for culling ( sign of normal ) and mipmap selection\r
-                       //f32 dc_area = screenarea_inside(face);\r
-\r
-                       // crossproduct (area of parallelogram * 0.5 = triangle screen size)\r
-                       f32 dc_area;\r
-                       {\r
-                               const sVec4& v0 = (face[0] + s4DVertex_proj(0))->Pos;\r
-                               const sVec4& v1 = (face[1] + s4DVertex_proj(0))->Pos;\r
-                               const sVec4& v2 = (face[2] + s4DVertex_proj(0))->Pos;\r
-\r
-                               //dc_area = a.x * b.y - b.x * a.y;\r
-                               dc_area = ((v1.x - v0.x) * (v2.y - v0.y) - (v2.x - v0.x) * (v1.y - v0.y)) * 0.5f;\r
-                       }\r
-\r
-                       //geometric clipping has problem with invisible or very small Triangles\r
-                       //size_t sign = dc_area < 0.001f ? CULL_BACK : dc_area > 0.001f ? CULL_FRONT : CULL_INVISIBLE;\r
-                       ieee754 t;\r
-                       t.f = dc_area;\r
-                       size_t sign = t.fields.sign ? CULL_BACK : CULL_FRONT;\r
-                       sign |= t.abs.frac_exp < 981668463 /*0.01f*/ ? CULL_INVISIBLE : 0;\r
-                       if (Material.CullFlag & sign)\r
-                               break; //continue;\r
-\r
-                       //select mipmap ratio between drawing space and texture space (for multiply divide here)\r
-                       dc_area = reciprocal_zero(dc_area);\r
-\r
-                       // select mipmap\r
-                       for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m)\r
-                       {\r
-                               video::CSoftwareTexture2* tex = MAT_TEXTURE(m);\r
-\r
-                               //only guessing: take more detail (lower mipmap) in light+bump textures\r
-                               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);\r
-\r
-                               //assume transparent add is ~50% transparent -> more detail\r
-                               switch (Material.org.MaterialType)\r
-                               {\r
-                                       case EMT_TRANSPARENT_ADD_COLOR:\r
-                                       case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
-                                               lod_bias *= 0.5f;\r
-                                               break;\r
-                                       default:\r
-                                               break;\r
-                               }\r
-                               lod_bias *= tex->get_lod_bias();\r
-                               //lod_bias += Material.org.TextureLayer[m].LODBias * 0.125f;\r
-       \r
-                               s32 lodFactor = lodFactor_inside(face, m, dc_area, lod_bias);\r
-\r
-                               CurrentShader->setTextureParam(m, tex, lodFactor);\r
-                               //currently shader receives texture coordinate as Pixelcoo of 1 Texture\r
-                               select_polygon_mipmap_inside(face, m, tex->getTexBound());\r
-                       }\r
-                       \r
-                       CurrentShader->drawWireFrameTriangle(face[0] + s4DVertex_proj(0), face[1] + s4DVertex_proj(0), face[2] + s4DVertex_proj(0));\r
-                       vertex_from_clipper = 1;\r
-               }\r
-\r
-       }\r
-\r
-       //release texture\r
-       for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m)\r
-       {\r
-               CurrentShader->setTextureParam(m, 0, 0);\r
-       }\r
-\r
-}\r
-\r
-\r
-//! Sets the dynamic ambient light color. The default color is\r
-//! (0,0,0,0) which means it is dark.\r
-//! \param color: New color of the ambient light.\r
-void CBurningVideoDriver::setAmbientLight(const SColorf& color)\r
-{\r
-       EyeSpace.Global_AmbientLight.setColorf(color);\r
-}\r
-\r
-\r
-//! adds a dynamic light\r
-s32 CBurningVideoDriver::addDynamicLight(const SLight& dl)\r
-{\r
-       (void)CNullDriver::addDynamicLight(dl);\r
-\r
-       SBurningShaderLight l;\r
-       //      l.org = dl;\r
-       l.Type = dl.Type;\r
-       l.LightIsOn = true;\r
-\r
-       l.AmbientColor.setColorf(dl.AmbientColor);\r
-       l.DiffuseColor.setColorf(dl.DiffuseColor);\r
-       l.SpecularColor.setColorf(dl.SpecularColor);\r
-\r
-       //should always be valid?\r
-       sVec4 nDirection;\r
-       nDirection.x = dl.Direction.X;\r
-       nDirection.y = dl.Direction.Y;\r
-       nDirection.z = dl.Direction.Z;\r
-       nDirection.normalize_dir_xyz();\r
-\r
-\r
-       switch (dl.Type)\r
-       {\r
-       case ELT_DIRECTIONAL:\r
-               l.pos.x = dl.Position.X;\r
-               l.pos.y = dl.Position.Y;\r
-               l.pos.z = dl.Position.Z;\r
-               l.pos.w = 0.f;\r
-\r
-               l.constantAttenuation = 1.f;\r
-               l.linearAttenuation = 0.f;\r
-               l.quadraticAttenuation = 0.f;\r
-\r
-               l.spotDirection.x = -nDirection.x;\r
-               l.spotDirection.y = -nDirection.y;\r
-               l.spotDirection.z = -nDirection.z;\r
-               l.spotDirection.w = 0.f;\r
-               l.spotCosCutoff = -1.f;\r
-               l.spotCosInnerCutoff = 1.f;\r
-               l.spotExponent = 0.f;\r
-               break;\r
-\r
-       case ELT_POINT:\r
-               l.pos.x = dl.Position.X;\r
-               l.pos.y = dl.Position.Y;\r
-               l.pos.z = dl.Position.Z;\r
-               l.pos.w = 1.f;\r
-\r
-               l.constantAttenuation = dl.Attenuation.X;\r
-               l.linearAttenuation = dl.Attenuation.Y;\r
-               l.quadraticAttenuation = dl.Attenuation.Z;\r
-\r
-               l.spotDirection.x = -nDirection.x;\r
-               l.spotDirection.y = -nDirection.y;\r
-               l.spotDirection.z = -nDirection.z;\r
-               l.spotDirection.w = 0.f;\r
-               l.spotCosCutoff = -1.f;\r
-               l.spotCosInnerCutoff = 1.f;\r
-               l.spotExponent = 0.f;\r
-               break;\r
-\r
-       case ELT_SPOT:\r
-               l.pos.x = dl.Position.X;\r
-               l.pos.y = dl.Position.Y;\r
-               l.pos.z = dl.Position.Z;\r
-               l.pos.w = 1.f;\r
-\r
-               l.constantAttenuation = dl.Attenuation.X;\r
-               l.linearAttenuation = dl.Attenuation.Y;\r
-               l.quadraticAttenuation = dl.Attenuation.Z;\r
-\r
-               l.spotDirection.x = nDirection.x;\r
-               l.spotDirection.y = nDirection.y;\r
-               l.spotDirection.z = nDirection.z;\r
-               l.spotDirection.w = 0.0f;\r
-               l.spotCosCutoff = cosf(dl.OuterCone * 2.0f * core::DEGTORAD * 0.5f);\r
-               l.spotCosInnerCutoff = cosf(dl.InnerCone * 2.0f * core::DEGTORAD * 0.5f);\r
-               l.spotExponent = dl.Falloff;\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       //which means ETS_VIEW\r
-       setTransform(ETS_WORLD, irr::core::IdentityMatrix);\r
-       transform_calc(ETS_MODEL_VIEW);\r
-\r
-       const core::matrix4* matrix = Transformation[TransformationStack];\r
-       transformVec4Vec4(matrix[ETS_MODEL_VIEW], &l.pos4.x, &l.pos.x);\r
-       rotateVec3Vec4(matrix[ETS_MODEL_VIEW], &l.spotDirection4.x, &l.spotDirection.x);\r
-\r
-       EyeSpace.Light.push_back(l);\r
-       return EyeSpace.Light.size() - 1;\r
-}\r
-\r
-\r
-//! Turns a dynamic light on or off\r
-void CBurningVideoDriver::turnLightOn(s32 lightIndex, bool turnOn)\r
-{\r
-       if ((u32)lightIndex < EyeSpace.Light.size())\r
-       {\r
-               EyeSpace.Light[lightIndex].LightIsOn = turnOn;\r
-       }\r
-}\r
-\r
-//! deletes all dynamic lights there are\r
-void CBurningVideoDriver::deleteAllDynamicLights()\r
-{\r
-       EyeSpace.reset();\r
-       CNullDriver::deleteAllDynamicLights();\r
-\r
-}\r
-\r
-//! returns the maximal amount of dynamic lights the device can handle\r
-u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const\r
-{\r
-       return 8; //no limit 8 only for convenience\r
-}\r
-\r
-\r
-//! sets a material\r
-void CBurningVideoDriver::setMaterial(const SMaterial& material)\r
-{\r
-       // ---------- Override\r
-       Material.org = material;\r
-       OverrideMaterial.apply(Material.org);\r
-\r
-       const SMaterial& in = Material.org;\r
-\r
-       // ---------- Notify Shader\r
-               // unset old material\r
-       u32 mi;\r
-       mi = (u32)Material.lastMaterial.MaterialType;\r
-       if (mi != material.MaterialType && mi < MaterialRenderers.size())\r
-               MaterialRenderers[mi].Renderer->OnUnsetMaterial();\r
-\r
-       // set new material.\r
-       mi = (u32)in.MaterialType;\r
-       if (mi < MaterialRenderers.size())\r
-               MaterialRenderers[mi].Renderer->OnSetMaterial(\r
-                       in, Material.lastMaterial, Material.resetRenderStates, this);\r
-\r
-       Material.lastMaterial = in;\r
-       Material.resetRenderStates = false;\r
-\r
-       //CSoftware2MaterialRenderer sets Material.Fallback_MaterialType\r
-\r
-       //Material.Fallback_MaterialType = material.MaterialType;\r
-\r
-//-----------------\r
-\r
-       //Material.org = material;\r
-       Material.CullFlag = CULL_INVISIBLE | (in.BackfaceCulling ? CULL_BACK : 0) | (in.FrontfaceCulling ? CULL_FRONT : 0);\r
-\r
-       size_t* flag = TransformationFlag[TransformationStack];\r
-\r
-#ifdef SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
-       for (u32 m = 0; m < BURNING_MATERIAL_MAX_TEXTURES /*&& m < vSize[VertexCache.vType].TexSize*/; ++m)\r
-       {\r
-               setTransform((E_TRANSFORMATION_STATE)(ETS_TEXTURE_0 + m), in.getTextureMatrix(m));\r
-               flag[ETS_TEXTURE_0 + m] &= ~ETF_TEXGEN_MASK;\r
-       }\r
-#endif\r
-\r
-#ifdef SOFTWARE_DRIVER_2_LIGHTING\r
-\r
-       Material.AmbientColor.setA8R8G8B8(in.AmbientColor.color);\r
-       Material.DiffuseColor.setA8R8G8B8(in.ColorMaterial ? 0xFFFFFFFF : in.DiffuseColor.color);\r
-       Material.EmissiveColor.setA8R8G8B8(in.EmissiveColor.color);\r
-       Material.SpecularColor.setA8R8G8B8(in.SpecularColor.color);\r
-\r
-       burning_setbit(EyeSpace.TL_Flag, in.Lighting, TL_LIGHT);\r
-       burning_setbit(EyeSpace.TL_Flag, (in.Shininess != 0.f) && (in.SpecularColor.color & 0x00ffffff), TL_SPECULAR);\r
-       burning_setbit(EyeSpace.TL_Flag, in.FogEnable, TL_FOG);\r
-       burning_setbit(EyeSpace.TL_Flag, in.NormalizeNormals, TL_NORMALIZE_NORMALS);\r
-       //if (EyeSpace.Flags & SPECULAR ) EyeSpace.Flags |= NORMALIZE_NORMALS;\r
-\r
-#endif\r
-\r
-//--------------- setCurrentShader\r
-\r
-       ITexture* texture0 = in.getTexture(0);\r
-       ITexture* texture1 = in.getTexture(1);\r
-       //ITexture* texture2 = in.getTexture(2);\r
-       //ITexture* texture3 = in.getTexture(3);\r
-\r
-       //visual studio code analysis\r
-       u32 maxTex = BURNING_MATERIAL_MAX_TEXTURES;\r
-       if (maxTex < 1) texture0 = 0;\r
-       if (maxTex < 2) texture1 = 0;\r
-       //if (maxTex < 3) texture2 = 0;\r
-       //if (maxTex < 4) texture3 = 0;\r
-\r
-       EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP);\r
-\r
-       //todo: seperate depth test from depth write\r
-       Material.depth_write = getWriteZBuffer(in);\r
-       Material.depth_test = in.ZBuffer != ECFN_DISABLED && Material.depth_write;\r
-\r
-       EBurningFFShader shader = Material.depth_test ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;\r
-\r
-       switch (Material.Fallback_MaterialType) //(Material.org.MaterialType)\r
-       {\r
-       case EMT_ONETEXTURE_BLEND:\r
-               shader = ETR_TEXTURE_BLEND;\r
-               break;\r
-\r
-       case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:\r
-               Material.org.MaterialTypeParam = 0.5f;\r
-               //fallthrough\r
-\r
-       case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
-               if (texture0 && texture0->hasAlpha())\r
-               {\r
-                       shader = Material.depth_test ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ;\r
-               }\r
-               else\r
-               {\r
-                       //fall back to EMT_TRANSPARENT_VERTEX_ALPHA\r
-                       shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;\r
-               }\r
-               break;\r
-\r
-       case EMT_TRANSPARENT_ADD_COLOR:\r
-               shader = Material.depth_test ? ETR_TEXTURE_GOURAUD_ADD : ETR_TEXTURE_GOURAUD_ADD_NO_Z;\r
-               break;\r
-\r
-       case EMT_TRANSPARENT_VERTEX_ALPHA:\r
-               shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;\r
-               break;\r
-\r
-       case EMT_LIGHTMAP:\r
-       case EMT_LIGHTMAP_LIGHTING:\r
-               if (texture1)\r
-                       shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;\r
-               break;\r
-\r
-       case EMT_LIGHTMAP_M2:\r
-       case EMT_LIGHTMAP_LIGHTING_M2:\r
-               if (texture1)\r
-                       shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M2;\r
-               break;\r
-\r
-       case EMT_LIGHTMAP_LIGHTING_M4:\r
-               if (texture1)\r
-                       shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M4;\r
-               break;\r
-       case EMT_LIGHTMAP_M4:\r
-               if (texture1)\r
-                       shader = ETR_TEXTURE_LIGHTMAP_M4;\r
-               break;\r
-\r
-       case EMT_LIGHTMAP_ADD:\r
-               if (texture1)\r
-                       shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD;\r
-               break;\r
-\r
-       case EMT_DETAIL_MAP:\r
-               if (texture1)\r
-                       shader = ETR_TEXTURE_GOURAUD_DETAIL_MAP;\r
-               break;\r
-\r
-       case EMT_SPHERE_MAP:\r
-               flag[ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_SPHERE;\r
-               EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;\r
-               break;\r
-       case EMT_REFLECTION_2_LAYER:\r
-       case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
-               if (texture1)\r
-               {\r
-                       shader = ETR_TRANSPARENT_REFLECTION_2_LAYER;\r
-                       flag[ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION;\r
-                       EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM;\r
-               }\r
-               break;\r
-\r
-       case EMT_NORMAL_MAP_SOLID:\r
-       case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:\r
-       case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:\r
-               if (texture1)\r
-               {\r
-                       shader = ETR_NORMAL_MAP_SOLID;\r
-                       EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP;\r
-               }\r
-               break;\r
-       case EMT_PARALLAX_MAP_SOLID:\r
-       case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:\r
-       case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:\r
-               if (texture1)\r
-               {\r
-                       shader = ETR_NORMAL_MAP_SOLID;\r
-                       EyeSpace.TL_Flag |= TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP;\r
-               }\r
-               break;\r
-\r
-       default:\r
-               break;\r
-\r
-       }\r
-\r
-       if (!texture0)\r
-       {\r
-               shader = Material.depth_test ? ETR_GOURAUD :\r
-                       shader == ETR_TEXTURE_GOURAUD_VERTEX_ALPHA ?\r
-                       ETR_GOURAUD_ALPHA_NOZ : // 2D Gradient\r
-                       ETR_GOURAUD_NOZ;\r
-\r
-               shader = ETR_COLOR;\r
-       }\r
-\r
-       if (in.Wireframe)\r
-       {\r
-               IBurningShader* candidate = BurningShader[shader];\r
-               if (!candidate || (candidate && !candidate->canWireFrame()))\r
-               {\r
-                       shader = ETR_TEXTURE_GOURAUD_WIRE;\r
-               }\r
-       }\r
-\r
-       if (in.PointCloud)\r
-       {\r
-               IBurningShader* candidate = BurningShader[shader];\r
-               if (!candidate || (candidate && !candidate->canPointCloud()))\r
-               {\r
-                       shader = ETR_TEXTURE_GOURAUD_WIRE;\r
-               }\r
-       }\r
-\r
-       //shader = ETR_REFERENCE;\r
-\r
-       // switchToTriangleRenderer\r
-       CurrentShader = BurningShader[shader];\r
-       if (CurrentShader)\r
-       {\r
-               CurrentShader->setTLFlag(EyeSpace.TL_Flag);\r
-               if (EyeSpace.TL_Flag & TL_FOG) CurrentShader->setFog(FogColor);\r
-               if (EyeSpace.TL_Flag & TL_SCISSOR) CurrentShader->setScissor(Scissor);\r
-               CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced);\r
-               CurrentShader->OnSetMaterial(Material);\r
-               CurrentShader->pushEdgeTest(in.Wireframe, in.PointCloud, 0);\r
-       }\r
-\r
-\r
-       /*\r
-               mi = (u32)Material.org.MaterialType;\r
-               if (mi < MaterialRenderers.size())\r
-                       MaterialRenderers[mi].Renderer->OnRender(this, (video::E_VERTEX_TYPE)VertexCache.vType);\r
-       */\r
-}\r
-\r
-\r
-//! Sets the fog mode.\r
-void CBurningVideoDriver::setFog(SColor color, E_FOG_TYPE fogType, f32 start,\r
-       f32 end, f32 density, bool pixelFog, bool rangeFog)\r
-{\r
-       CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog);\r
-\r
-       EyeSpace.fog_scale = reciprocal_zero(FogEnd - FogStart);\r
-}\r
-\r
-\r
-\r
-#if defined(SOFTWARE_DRIVER_2_LIGHTING) && BURNING_MATERIAL_MAX_COLORS > 0\r
-\r
-\r
-/*!\r
-       applies lighting model\r
-*/\r
-void CBurningVideoDriver::lightVertex_eye(s4DVertex* dest, u32 vertexargb)\r
-{\r
-       //gl_FrontLightModelProduct.sceneColor = gl_FrontMaterial.emission + gl_FrontMaterial.ambient * gl_LightModel.ambient\r
-\r
-       sVec3Color ambient;\r
-       sVec3Color diffuse;\r
-       sVec3Color specular;\r
-\r
-\r
-       // the universe started in darkness..\r
-       ambient = EyeSpace.Global_AmbientLight;\r
-       diffuse.set(0.f);\r
-       specular.set(0.f);\r
-\r
-\r
-       u32 i;\r
-       f32 dot;\r
-       f32 distance;\r
-       f32 attenuation;\r
-       sVec4 vp;                       // unit vector vertex to light\r
-       sVec4 lightHalf;        // blinn-phong reflection\r
-\r
-       f32 spotDot;                    // cos of angle between spotlight and point on surface\r
-\r
-       for (i = 0; i < EyeSpace.Light.size(); ++i)\r
-       {\r
-               const SBurningShaderLight& light = EyeSpace.Light[i];\r
-               if (!light.LightIsOn)\r
-                       continue;\r
-\r
-               switch (light.Type)\r
-               {\r
-               case ELT_DIRECTIONAL:\r
-\r
-                       //angle between normal and light vector\r
-                       dot = EyeSpace.normal.dot_xyz(light.spotDirection4);\r
-\r
-                       // accumulate ambient\r
-                       ambient.add_rgb(light.AmbientColor);\r
-\r
-                       // diffuse component\r
-                       if (dot > 0.f)\r
-                               diffuse.mad_rgb(light.DiffuseColor, dot);\r
-                       break;\r
-\r
-               case ELT_POINT:\r
-                       // surface to light\r
-                       vp.x = light.pos4.x - EyeSpace.vertex.x;\r
-                       vp.y = light.pos4.y - EyeSpace.vertex.y;\r
-                       vp.z = light.pos4.z - EyeSpace.vertex.z;\r
-\r
-                       distance = vp.length_xyz();\r
-\r
-                       attenuation = light.constantAttenuation\r
-                               + light.linearAttenuation * distance\r
-                               + light.quadraticAttenuation * (distance * distance);\r
-                       attenuation = reciprocal_one(attenuation);\r
-\r
-                       //att = clamp(1.0 - dist/radius, 0.0, 1.0); att *= att\r
-\r
-                       // accumulate ambient\r
-                       ambient.mad_rgb(light.AmbientColor, attenuation);\r
-\r
-                       // build diffuse reflection\r
-\r
-                       //angle between normal and light vector\r
-                       vp.mul_xyz(reciprocal_zero(distance)); //normalize\r
-                       dot = EyeSpace.normal.dot_xyz(vp);\r
-                       if (dot <= 0.f) continue;\r
-\r
-                       // diffuse component\r
-                       diffuse.mad_rgb(light.DiffuseColor, dot * attenuation);\r
-\r
-                       if (!(EyeSpace.TL_Flag & TL_SPECULAR))\r
-                               continue;\r
-\r
-                       lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x;\r
-                       lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y;\r
-                       lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z;\r
-                       lightHalf.normalize_dir_xyz();\r
-\r
-                       //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation\r
-                       specular.mad_rgb(light.SpecularColor,\r
-                               powf_limit(EyeSpace.normal.dot_xyz(lightHalf), Material.org.Shininess) * attenuation\r
-                       );\r
-                       break;\r
-\r
-               case ELT_SPOT:\r
-                       // surface to light\r
-                       vp.x = light.pos4.x - EyeSpace.vertex.x;\r
-                       vp.y = light.pos4.y - EyeSpace.vertex.y;\r
-                       vp.z = light.pos4.z - EyeSpace.vertex.z;\r
-\r
-                       distance = vp.length_xyz();\r
-\r
-                       //normalize\r
-                       vp.mul_xyz(reciprocal_zero(distance));\r
-\r
-                       // point on surface inside cone of illumination\r
-                       spotDot = vp.dot_minus_xyz(light.spotDirection4);\r
-                       if (spotDot < light.spotCosCutoff)\r
-                               continue;\r
-\r
-                       attenuation = light.constantAttenuation\r
-                               + light.linearAttenuation * distance\r
-                               + light.quadraticAttenuation * distance * distance;\r
-                       attenuation = reciprocal_one(attenuation);\r
-                       attenuation *= powf_limit(spotDot, light.spotExponent);\r
-\r
-                       // accumulate ambient\r
-                       ambient.mad_rgb(light.AmbientColor, attenuation);\r
-\r
-\r
-                       // build diffuse reflection\r
-                       //angle between normal and light vector\r
-                       dot = EyeSpace.normal.dot_xyz(vp);\r
-                       if (dot < 0.f) continue;\r
-\r
-                       // diffuse component\r
-                       diffuse.mad_rgb(light.DiffuseColor, dot * attenuation);\r
-\r
-                       if (!(EyeSpace.TL_Flag & TL_SPECULAR))\r
-                               continue;\r
-\r
-                       lightHalf.x = vp.x + 0.f; // EyeSpace.cam_eye_pos.x;\r
-                       lightHalf.y = vp.y + 0.f; // EyeSpace.cam_eye_pos.y;\r
-                       lightHalf.z = vp.z - 1.f; // EyeSpace.cam_eye_pos.z;\r
-                       lightHalf.normalize_dir_xyz();\r
-\r
-                       //specular += light.SpecularColor * pow(max(dot(Eyespace.normal,lighthalf),0,Material.org.Shininess)*attenuation\r
-                       specular.mad_rgb(light.SpecularColor,\r
-                               powf_limit(EyeSpace.normal.dot_xyz(lightHalf), Material.org.Shininess) * attenuation\r
-                       );\r
-                       break;\r
-\r
-               default:\r
-                       break;\r
-               }\r
-\r
-       }\r
-\r
-       // sum up lights\r
-       sVec3Color dColor;\r
-       dColor.set(0.f);\r
-       dColor.mad_rgbv(diffuse, Material.DiffuseColor);\r
-\r
-       //diffuse * vertex color.\r
-       //has to move to shader (for vertex color only this will fit [except clamping])\r
-\r
-       sVec3Color c;\r
-       c.setA8R8G8B8(vertexargb);\r
-       dColor.r *= c.r;\r
-       dColor.g *= c.g;\r
-       dColor.b *= c.b;\r
-\r
-       //separate specular\r
-#if defined(SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR)\r
-       if ((VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_COLOR_2_FOG))\r
-       {\r
-               specular.sat_xyz(dest->Color[1], Material.SpecularColor);\r
-       }\r
-       else\r
-               if (!(EyeSpace.TL_Flag & TL_LIGHT0_IS_NORMAL_MAP) &&\r
-                       (VertexCache.vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_MASK_LIGHT)\r
-                       )\r
-               {\r
-                       specular.sat_xyz(dest->LightTangent[0], Material.SpecularColor);\r
-               }\r
-               else\r
-#endif\r
-               {\r
-                       dColor.mad_rgbv(specular, Material.SpecularColor);\r
-               }\r
-\r
-\r
-       dColor.mad_rgbv(ambient, Material.AmbientColor);\r
-       dColor.add_rgb(Material.EmissiveColor);\r
-\r
-\r
-       dColor.sat(dest->Color[0], vertexargb);\r
-\r
-}\r
-\r
-#endif\r
-/*\r
-CImage* getImage(const video::ITexture* texture)\r
-{\r
-       if (!texture) return 0;\r
-\r
-       CImage* img = 0;\r
-       switch (texture->getDriverType())\r
-       {\r
-       case EDT_BURNINGSVIDEO:\r
-               img = ((CSoftwareTexture2*)texture)->getImage();\r
-               break;\r
-       case EDT_SOFTWARE:\r
-               img = ((CSoftwareTexture*)texture)->getImage();\r
-               break;\r
-       default:\r
-               os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
-               break;\r
-       }\r
-       return img;\r
-}\r
-*/\r
-/*\r
-       draw2DImage with single color scales into destination quad & cliprect(more like viewport)\r
-       draw2DImage with 4 color scales on destination and cliprect is scissor\r
-*/\r
-\r
-static const u16 quad_triangle_indexList[6] = { 0,1,2,0,2,3 };\r
-\r
-\r
-#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)\r
-\r
-//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.\r
-void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,\r
-       const core::rect<s32>& sourceRect,\r
-       const core::rect<s32>* clipRect, SColor color,\r
-       bool useAlphaChannelOfTexture)\r
-{\r
-       if (texture)\r
-       {\r
-               if (texture->getOriginalSize() != texture->getSize())\r
-               {\r
-                       core::rect<s32> destRect(destPos, sourceRect.getSize());\r
-                       SColor c4[4] = { color,color,color,color };\r
-                       draw2DImage(texture, destRect, sourceRect, clipRect, c4, useAlphaChannelOfTexture);\r
-                       return;\r
-               }\r
-\r
-               if (texture->getDriverType() != EDT_BURNINGSVIDEO)\r
-               {\r
-                       os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
-                       return;\r
-               }\r
-\r
-               if (useAlphaChannelOfTexture)\r
-                       ((CSoftwareTexture2*)texture)->getImage()->copyToWithAlpha(\r
-                               RenderTargetSurface, destPos, sourceRect, color, clipRect);\r
-               else\r
-                       ((CSoftwareTexture2*)texture)->getImage()->copyTo(\r
-                               RenderTargetSurface, destPos, sourceRect, clipRect);\r
-       }\r
-}\r
-\r
-\r
-//! Draws a part of the texture into the rectangle.\r
-void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,\r
-       const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,\r
-       const video::SColor* const colors, bool useAlphaChannelOfTexture)\r
-{\r
-       if (texture)\r
-       {\r
-               if (texture->getDriverType() != EDT_BURNINGSVIDEO)\r
-               {\r
-                       os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);\r
-                       return;\r
-               }\r
-\r
-               u32 argb = (colors ? colors[0].color : 0xFFFFFFFF);\r
-               eBlitter op = useAlphaChannelOfTexture ?\r
-                       (argb == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND) : BLITTER_TEXTURE;\r
-\r
-               StretchBlit(op, RenderTargetSurface, clipRect, &destRect,\r
-                       ((CSoftwareTexture2*)texture)->getImage(), &sourceRect, &texture->getOriginalSize(), argb);\r
-\r
-       }\r
-}\r
-\r
-//!Draws an 2d rectangle with a gradient.\r
-void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,\r
-       SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,\r
-       const core::rect<s32>* clip)\r
-{\r
-       core::rect<s32> p(position);\r
-       if (clip) p.clipAgainst(*clip);\r
-       if (p.isValid()) drawRectangle(RenderTargetSurface, p, colorLeftUp);\r
-}\r
-\r
-#endif //defined(SOFTWARE_DRIVER_2_2D_AS_2D)\r
-\r
-\r
-\r
-//! Enable the 2d override material\r
-void CBurningVideoDriver::enableMaterial2D(bool enable)\r
-{\r
-       CNullDriver::enableMaterial2D(enable);\r
-       burning_setbit(TransformationFlag[1][ETS_PROJECTION], 0, ETF_VALID);\r
-}\r
-\r
-size_t compare_2d_material(const SMaterial& a, const SMaterial& b)\r
-{\r
-       size_t flag = 0;\r
-       flag |= a.MaterialType == b.MaterialType ? 0 : 1;\r
-       flag |= a.ZBuffer == b.ZBuffer ? 0 : 2;\r
-       flag |= a.TextureLayer[0].Texture == b.TextureLayer[0].Texture ? 0 : 4;\r
-       flag |= a.TextureLayer[0].BilinearFilter == b.TextureLayer[0].BilinearFilter ? 0 : 8;\r
-       flag |= a.MaterialTypeParam == b.MaterialTypeParam ? 0 : 16;\r
-       if (flag) return flag;\r
-\r
-       flag |= a.TextureLayer[1].Texture == b.TextureLayer[1].Texture ? 0 : 32;\r
-       flag |= a.ZWriteEnable == b.ZWriteEnable ? 0 : 64;\r
-\r
-       return flag;\r
-}\r
-\r
-void CBurningVideoDriver::setRenderStates2DMode(const video::SColor& color, const video::ITexture* texture, bool useAlphaChannelOfTexture)\r
-{\r
-       //save current 3D Material\r
-       //Material.save3D = Material.org;\r
-\r
-       //build new 2D Material\r
-\r
-       bool vertexAlpha = color.getAlpha() < 255;\r
-\r
-       //2D uses textureAlpa*vertexAlpha 3D not..\r
-       if (useAlphaChannelOfTexture && texture && texture->hasAlpha())\r
-       {\r
-               Material.mat2D.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;\r
-       }\r
-       else if (vertexAlpha)\r
-       {\r
-               Material.mat2D.MaterialType = EMT_TRANSPARENT_VERTEX_ALPHA;\r
-       }\r
-       else\r
-       {\r
-               Material.mat2D.MaterialType = EMT_SOLID;\r
-       }\r
-\r
-       Material.mat2D.ZBuffer = ECFN_DISABLED;\r
-       Material.mat2D.ZWriteEnable = EZW_OFF;\r
-       Material.mat2D.Lighting = false;\r
-\r
-       Material.mat2D.setTexture(0, (video::ITexture*)texture);\r
-\r
-       //used for text. so stay as sharp as possible (like HW Driver)\r
-       bool mip = false;\r
-\r
-       const SMaterial& currentMaterial = (!OverrideMaterial2DEnabled) ? InitMaterial2D : OverrideMaterial2D;\r
-       mip = currentMaterial.TextureLayer[0].Texture && currentMaterial.TextureLayer[0].BilinearFilter;\r
-\r
-       Material.mat2D.setFlag(video::EMF_BILINEAR_FILTER, mip);\r
-\r
-\r
-       //switch to 2D Matrix Stack [ Material set Texture Matrix ]\r
-       TransformationStack = 1;\r
-\r
-       //2D GUI Matrix\r
-       if (!(TransformationFlag[TransformationStack][ETS_PROJECTION] & ETF_VALID))\r
-       {\r
-               const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();\r
-               core::matrix4 m(core::matrix4::EM4CONST_NOTHING);\r
-               m.buildProjectionMatrixOrthoLH(f32(renderTargetSize.Width), f32(-(s32)(renderTargetSize.Height)), -1.0f, 1.0f);\r
-               m.setTranslation(core::vector3df(-1.f, 1.f, 0));\r
-               setTransform(ETS_PROJECTION, m);\r
-\r
-               m.makeIdentity();\r
-               setTransform(ETS_WORLD, m);\r
-\r
-               if (mip)\r
-                       m.setTranslation(core::vector3df(IRRLICHT_2D_TEXEL_OFFSET, IRRLICHT_2D_TEXEL_OFFSET, 0.0f));\r
-\r
-               setTransform(ETS_VIEW, m);\r
-\r
-               //Tweak 2D Pixel Center for openGL compatibility (guessing)\r
-               //buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[TransformationStack], ViewPort, mip ? (IRRLICHT_2D_TEXEL_OFFSET) * 0.5f : 0.f);\r
-       }\r
-\r
-       //compare\r
-       if (compare_2d_material(Material.org, Material.mat2D))\r
-       {\r
-               setMaterial(Material.mat2D);\r
-       }\r
-       if (CurrentShader)\r
-       {\r
-               CurrentShader->setPrimitiveColor(color.color);\r
-               CurrentShader->setTLFlag(EyeSpace.TL_Flag);\r
-               if (EyeSpace.TL_Flag & TL_SCISSOR) CurrentShader->setScissor(Scissor);\r
-       }\r
-\r
-}\r
-\r
-void CBurningVideoDriver::setRenderStates3DMode()\r
-{\r
-       //restoreRenderStates3DMode\r
-\r
-       //setMaterial(Material.save3D);\r
-       //switch to 3D Matrix Stack\r
-       TransformationStack = 0;\r
-}\r
-\r
-//! draws a vertex primitive list in 2d\r
-void CBurningVideoDriver::draw2DVertexPrimitiveList(const void* vertices, u32 vertexCount,\r
-       const void* indexList, u32 primitiveCount,\r
-       E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType)\r
-{\r
-       if (!checkPrimitiveCount(primitiveCount))\r
-               return;\r
-\r
-       CNullDriver::draw2DVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);\r
-\r
-       bool useAlphaChannelOfTexture = false;\r
-       video::SColor color(0xFFFFFFFF);\r
-       switch (Material.org.MaterialType)\r
-       {\r
-       case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
-               useAlphaChannelOfTexture = true;\r
-               break;\r
-       case EMT_TRANSPARENT_VERTEX_ALPHA:\r
-               color.setAlpha(127);\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-       setRenderStates2DMode(color, Material.org.getTexture(0), useAlphaChannelOfTexture);\r
-\r
-       drawVertexPrimitiveList(vertices, vertexCount,\r
-               indexList, primitiveCount,\r
-               vType, pType, iType);\r
-\r
-       setRenderStates3DMode();\r
-\r
-}\r
-\r
-//setup a quad\r
-#if defined(SOFTWARE_DRIVER_2_2D_AS_3D)\r
-\r
-//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.\r
-void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,\r
-       const core::rect<s32>& sourceRect,\r
-       const core::rect<s32>* clipRect, SColor color,\r
-       bool useAlphaChannelOfTexture)\r
-{\r
-       if (!texture)\r
-               return;\r
-\r
-       if (!sourceRect.isValid())\r
-               return;\r
-\r
-       // clip these coordinates\r
-       core::rect<s32> targetRect(destPos, sourceRect.getSize());\r
-       if (clipRect)\r
-       {\r
-               targetRect.clipAgainst(*clipRect);\r
-               if (targetRect.getWidth() < 0 || targetRect.getHeight() < 0)\r
-                       return;\r
-       }\r
-\r
-       const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();\r
-       targetRect.clipAgainst(core::rect<s32>(0, 0, (s32)renderTargetSize.Width, (s32)renderTargetSize.Height));\r
-       if (targetRect.getWidth() < 0 || targetRect.getHeight() < 0)\r
-               return;\r
-\r
-       // ok, we've clipped everything.\r
-       // now draw it.\r
-       const core::dimension2d<s32> sourceSize(targetRect.getSize());\r
-       const core::position2d<s32> sourcePos(sourceRect.UpperLeftCorner + (targetRect.UpperLeftCorner - destPos));\r
-\r
-       const core::dimension2d<u32>& tex_orgsize = texture->getOriginalSize();\r
-       const f32 invW = 1.f / static_cast<f32>(tex_orgsize.Width);\r
-       const f32 invH = 1.f / static_cast<f32>(tex_orgsize.Height);\r
-       const core::rect<f32> tcoords(\r
-               sourcePos.X * invW,\r
-               sourcePos.Y * invH,\r
-               (sourcePos.X + sourceSize.Width) * invW,\r
-               (sourcePos.Y + sourceSize.Height) * invH);\r
-\r
-\r
-       Quad2DVertices[0].Color = color;\r
-       Quad2DVertices[1].Color = color;\r
-       Quad2DVertices[2].Color = color;\r
-       Quad2DVertices[3].Color = color;\r
-\r
-       Quad2DVertices[0].Pos = core::vector3df((f32)targetRect.UpperLeftCorner.X, (f32)targetRect.UpperLeftCorner.Y, 0.0f);\r
-       Quad2DVertices[1].Pos = core::vector3df((f32)targetRect.LowerRightCorner.X, (f32)targetRect.UpperLeftCorner.Y, 0.0f);\r
-       Quad2DVertices[2].Pos = core::vector3df((f32)targetRect.LowerRightCorner.X, (f32)targetRect.LowerRightCorner.Y, 0.0f);\r
-       Quad2DVertices[3].Pos = core::vector3df((f32)targetRect.UpperLeftCorner.X, (f32)targetRect.LowerRightCorner.Y, 0.0f);\r
-\r
-       Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);\r
-       Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);\r
-       Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);\r
-       Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);\r
-\r
-       setRenderStates2DMode(color, texture, useAlphaChannelOfTexture);\r
-\r
-       drawVertexPrimitiveList(Quad2DVertices, 4,\r
-               quad_triangle_indexList, 2,\r
-               EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);\r
-\r
-       setRenderStates3DMode();\r
-\r
-}\r
-\r
-\r
-//! Draws a part of the texture into the rectangle.\r
-void CBurningVideoDriver::draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,\r
-       const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,\r
-       const video::SColor* const colors, bool useAlphaChannelOfTexture)\r
-{\r
-       const core::dimension2d<u32>& st = texture->getOriginalSize();\r
-       const f32 invW = 1.f / static_cast<f32>(st.Width);\r
-       const f32 invH = 1.f / static_cast<f32>(st.Height);\r
-       const core::rect<f32> tcoords(\r
-               sourceRect.UpperLeftCorner.X * invW,\r
-               sourceRect.UpperLeftCorner.Y * invH,\r
-               sourceRect.LowerRightCorner.X * invW,\r
-               sourceRect.LowerRightCorner.Y * invH);\r
-\r
-       const video::SColor temp[4] =\r
-       {\r
-               0xFFFFFFFF,\r
-               0xFFFFFFFF,\r
-               0xFFFFFFFF,\r
-               0xFFFFFFFF\r
-       };\r
-\r
-       const video::SColor* const useColor = colors ? colors : temp;\r
-\r
-\r
-       Quad2DVertices[0].Color = useColor[0];\r
-       Quad2DVertices[1].Color = useColor[3];\r
-       Quad2DVertices[2].Color = useColor[2];\r
-       Quad2DVertices[3].Color = useColor[1];\r
-\r
-       Quad2DVertices[0].Pos = core::vector3df((f32)destRect.UpperLeftCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f);\r
-       Quad2DVertices[1].Pos = core::vector3df((f32)destRect.LowerRightCorner.X, (f32)destRect.UpperLeftCorner.Y, 0.0f);\r
-       Quad2DVertices[2].Pos = core::vector3df((f32)destRect.LowerRightCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f);\r
-       Quad2DVertices[3].Pos = core::vector3df((f32)destRect.UpperLeftCorner.X, (f32)destRect.LowerRightCorner.Y, 0.0f);\r
-\r
-       Quad2DVertices[0].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);\r
-       Quad2DVertices[1].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);\r
-       Quad2DVertices[2].TCoords = core::vector2df(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);\r
-       Quad2DVertices[3].TCoords = core::vector2df(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);\r
-\r
-\r
-       if (clipRect)\r
-       {\r
-               if (!clipRect->isValid())\r
-                       return;\r
-\r
-               //glEnable(GL_SCISSOR_TEST);\r
-               EyeSpace.TL_Flag |= TL_SCISSOR;\r
-               setScissor(clipRect->UpperLeftCorner.X, clipRect->UpperLeftCorner.Y,//renderTargetSize.Height - clipRect->LowerRightCorner.Y\r
-                       clipRect->getWidth(), clipRect->getHeight());\r
-       }\r
-\r
-       video::SColor alphaTest;\r
-       alphaTest.color = useColor[0].color & useColor[0].color & useColor[0].color & useColor[0].color;\r
-\r
-\r
-       setRenderStates2DMode(alphaTest,texture, useAlphaChannelOfTexture);\r
-\r
-       drawVertexPrimitiveList(Quad2DVertices, 4,\r
-               quad_triangle_indexList, 2,\r
-               EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);\r
-\r
-       if (clipRect)\r
-               EyeSpace.TL_Flag &= ~TL_SCISSOR;\r
-\r
-       setRenderStates3DMode();\r
-\r
-}\r
-\r
-\r
-//!Draws an 2d rectangle with a gradient.\r
-void CBurningVideoDriver::draw2DRectangle(const core::rect<s32>& position,\r
-       SColor colorLeftUp, SColor colorRightUp, SColor colorLeftDown, SColor colorRightDown,\r
-       const core::rect<s32>* clip)\r
-{\r
-       core::rect<s32> pos = position;\r
-\r
-       if (clip)\r
-               pos.clipAgainst(*clip);\r
-\r
-       if (!pos.isValid())\r
-               return;\r
-\r
-       Quad2DVertices[0].Color = colorLeftUp;\r
-       Quad2DVertices[1].Color = colorRightUp;\r
-       Quad2DVertices[2].Color = colorRightDown;\r
-       Quad2DVertices[3].Color = colorLeftDown;\r
-\r
-       Quad2DVertices[0].Pos = core::vector3df((f32)pos.UpperLeftCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f);\r
-       Quad2DVertices[1].Pos = core::vector3df((f32)pos.LowerRightCorner.X, (f32)pos.UpperLeftCorner.Y, 0.0f);\r
-       Quad2DVertices[2].Pos = core::vector3df((f32)pos.LowerRightCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f);\r
-       Quad2DVertices[3].Pos = core::vector3df((f32)pos.UpperLeftCorner.X, (f32)pos.LowerRightCorner.Y, 0.0f);\r
-\r
-       Quad2DVertices[0].TCoords.X = 0.f;\r
-       Quad2DVertices[0].TCoords.Y = 0.f;\r
-       Quad2DVertices[1].TCoords.X = 0.f;\r
-       Quad2DVertices[1].TCoords.Y = 0.f;\r
-       Quad2DVertices[2].TCoords.X = 0.f;\r
-       Quad2DVertices[3].TCoords.Y = 0.f;\r
-       Quad2DVertices[3].TCoords.X = 0.f;\r
-       Quad2DVertices[3].TCoords.Y = 0.f;\r
-\r
-\r
-       video::SColor alphaTest;\r
-       alphaTest.color = colorLeftUp.color & colorRightUp.color & colorRightDown.color & colorLeftDown.color;\r
-       setRenderStates2DMode(alphaTest, 0, 0);\r
-\r
-       drawVertexPrimitiveList(Quad2DVertices, 4,\r
-               quad_triangle_indexList, 2,\r
-               EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);\r
-\r
-       setRenderStates3DMode();\r
-\r
-}\r
-\r
-\r
-#endif // SOFTWARE_DRIVER_2_2D_AS_3D\r
-\r
-\r
-\r
-\r
-\r
-//! Draws a 2d line.\r
-void CBurningVideoDriver::draw2DLine(const core::position2d<s32>& start,\r
-       const core::position2d<s32>& end,\r
-       SColor color)\r
-{\r
-       drawLine(RenderTargetSurface, start, end, color);\r
-}\r
-\r
-\r
-//! Draws a pixel\r
-void CBurningVideoDriver::drawPixel(u32 x, u32 y, const SColor& color)\r
-{\r
-       RenderTargetSurface->setPixel(x, y, color, true);\r
-}\r
-\r
-\r
-//! Only used by the internal engine. Used to notify the driver that\r
-//! the window was resized.\r
-void CBurningVideoDriver::OnResize(const core::dimension2d<u32>& size)\r
-{\r
-       // make sure width and height are multiples of 2\r
-       core::dimension2d<u32> realSize(size);\r
-       /*\r
-               if (realSize.Width % 2)\r
-                       realSize.Width += 1;\r
-\r
-               if (realSize.Height % 2)\r
-                       realSize.Height += 1;\r
-       */\r
-       if (ScreenSize != realSize)\r
-       {\r
-               if (ViewPort.getWidth() == (s32)ScreenSize.Width &&\r
-                       ViewPort.getHeight() == (s32)ScreenSize.Height)\r
-               {\r
-                       ViewPort.UpperLeftCorner.X = 0;\r
-                       ViewPort.UpperLeftCorner.Y = 0;\r
-                       ViewPort.LowerRightCorner.X = realSize.Width;\r
-                       ViewPort.LowerRightCorner.X = realSize.Height;\r
-               }\r
-\r
-               ScreenSize = realSize;\r
-\r
-               bool resetRT = (RenderTargetSurface == BackBuffer);\r
-\r
-               if (BackBuffer)\r
-                       BackBuffer->drop();\r
-               BackBuffer = new CImage(SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT, realSize);\r
-\r
-               if (resetRT)\r
-                       setRenderTargetImage2(BackBuffer);\r
-       }\r
-}\r
-\r
-\r
-//! returns the current render target size\r
-const core::dimension2d<u32>& CBurningVideoDriver::getCurrentRenderTargetSize() const\r
-{\r
-       return (RenderTargetSurface == BackBuffer) ? ScreenSize : RenderTargetSize;\r
-}\r
-\r
-\r
-\r
-//! Draws a 3d line.\r
-void CBurningVideoDriver::draw3DLine(const core::vector3df& start,\r
-       const core::vector3df& end, SColor color_start)\r
-{\r
-       SColor color_end = color_start;\r
-\r
-       VertexCache.primitiveHasVertex = 2;\r
-       VertexCache.vType = E4VT_LINE;\r
-\r
-       s4DVertex* v = Clipper.data;\r
-\r
-       transform_calc(ETS_PROJ_MODEL_VIEW);\r
-       const core::matrix4* matrix = Transformation[TransformationStack];\r
-       matrix[ETS_PROJ_MODEL_VIEW].transformVect(&v[s4DVertex_ofs(0)].Pos.x, start);\r
-       matrix[ETS_PROJ_MODEL_VIEW].transformVect(&v[s4DVertex_ofs(1)].Pos.x, end);\r
-\r
-#if BURNING_MATERIAL_MAX_COLORS > 0\r
-       v[s4DVertex_ofs(0)].Color[0].setA8R8G8B8(color_start.color);\r
-       v[s4DVertex_ofs(1)].Color[0].setA8R8G8B8(color_end.color);\r
-#endif\r
-\r
-       size_t has_vertex_run;\r
-       for (has_vertex_run = 0; has_vertex_run < VertexCache.primitiveHasVertex; has_vertex_run += 1)\r
-       {\r
-               v[s4DVertex_ofs(has_vertex_run)].flag = (u32)(VertexCache.vSize[VertexCache.vType].Format);\r
-               v[s4DVertex_proj(has_vertex_run)].flag = v[s4DVertex_ofs(has_vertex_run)].flag;\r
-       }\r
-\r
-       \r
-       size_t vOut;\r
-\r
-       // vertices count per line\r
-       vOut = clipToFrustum(VertexCache.primitiveHasVertex);\r
-       if (vOut < VertexCache.primitiveHasVertex)\r
-               return;\r
-\r
-       // to DC Space, project homogenous vertex\r
-       ndc_2_dc_and_project(v + s4DVertex_proj(0), v+ s4DVertex_ofs(0), s4DVertex_ofs(vOut));\r
-\r
-       // unproject vertex color\r
-#if 0\r
-#if BURNING_MATERIAL_MAX_COLORS > 0\r
-       for (g = 0; g != vOut; g += 2)\r
-       {\r
-               v[g + 1].Color[0].setA8R8G8B8(color.color);\r
-       }\r
-#endif\r
-#endif\r
-\r
-       IBurningShader* shader = 0;\r
-       if (CurrentShader && CurrentShader->canWireFrame()) shader = CurrentShader;\r
-       else shader = BurningShader[ETR_TEXTURE_GOURAUD_WIRE];\r
-       shader = BurningShader[ETR_TEXTURE_GOURAUD_WIRE];\r
-\r
-       shader->pushEdgeTest(1, 0, 1);\r
-       shader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced);\r
-\r
-       for (has_vertex_run = 0; (has_vertex_run + VertexCache.primitiveHasVertex) <= vOut; has_vertex_run += 1)\r
-       {\r
-               shader->drawLine(v + s4DVertex_proj(has_vertex_run), v + s4DVertex_proj(has_vertex_run+1));\r
-       }\r
-\r
-       shader->popEdgeTest();\r
-\r
-}\r
-\r
-\r
-//! \return Returns the name of the video driver. Example: In case of the DirectX8\r
-//! driver, it would return "Direct3D8.1".\r
-const wchar_t* CBurningVideoDriver::getName() const\r
-{\r
-#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
-       return L"Burning's Video 0.52 beautiful";\r
-#elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST )\r
-       return L"Burning's Video 0.52 ultra fast";\r
-#elif defined ( BURNINGVIDEO_RENDERER_FAST )\r
-       return L"Burning's Video 0.52 fast";\r
-#elif defined ( BURNINGVIDEO_RENDERER_CE )\r
-       return L"Burning's Video 0.52 CE";\r
-#else\r
-       return L"Burning's Video 0.52";\r
-#endif\r
-}\r
-\r
-//! Returns the graphics card vendor name.\r
-core::stringc CBurningVideoDriver::getVendorInfo()\r
-{\r
-       return "Burning's Video: Ing. Thomas Alten (c) 2006-2020";\r
-}\r
-\r
-\r
-//! Returns type of video driver\r
-E_DRIVER_TYPE CBurningVideoDriver::getDriverType() const\r
-{\r
-       return EDT_BURNINGSVIDEO;\r
-}\r
-\r
-\r
-//! returns color format\r
-ECOLOR_FORMAT CBurningVideoDriver::getColorFormat() const\r
-{\r
-       return BackBuffer ? BackBuffer->getColorFormat() : CNullDriver::getColorFormat();\r
-}\r
-\r
-\r
-//! Creates a render target texture.\r
-ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,\r
-       const io::path& name, const ECOLOR_FORMAT format\r
-#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-       , const bool useStencil\r
-#endif\r
-)\r
-{\r
-       //IImage* img = createImage(SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT, size);\r
-       //empty proxy image\r
-       IImage* img = createImageFromData(format, size, 0, true, false);\r
-       ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET /*| CSoftwareTexture2::GEN_MIPMAP */, this);\r
-       if ( img ) img->drop();\r
-       addTexture(tex);\r
-       tex->drop();\r
-       return tex;\r
-}\r
-\r
-void CBurningVideoDriver::clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil)\r
-{\r
-       if ((flag & ECBF_COLOR) && RenderTargetSurface) image_fill(RenderTargetSurface, color, Interlaced);\r
-       if ((flag & ECBF_DEPTH) && DepthBuffer) DepthBuffer->clear(depth, Interlaced);\r
-       if ((flag & ECBF_STENCIL) && StencilBuffer) StencilBuffer->clear(stencil, Interlaced);\r
-}\r
-\r
-#if 0\r
-void CBurningVideoDriver::saveBuffer()\r
-{\r
-       static int shotCount = 0;\r
-       char buf[256];\r
-       if (BackBuffer)\r
-       {\r
-               sprintf(buf, "shot/%04d_b.png", shotCount);\r
-               writeImageToFile(BackBuffer, buf);\r
-       }\r
-       if (StencilBuffer)\r
-       {\r
-               CImage stencil(ECF_A8R8G8B8, StencilBuffer->getSize(), StencilBuffer->lock(), true, false);\r
-               sprintf(buf, "shot/%04d_s.ppm", shotCount);\r
-               writeImageToFile(&stencil, buf);\r
-       }\r
-       shotCount += 1;\r
-}\r
-#endif\r
-\r
-//! Returns an image created from the last rendered frame.\r
-IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RENDER_TARGET target)\r
-{\r
-       if (target != video::ERT_FRAME_BUFFER)\r
-               return 0;\r
-\r
-       if (BackBuffer)\r
-       {\r
-               IImage* tmp = createImage(BackBuffer->getColorFormat(), BackBuffer->getDimension());\r
-               BackBuffer->copyTo(tmp);\r
-               return tmp;\r
-       }\r
-       else\r
-               return 0;\r
-}\r
-\r
-ITexture* CBurningVideoDriver::createDeviceDependentTexture(const io::path& name, IImage* image)\r
-{\r
-       u32 flags =\r
-               ((TextureCreationFlags & ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0)\r
-#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-               | CSoftwareTexture2::GEN_MIPMAP_AUTO\r
-#else\r
-               | ((TextureCreationFlags & ETCF_AUTO_GENERATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP_AUTO : 0)\r
-#endif\r
-               | ((TextureCreationFlags & ETCF_ALLOW_NON_POWER_2) ? CSoftwareTexture2::ALLOW_NPOT : 0)\r
-#if defined(IRRLICHT_sRGB)\r
-               | ((TextureCreationFlags & ETCF_IMAGE_IS_LINEAR) ? CSoftwareTexture2::IMAGE_IS_LINEAR : 0)\r
-               | ((TextureCreationFlags & ETCF_TEXTURE_IS_LINEAR) ? CSoftwareTexture2::TEXTURE_IS_LINEAR : 0)\r
-#endif\r
-               ;\r
-\r
-       CSoftwareTexture2* texture = new CSoftwareTexture2(image, name, flags, this);\r
-       return texture;\r
-}\r
-\r
-ITexture* CBurningVideoDriver::createDeviceDependentTextureCubemap(const io::path& name, const core::array<IImage*>& image)\r
-{\r
-       return 0;\r
-}\r
-\r
-//! Returns the maximum amount of primitives (mostly vertices) which\r
-//! the device is able to render with one drawIndexedTriangleList\r
-//! call.\r
-u32 CBurningVideoDriver::getMaximalPrimitiveCount() const\r
-{\r
-       return 0x7FFFFFFF;\r
-}\r
-\r
-\r
-//! Draws a shadow volume into the stencil buffer. To draw a stencil shadow, do\r
-//! this: First, draw all geometry. Then use this method, to draw the shadow\r
-//! volume. Next use IVideoDriver::drawStencilShadow() to visualize the shadow.\r
-void CBurningVideoDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)\r
-{\r
-       const u32 count = triangles.size();\r
-       if (!StencilBuffer || !count)\r
-               return;\r
-\r
-       Material.org.MaterialType = video::EMT_SOLID;\r
-       Material.org.Lighting = false;\r
-       Material.org.ZWriteEnable = video::EZW_OFF;\r
-       Material.org.ZBuffer = ECFN_LESS;\r
-\r
-       CurrentShader = BurningShader[ETR_STENCIL_SHADOW];\r
-\r
-       CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort, Interlaced);\r
-       CurrentShader->pushEdgeTest(Material.org.Wireframe, 0, 0);\r
-\r
-       //setMaterial\r
-       EyeSpace.TL_Flag &= ~(TL_TEXTURE_TRANSFORM | TL_LIGHT0_IS_NORMAL_MAP);\r
-       CurrentShader->setTLFlag(EyeSpace.TL_Flag);\r
-       //glStencilMask(~0);\r
-       //glStencilFunc(GL_ALWAYS, 0, ~0);\r
-\r
-       //glEnable(GL_DEPTH_CLAMP);\r
-\r
-       if (zfail)\r
-       {\r
-               Material.org.BackfaceCulling = false;\r
-               Material.org.FrontfaceCulling = true;\r
-               Material.CullFlag = CULL_FRONT | CULL_INVISIBLE;\r
-\r
-               CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_INCR, StencilOp_KEEP);\r
-               drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
-\r
-               Material.org.BackfaceCulling = true;\r
-               Material.org.FrontfaceCulling = false;\r
-               Material.CullFlag = CULL_BACK | CULL_INVISIBLE;\r
-\r
-               CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_DECR, StencilOp_KEEP);\r
-               drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
-       }\r
-       else // zpass\r
-       {\r
-               Material.org.BackfaceCulling = true;\r
-               Material.org.FrontfaceCulling = false;\r
-               Material.CullFlag = CULL_BACK | CULL_INVISIBLE;\r
-\r
-               CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_KEEP, StencilOp_INCR);\r
-               drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
-\r
-               Material.org.BackfaceCulling = false;\r
-               Material.org.FrontfaceCulling = true;\r
-               Material.CullFlag = CULL_FRONT | CULL_INVISIBLE;\r
-\r
-               CurrentShader->setStencilOp(StencilOp_KEEP, StencilOp_KEEP, StencilOp_DECR);\r
-               drawVertexPrimitiveList(triangles.const_pointer(), count, 0, count / 3, (video::E_VERTEX_TYPE) E4VT_SHADOW, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) E4IT_NONE);\r
-       }\r
-       //glDisable(GL_DEPTH_CLAMP);\r
-\r
-}\r
-\r
-//! Fills the stencil shadow with color. After the shadow volume has been drawn\r
-//! into the stencil buffer using IVideoDriver::drawStencilShadowVolume(), use this\r
-//! to draw the color of the shadow.\r
-void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SColor leftUpEdge,\r
-       video::SColor rightUpEdge, video::SColor leftDownEdge, video::SColor rightDownEdge)\r
-{\r
-       if (!StencilBuffer)\r
-               return;\r
-\r
-       // draw a shadow rectangle covering the entire screen using stencil buffer\r
-       const u32 h = RenderTargetSurface->getDimension().Height;\r
-       const u32 w = RenderTargetSurface->getDimension().Width;\r
-\r
-       const bool bit32 = RenderTargetSurface->getColorFormat() == ECF_A8R8G8B8;\r
-       const tVideoSample alpha = extractAlpha(leftUpEdge.color) >> (bit32 ? 0 : 3);\r
-       const tVideoSample src = bit32 ? leftUpEdge.color : video::A8R8G8B8toA1R5G5B5(leftUpEdge.color);\r
-\r
-       interlace_scanline_data line;\r
-       for (line.y = 0; line.y < h; line.y += SOFTWARE_DRIVER_2_STEP_Y)\r
-       {\r
-               interlace_scanline\r
-               {\r
-                       tVideoSample * dst = (tVideoSample*)RenderTargetSurface->getData() + (line.y * w);\r
-                       const tStencilSample* stencil = (tStencilSample*)StencilBuffer->lock() + (line.y * w);\r
-\r
-                       if (bit32)\r
-                       {\r
-                               for (u32 x = 0; x < w; x += SOFTWARE_DRIVER_2_STEP_X)\r
-                               {\r
-                                       if (stencil[x]) dst[x] = PixelBlend32(dst[x], src, alpha);\r
-                               }\r
-                       }\r
-                       else\r
-                       {\r
-                               for (u32 x = 0; x < w; x += SOFTWARE_DRIVER_2_STEP_X)\r
-                               {\r
-                                       if (stencil[x]) dst[x] = PixelBlend16(dst[x], src, alpha);\r
-                               }\r
-                       }\r
-\r
-               }\r
-       }\r
-\r
-       if (clearStencilBuffer)\r
-               StencilBuffer->clear(0, Interlaced);\r
-}\r
-\r
-\r
-core::dimension2du CBurningVideoDriver::getMaxTextureSize() const\r
-{\r
-       return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE, SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE);\r
-}\r
-\r
-bool CBurningVideoDriver::queryTextureFormat(ECOLOR_FORMAT format) const\r
-{\r
-       return format == SOFTWARE_DRIVER_2_RENDERTARGET_COLOR_FORMAT || format == SOFTWARE_DRIVER_2_TEXTURE_COLOR_FORMAT;\r
-}\r
-\r
-#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-bool CBurningVideoDriver::needsTransparentRenderPass(const irr::video::SMaterial& material) const\r
-{\r
-       return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); // || material.isTransparent();\r
-}\r
-#endif\r
-\r
-s32 CBurningVideoDriver::addShaderMaterial(const c8* vertexShaderProgram,\r
-       const c8* pixelShaderProgram,\r
-       IShaderConstantSetCallBack* callback,\r
-       E_MATERIAL_TYPE baseMaterial,\r
-       s32 userData)\r
-{\r
-       s32 materialID = -1;\r
-\r
-       IBurningShader* shader = new IBurningShader(\r
-               this, materialID,\r
-               vertexShaderProgram, 0, video::EVST_VS_1_1,\r
-               pixelShaderProgram, 0, video::EPST_PS_1_1,\r
-               0, 0, EGST_GS_4_0,\r
-               scene::EPT_TRIANGLES, scene::EPT_TRIANGLE_STRIP, 0,\r
-               callback, baseMaterial, userData);\r
-\r
-       shader->drop();\r
-\r
-       return materialID;\r
-}\r
-\r
-//! Adds a new material renderer to the VideoDriver, based on a high level shading language.\r
-s32 CBurningVideoDriver::addHighLevelShaderMaterial(\r
-       const c8* vertexShaderProgram,\r
-       const c8* vertexShaderEntryPointName,\r
-       E_VERTEX_SHADER_TYPE vsCompileTarget,\r
-       const c8* pixelShaderProgram,\r
-       const c8* pixelShaderEntryPointName,\r
-       E_PIXEL_SHADER_TYPE psCompileTarget,\r
-       const c8* geometryShaderProgram,\r
-       const c8* geometryShaderEntryPointName,\r
-       E_GEOMETRY_SHADER_TYPE gsCompileTarget,\r
-       scene::E_PRIMITIVE_TYPE inType,\r
-       scene::E_PRIMITIVE_TYPE outType,\r
-       u32 verticesOut,\r
-       IShaderConstantSetCallBack* callback,\r
-       E_MATERIAL_TYPE baseMaterial,\r
-       s32 userData\r
-#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
-       , E_GPU_SHADING_LANGUAGE shadingLang\r
-#endif\r
-)\r
-{\r
-       s32 materialID = -1;\r
-\r
-       IBurningShader* shader = new IBurningShader(\r
-               this, materialID,\r
-               vertexShaderProgram, vertexShaderEntryPointName, vsCompileTarget,\r
-               pixelShaderProgram, pixelShaderEntryPointName, psCompileTarget,\r
-               geometryShaderProgram, geometryShaderEntryPointName, gsCompileTarget,\r
-               inType, outType, verticesOut,\r
-               callback, baseMaterial, userData);\r
-\r
-       shader->drop();\r
-\r
-       return materialID;\r
-}\r
-\r
-\r
-void CBurningVideoDriver::setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType)\r
-{\r
-       //this should be in material....\r
-       Material.Fallback_MaterialType = fallback_MaterialType;\r
-}\r
-\r
-void CBurningVideoDriver::setBasicRenderStates(const SMaterial& material,\r
-       const SMaterial& lastMaterial,\r
-       bool resetAllRenderstates)\r
-{\r
-\r
-}\r
-\r
-//! Return an index constant for the vertex shader based on a name.\r
-s32 CBurningVideoDriver::getVertexShaderConstantID(const c8* name)\r
-{\r
-       return -1;\r
-}\r
-\r
-bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const f32* floats, int count)\r
-{\r
-       return true;\r
-}\r
-\r
-bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const s32* ints, int count)\r
-{\r
-       return true;\r
-}\r
-\r
-bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const u32* ints, int count)\r
-{\r
-       return true;\r
-}\r
-\r
-void CBurningVideoDriver::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
-{\r
-}\r
-\r
-//! Return an index constant for the pixel shader based on a name.\r
-s32 CBurningVideoDriver::getPixelShaderConstantID(const c8* name)\r
-{\r
-       return -1;\r
-}\r
-\r
-bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const f32* floats, int count)\r
-{\r
-       return false;\r
-}\r
-\r
-bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const s32* ints, int count)\r
-{\r
-       return false;\r
-}\r
-\r
-bool CBurningVideoDriver::setPixelShaderConstant(s32 index, const u32* ints, int count)\r
-{\r
-       return false;\r
-}\r
-\r
-void CBurningVideoDriver::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1)\r
-{\r
-}\r
-\r
-//! Get pointer to the IVideoDriver interface\r
-/** \return Pointer to the IVideoDriver interface */\r
-IVideoDriver* CBurningVideoDriver::getVideoDriver()\r
-{\r
-       return this;\r
-}\r
-\r
-} // end namespace video\r
-} // end namespace irr\r
-\r
-#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
-\r
-\r
-namespace irr\r
-{\r
-namespace video\r
-{\r
-\r
-//! creates a video driver\r
-IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter)\r
-{\r
-#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
-       return new CBurningVideoDriver(params, io, presenter);\r
-#else\r
-       return 0;\r
-#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
-}\r
-\r
-\r
-\r
-} // end namespace video\r
-} // end namespace irr\r
-\r