]> git.lizzy.rs Git - irrlicht.git/commitdiff
Merging r6075 through r6106 from trunk to ogl-es branch.
authorcutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>
Fri, 12 Jun 2020 20:41:49 +0000 (20:41 +0000)
committercutealien <cutealien@dfc29bdd-3216-0410-991c-e03cc46cb475>
Fri, 12 Jun 2020 20:41:49 +0000 (20:41 +0000)
Burnings renderer changes.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@6116 dfc29bdd-3216-0410-991c-e03cc46cb475

117 files changed:
changes.txt
examples/05.UserInterface/main.cpp
examples/09.Meshviewer/main.cpp
examples/10.Shaders/main.cpp
examples/11.PerPixelLighting/main.cpp
examples/12.TerrainRendering/main.cpp
examples/16.Quake3MapShader/main.cpp
examples/22.MaterialViewer/main.cpp
examples/23.SMeshHandling/main.cpp
examples/25.XmlHandling/main.cpp
examples/Demo/CDemo.cpp
examples/Demo/CMainMenu.cpp
source/Irrlicht/Android/jni/Android.mk
source/Irrlicht/CAnimatedMeshSceneNode.cpp
source/Irrlicht/CBlit.h
source/Irrlicht/CBurningShader_Raster_Reference.cpp
source/Irrlicht/CDepthBuffer.cpp
source/Irrlicht/CDepthBuffer.h
source/Irrlicht/CGUIContextMenu.cpp
source/Irrlicht/CImage.cpp
source/Irrlicht/CImageLoaderRGB.cpp
source/Irrlicht/CMY3DMeshFileLoader.h
source/Irrlicht/COBJMeshFileLoader.cpp
source/Irrlicht/COSOperator.cpp
source/Irrlicht/CSoftware2MaterialRenderer.h
source/Irrlicht/CSoftwareDriver2.cpp
source/Irrlicht/CSoftwareDriver2.h
source/Irrlicht/CSoftwareTexture2.cpp
source/Irrlicht/CSoftwareTexture2.h
source/Irrlicht/CTRGouraud2.cpp
source/Irrlicht/CTRGouraudAlpha2.cpp
source/Irrlicht/CTRGouraudAlphaNoZ2.cpp
source/Irrlicht/CTRGouraudNoZ2.cpp [new file with mode: 0644]
source/Irrlicht/CTRNormalMap.cpp
source/Irrlicht/CTRStencilShadow.cpp
source/Irrlicht/CTRTextureBlend.cpp
source/Irrlicht/CTRTextureDetailMap2.cpp
source/Irrlicht/CTRTextureGouraud2.cpp
source/Irrlicht/CTRTextureGouraudAdd2.cpp
source/Irrlicht/CTRTextureGouraudAddNoZ2.cpp
source/Irrlicht/CTRTextureGouraudAlpha.cpp
source/Irrlicht/CTRTextureGouraudAlphaNoZ.cpp
source/Irrlicht/CTRTextureGouraudNoZ2.cpp
source/Irrlicht/CTRTextureGouraudVertexAlpha2.cpp
source/Irrlicht/CTRTextureLightMap2_Add.cpp
source/Irrlicht/CTRTextureLightMap2_M1.cpp
source/Irrlicht/CTRTextureLightMap2_M2.cpp
source/Irrlicht/CTRTextureLightMap2_M4.cpp
source/Irrlicht/CTRTextureLightMapGouraud2_M4.cpp
source/Irrlicht/CTRTextureWire2.cpp
source/Irrlicht/CTR_transparent_reflection_2_layer.cpp [new file with mode: 0644]
source/Irrlicht/CXMeshFileLoader.cpp
source/Irrlicht/IBurningShader.cpp
source/Irrlicht/IBurningShader.h
source/Irrlicht/IDepthBuffer.h
source/Irrlicht/Irrlicht-gcc.cbp
source/Irrlicht/Irrlicht10.0.vcxproj
source/Irrlicht/Irrlicht10.0.vcxproj.filters
source/Irrlicht/Irrlicht11.0.vcxproj
source/Irrlicht/Irrlicht11.0.vcxproj.filters
source/Irrlicht/Irrlicht12.0.vcxproj
source/Irrlicht/Irrlicht12.0.vcxproj.filters
source/Irrlicht/Irrlicht14.0.vcxproj
source/Irrlicht/Irrlicht14.0.vcxproj.filters
source/Irrlicht/Irrlicht15.0.vcxproj
source/Irrlicht/Irrlicht15.0.vcxproj.filters
source/Irrlicht/Makefile
source/Irrlicht/S4DVertex.h
source/Irrlicht/SoftwareDriver2_compile_config.h
source/Irrlicht/SoftwareDriver2_helper.h
source/Irrlicht/burning_shader_color.cpp [new file with mode: 0644]
source/Irrlicht/burning_shader_color_fraq.h [new file with mode: 0644]
source/Irrlicht/burning_shader_compile_fragment_default.h [new file with mode: 0644]
source/Irrlicht/burning_shader_compile_fragment_end.h [new file with mode: 0644]
source/Irrlicht/burning_shader_compile_fragment_start.h [new file with mode: 0644]
source/Irrlicht/burning_shader_compile_start.h [new file with mode: 0644]
source/Irrlicht/burning_shader_compile_triangle.h [new file with mode: 0644]
source/Irrlicht/burning_shader_compile_verify.h [new file with mode: 0644]
tests/media/Burning's Video-2dmatFilter.png
tests/media/Burning's Video-b3dAnimation.png
tests/media/Burning's Video-b3dJointPosition.png
tests/media/Burning's Video-billboard.png
tests/media/Burning's Video-billboardOrientation.png
tests/media/Burning's Video-draw2DImage4cFilter.png
tests/media/Burning's Video-drawPixel.png
tests/media/Burning's Video-drawVPL_e.png
tests/media/Burning's Video-drawVPL_g.png
tests/media/Burning's Video-drawVPL_h.png
tests/media/Burning's Video-drawVPL_i.png
tests/media/Burning's Video-flyCircleAnimator.png
tests/media/Burning's Video-lightType.png
tests/media/Burning's Video-loadScene.png
tests/media/Burning's Video-md2Normals.png
tests/media/Burning's Video-multiTexture.png
tests/media/Burning's Video-orthoCam.png
tests/media/Burning's Video-planeMatrix-scaledClip.png
tests/media/Burning's Video-renderMipmap.png
tests/media/Burning's Video-stencilSelfShadow.png
tests/media/Burning's Video-stencilShadow.png
tests/media/Burning's Video-terrainGap.png
tests/media/Burning's Video-terrainSceneNode-1.png
tests/media/Burning's Video-terrainSceneNode-2.png
tests/media/Burning's Video-testGeometryCreator.png
tests/media/Burning's Video-testTerrainMesh.png
tests/media/Burning's Video-textureMatrix.png [new file with mode: 0644]
tests/media/Burning's Video-textureMatrix2.png [new file with mode: 0644]
tests/media/Burning's Video-textureMatrixInMixedScenes.png [new file with mode: 0644]
tests/media/Burning's Video-textureRenderStates.png
tests/media/Burning's Video-transparentAddColor.png
tests/media/Burning's Video-transparentAlphaChannel.png
tests/media/Burning's Video-transparentAlphaChannelRef.png
tests/media/Burning's Video-transparentReflection2Layer.png
tests/media/Burning's Video-transparentVertexAlpha.png
tests/media/Burning's Video-transparentVertexAlphaChannelMore.png
tests/media/Burning's Video-viewPortText.png
tests/media/Burning's Video-writeImageToFile.png [new file with mode: 0644]
tests/tests-last-passed-at.txt

index fd1732bdb8b11cb34a0bcd79eaa7ebaa770f0bf2..c213dfc6b86295d8d672e650fe7ae850f862828f 100644 (file)
@@ -9,6 +9,18 @@ Changes in ogl-es (not yet released - will be merged with trunk at some point)
 \r
 --------------------------\r
 Changes in 1.9 (not yet released)\r
+- BurningVideo: 0.51\r
+  - 10 year anniversary update\r
+  - Lighting model reworked. moved to eyespace like openGL. [Specular Highlights, Fog, Sphere/Reflection Map] \r
+  - increased internal s4DVertex to support 4 Textures and 4 Colors [switchable]\r
+  - Textures are handled as sRGB during Mipmap Generation. More accurate, less visual disruption\r
+  - 2D is drawn as 3D like hardware drivers. [switchable]. enables viewport scaling, material2D\r
+  - Texture Spatial Resolution Limiting working. [lower memory consumption,SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE]\r
+  - NormalMap for 1 Light accurate. still all lights are accumulated\r
+  - SuperTuxKart 8.0.1 playable\r
+  - Known Problems\r
+    - Depthbuffer range not equal to Hardware Drivers. Problems with Orthographic Stencil Shadows\r
+       - Triangle MipMap Selection. Wrong for TextureAtlas and Billboards\r
 - Fix CPLYMeshFileLoader checking for wrong vertex count when switching between 16/32 bit. Thanks @randomMesh for reporting.\r
 - Fix bug that AnimatedMeshSceneNode ignored ReadOnlyMaterials flag when checking materials for transparent render passes.\r
 - Unify checks if materials should use transparent render pass with new IVideoDriver::needsTransparentRenderPass function.\r
index 501eed3d531dd61bda95ea2cd3e9dfe8f23d5024..deaba6f1f7cee4e3914daf02870cb12ad702c7b6 100644 (file)
@@ -266,7 +266,7 @@ int main()
        /*\r
        And at last, we create a nice Irrlicht Engine logo in the top left corner.\r
        */\r
-       env->addImage(driver->getTexture(mediaPath + "irrlichtlogo2.png"),\r
+       env->addImage(driver->getTexture(mediaPath + "irrlichtlogo3.png"),\r
                        position2d<int>(10,10));\r
 \r
 \r
index 010ad6eb26803b68b17f503bed1b0d3f0ed5b43b..1a5f51a93969b9a172ad3ffd866df9fcb13fa74d 100644 (file)
@@ -978,7 +978,7 @@ int main(int argc, char* argv[])
 \r
        // load the irrlicht engine logo\r
        IGUIImage *img =\r
-               env->addImage(driver->getTexture("irrlichtlogo2.png"),\r
+               env->addImage(driver->getTexture("irrlichtlogo3.png"),\r
                        core::position2d<s32>(10, driver->getScreenSize().Height - 128));\r
 \r
        // lock the logo's edges to the bottom left corner of the screen\r
index 1beb3deb2da946a924cd29a9edfbe42429cd2b48..ff80bd51e3c35f22caf9848817c1feae6b46a56d 100644 (file)
@@ -236,6 +236,8 @@ int main()
                        vsFileName = mediaPath + "opengl.vsh";\r
                }\r
                break;\r
+       default:\r
+               break;\r
        }\r
 \r
        /*\r
index c2e03af26e375656ddaa72e46555a87a06d2764e..afa59cb519d28b95e4131e362108cc453081414f 100644 (file)
@@ -285,9 +285,9 @@ int main()
                                driver->getTexture(mediaPath + "rockwall.jpg"));\r
                room->setMaterialTexture(1, normalMap);\r
 \r
-               // Stones don't glitter..\r
-               room->getMaterial(0).SpecularColor.set(0,0,0,0);\r
-               room->getMaterial(0).Shininess = 0.f;\r
+               // Stones don't glitter.. (but specular highlight for EMT_SOLID)\r
+               //room->getMaterial(0).SpecularColor.set(0,0,0,0);\r
+               //room->getMaterial(0).Shininess = 0.f;\r
 \r
                room->setMaterialFlag(video::EMF_FOG_ENABLE, true);\r
                room->setMaterialType(video::EMT_PARALLAX_MAP_SOLID);\r
@@ -365,7 +365,7 @@ int main()
        // add light 1 (more green)\r
        scene::ILightSceneNode* light1 =\r
                smgr->addLightSceneNode(0, core::vector3df(0,0,0),\r
-               video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 800.0f);\r
+               video::SColorf(0.5f, 1.0f, 0.5f, 0.0f), 400.0f);\r
 \r
        // add fly circle animator to light 1\r
        scene::ISceneNodeAnimator* anim =\r
@@ -398,7 +398,7 @@ int main()
        // add light 2 (red)\r
        scene::ISceneNode* light2 =\r
                smgr->addLightSceneNode(0, core::vector3df(0,0,0),\r
-               video::SColorf(1.0f, 0.2f, 0.2f, 0.0f), 800.0f);\r
+               video::SColorf(1.0f, 0.2f, 0.2f, 0.0f), 400.0f);\r
 \r
        // add fly circle animator to light 2\r
        anim = smgr->createFlyCircleAnimator(core::vector3df(0,150,0), 200.0f,\r
index 7c38598e14509691ef6446a9d73032fbbb092c87..f9bc97e614d3ce0435654f7a616543d99daa34cb 100644 (file)
@@ -120,7 +120,7 @@ int main()
        const io::path mediaPath = getExampleMediaPath();\r
 \r
        // add irrlicht logo\r
-       env->addImage(driver->getTexture(mediaPath + "irrlichtlogo2.png"),\r
+       env->addImage(driver->getTexture(mediaPath + "irrlichtlogo3.png"),\r
                core::position2d<s32>(10,10));\r
 \r
        //set other font\r
@@ -213,6 +213,7 @@ int main()
        terrain->getMeshBufferForLOD(*buffer, 0);\r
        video::S3DVertex2TCoords* data = (video::S3DVertex2TCoords*)buffer->getVertexBuffer().getData();\r
        // Work on data or get the IndexBuffer with a similar call.\r
+       (void)data; // disable unused variable warnings\r
        buffer->drop(); // When done drop the buffer again.\r
 \r
        /*\r
index e8a318dce26fdf296415d0399d9686b12f969348..38062c5aa6742df8e48f70d69b1d844d66926ea0 100644 (file)
@@ -318,7 +318,7 @@ int IRRCALLCONV main(int argc, char* argv[])
        device->getCursorControl()->setVisible(false);\r
 \r
        // load the engine logo\r
-       gui->addImage(driver->getTexture("irrlichtlogo2.png"),\r
+       gui->addImage(driver->getTexture("irrlichtlogo3.png"),\r
                        core::position2d<s32>(10, 10));\r
 \r
        // show the driver logo\r
@@ -335,6 +335,8 @@ int IRRCALLCONV main(int argc, char* argv[])
                case video::EDT_DIRECT3D9:\r
                        gui->addImage(driver->getTexture("directxlogo.png"), pos);\r
                        break;\r
+               default:\r
+                       break;\r
        }\r
 \r
        /*\r
@@ -355,14 +357,14 @@ int IRRCALLCONV main(int argc, char* argv[])
                driver->endScene();\r
 \r
                int fps = driver->getFPS();\r
-               //if (lastFPS != fps)\r
+               if (1 || lastFPS != fps)\r
                {\r
-                       io::IAttributes * const attr = smgr->getParameters();\r
                        core::stringw str = L"Q3 [";\r
                        str += driver->getName();\r
                        str += "] FPS:";\r
                        str += fps;\r
 #ifdef _IRR_SCENEMANAGER_DEBUG                 \r
+                       io::IAttributes * const attr = smgr->getParameters();\r
                        str += " Cull:";\r
                        str += attr->getAttributeAsInt("calls");\r
                        str += "/";\r
index 833092609fcd64f364a71555b50a469c03ecb7aa..358ce02c85696dfd14aa2a49e9443faaf6515f11 100755 (executable)
@@ -429,7 +429,7 @@ void CMaterialControl::init(scene::IMeshSceneNode* node, IrrlichtDevice * device
 \r
        Driver = device->getVideoDriver ();\r
        gui::IGUIEnvironment* guiEnv = device->getGUIEnvironment();\r
-       scene::ISceneManager* smgr = device->getSceneManager();\r
+       //scene::ISceneManager* smgr = device->getSceneManager();\r
        const video::SMaterial & material = node->getMaterial(0);\r
 \r
        s32 top = pos.Y;\r
index 2d413094976a5bbc148b13cd32e90ec5a6e5a18b..a4ef9ebc24e8bb2de3edcacb99eec32a307b1b91 100644 (file)
@@ -57,7 +57,7 @@ typedef f32 generate_func(s16 x, s16 y, f32 s);
 f32 eggbox(s16 x, s16 y, f32 s)\r
 {\r
        const f32 r = 4.f*sqrtf((f32)(x*x + y*y))/s;\r
-       const f32 z = expf(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));\r
+       const f32 z = (f32)exp(-r * 2) * (cosf(0.2f * x) + cosf(0.2f * y));\r
        return 0.25f+0.25f*z;\r
 }\r
 \r
@@ -180,7 +180,7 @@ private:
 public:\r
        SMesh* Mesh;\r
 \r
-       TMesh() : Mesh(0), Width(0), Height(0), Scale(1.f)\r
+       TMesh() : Width(0), Height(0), Scale(1.f), Mesh(0)\r
        {\r
                Mesh = new SMesh();\r
        }\r
index 657ad8dc276956d0e17419c65ac54815230870b2..d022e5c277a3d15884ae4653f7ff63302acaef63 100644 (file)
@@ -142,6 +142,8 @@ public:
                                        //we were at the end of the video section so we reset our tag\r
                                        currentSection=L"";\r
                                break;\r
+                               default:\r
+                                       break;\r
                        }\r
                }\r
 \r
@@ -344,6 +346,8 @@ public:
                                        }\r
                                }\r
                                break;\r
+                               default:\r
+                                       break;\r
                        }\r
                }\r
 \r
index 49dd7b6ee03ce47271f65d16a86aa2f56de15a32..6c073ab314f72afb3dfbdb8048801a7b0de37e97 100644 (file)
@@ -497,6 +497,7 @@ void CDemo::loadSceneData()
                bill = sm->addBillboardSceneNode(0, core::dimension2d<f32>(100,100),\r
                        waypoint[r]+ core::vector3df(0,20,0));\r
                bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
+               bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
                bill->setMaterialTexture(0, driver->getTexture(mediaPath + "portal1.bmp"));\r
                bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
                bill->addAnimator(anim);\r
@@ -583,7 +584,7 @@ void CDemo::createLoadingScreen()
        const io::path mediaPath = getExampleMediaPath();\r
 \r
        // irrlicht logo\r
-       device->getGUIEnvironment()->addImage(device->getVideoDriver()->getTexture(mediaPath + "irrlichtlogo2.png"),\r
+       device->getGUIEnvironment()->addImage(device->getVideoDriver()->getTexture(mediaPath + "irrlichtlogo3.png"),\r
                core::position2d<s32>(5,5));\r
 \r
        // loading text\r
@@ -648,8 +649,8 @@ void CDemo::shoot()
        else\r
        {\r
                // doesnt collide with wall\r
-               core::vector3df start = camera->getPosition();\r
-               core::vector3df end = (camera->getTarget() - start);\r
+               start = camera->getPosition();\r
+               end = (camera->getTarget() - start);\r
                end.normalize();\r
                start += end*8.0f;\r
                end = start + (end * camera->getFarValue());\r
index ebc9469e8ad9845a51353834cf0cf8b96c5873d2..432c87274b999e642c9c8582eb81b159f2622cd5 100644 (file)
@@ -27,9 +27,9 @@ CMainMenu::CMainMenu()
 \r
 bool CMainMenu::run()\r
 {\r
-       video::E_DRIVER_TYPE driverType = EDT_OPENGL;\r
+       video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;\r
        if (!IrrlichtDevice::isDriverSupported(video::EDT_OPENGL))\r
-               driverType = video::video::EDT_BURNINGSVIDEO;\r
+               driverType = video::EDT_BURNINGSVIDEO;\r
 \r
        MenuDevice = createDevice(driverType,\r
                core::dimension2d<u32>(512, 384), 16, false, false, false, this);\r
@@ -195,6 +195,7 @@ bool CMainMenu::run()
                                {\r
                                        bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
                                        bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
+                                       bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
                                        bill->setMaterialTexture(0, driver->getTexture(mediaPath + "particlered.bmp"));\r
                                }\r
                                // add fly circle animator to the light\r
@@ -213,6 +214,7 @@ bool CMainMenu::run()
                                {\r
                                        bill->setMaterialFlag(video::EMF_LIGHTING, false);\r
                                        bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);\r
+                                       bill->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);\r
                                        bill->setMaterialTexture(0, driver->getTexture(mediaPath + "portal1.bmp"));\r
                                }\r
                                // add fly circle animator to the light\r
@@ -275,7 +277,7 @@ bool CMainMenu::run()
                {\r
                        if (!selected)\r
                        {\r
-                               outDriver=video::E_DRIVER_TYPE(i);\r
+                               driverType=video::E_DRIVER_TYPE(i);\r
                                break;\r
                        }\r
                        --selected;\r
index 54fb245b3703d353c5a4f410e6e255ec7730b62a..05a2d2814dad96b1f13c259702f3e9c2319e1741 100755 (executable)
@@ -31,6 +31,7 @@ LOCAL_SRC_FILES := \
                                        aesGladman/pwd2key.cpp \
                                        aesGladman/sha1.cpp \
                                        aesGladman/sha2.cpp \
+                                       burning_shader_color.cpp \
                                        C3DSMeshFileLoader.cpp \
                                        CAnimatedMeshHalfLife.cpp \
                                        CAnimatedMeshMD2.cpp \
@@ -221,6 +222,7 @@ LOCAL_SRC_FILES := \
                                        CTRGouraudWire.cpp \
                                        CTriangleBBSelector.cpp \
                                        CTriangleSelector.cpp \
+                                       CTRGouraudNoZ2.cpp \
                                        CTRNormalMap.cpp \
                                        CTRStencilShadow.cpp \
                                        CTRTextureBlend.cpp \
@@ -244,6 +246,7 @@ LOCAL_SRC_FILES := \
                                        CTRTextureLightMap2_M4.cpp \
                                        CTRTextureLightMapGouraud2_M4.cpp \
                                        CTRTextureWire2.cpp \
+                                       CTR_transparent_reflection_2_layer.cpp \
                                        CVideoModeList.cpp \
                                        CVolumeLightSceneNode.cpp \
                                        CWADReader.cpp \
index 593496a490a86512d0183eee3a9c099494e3b63d..de96749bd54990aa53c1bdd26712395f6a4d41af 100644 (file)
@@ -112,12 +112,12 @@ void CAnimatedMeshSceneNode::buildFrameNr(u32 timeMs)
                if (FramesPerSecond > 0.f) //forwards...\r
                {\r
                        if (CurrentFrameNr > EndFrame)\r
-                               CurrentFrameNr = StartFrame + fmod(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame));\r
+                               CurrentFrameNr = StartFrame + fmodf(CurrentFrameNr - StartFrame, (f32)(EndFrame-StartFrame));\r
                }\r
                else //backwards...\r
                {\r
                        if (CurrentFrameNr < StartFrame)\r
-                               CurrentFrameNr = EndFrame - fmod(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame));\r
+                               CurrentFrameNr = EndFrame - fmodf(EndFrame - CurrentFrameNr, (f32)(EndFrame-StartFrame));\r
                }\r
        }\r
        else\r
index d67a76b00a8ce7f3862823c7426fddba3632c530..b7788289da512ce09b69bedabc141587f0fb8024 100644 (file)
 namespace irr\r
 {\r
 \r
+//! f18 - fixpoint 14.18 limit to 16k Textures\r
+#define CBLIT_USE_FIXPOINT18\r
+\r
+#if defined(CBLIT_USE_FIXPOINT18)\r
+       typedef int f18;\r
+       #define f18_one 262144\r
+       #define f18_zero 0\r
+       #define f32_to_f18(x)((f18)floorf(((x) * 262144.f) + 0.f))\r
+       #define f32_to_f32(x)(x)\r
+       #define f18_floor(x) ((x)>>18)\r
+       #define f18_round(x) ((x+131.072)>>18)\r
+#else\r
+       typedef float f18;\r
+       #define f18_one 1.f\r
+       #define f18_zero_dot_five 0.5f\r
+       #define f18_zero 0.f\r
+       #define f32_to_f18(x)(x)\r
+       #define f32_to_f32(x)(x)\r
+       #define f18_floor(x) ((int)(x))\r
+       #define f18_round(x) ((int)(x+0.5f))\r
+#endif\r
+\r
        struct SBlitJob\r
        {\r
                AbsRectangle Dest;\r
@@ -17,23 +39,21 @@ namespace irr
 \r
                u32 argb;\r
 \r
-               void * src;\r
-               void * dst;\r
+               const void* src;\r
+               void* dst;\r
 \r
-               s32 width;\r
-               s32 height;\r
+               u32 width;              //draw size\r
+               u32 height;\r
 \r
-               u32 srcPitch;\r
-               u32 dstPitch;\r
-\r
-               u32 srcPixelMul;\r
+               u32 srcPixelMul; //pixel byte size\r
                u32 dstPixelMul;\r
 \r
-               bool stretch;\r
-               float x_stretch;\r
-               float y_stretch;\r
+               int srcPitch;   //scanline byte size. allow negative for mirror\r
+               u32 dstPitch;\r
 \r
-               SBlitJob() : stretch(false) {}\r
+               bool stretch;\r
+               f32 x_stretch;\r
+               f32 y_stretch;\r
        };\r
 \r
        // Bitfields Cohen Sutherland\r
@@ -237,7 +257,7 @@ static void RenderLine32_Decal(video::IImage *t,
        }\r
 \r
        u32 *dst;\r
-       dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );\r
+       dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );\r
 \r
        if ( dy > dx )\r
        {\r
@@ -301,7 +321,7 @@ static void RenderLine32_Blend(video::IImage *t,
        }\r
 \r
        u32 *dst;\r
-       dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 2 ) );\r
+       dst = (u32*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 4 ) );\r
 \r
        if ( dy > dx )\r
        {\r
@@ -365,7 +385,7 @@ static void RenderLine16_Decal(video::IImage *t,
        }\r
 \r
        u16 *dst;\r
-       dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );\r
+       dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );\r
 \r
        if ( dy > dx )\r
        {\r
@@ -429,7 +449,7 @@ static void RenderLine16_Blend(video::IImage *t,
        }\r
 \r
        u16 *dst;\r
-       dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X << 1 ) );\r
+       dst = (u16*) ( (u8*) t->getData() + ( p0.Y * t->getPitch() ) + ( p0.X * 2 ) );\r
 \r
        if ( dy > dx )\r
        {\r
@@ -467,37 +487,57 @@ static void RenderLine16_Blend(video::IImage *t,
 */\r
 static void executeBlit_TextureCopy_x_to_x( const SBlitJob * job )\r
 {\r
-       const u32 w = job->width;\r
-       const u32 h = job->height;\r
        if (job->stretch)\r
        {\r
-               const u32 *src = static_cast<const u32*>(job->src);\r
-               u32 *dst = static_cast<u32*>(job->dst);\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const f18 wscale = f32_to_f18(job->x_stretch);\r
+               const f18 hscale = f32_to_f18(job->y_stretch);\r
 \r
-               for ( u32 dy = 0; dy < h; ++dy )\r
+               f18 src_y = f18_zero;\r
+\r
+               if (job->srcPixelMul == 4)\r
                {\r
-                       const u32 src_y = (u32)(dy*hscale);\r
-                       src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );\r
+                       const u32 *src = (u32*)(job->src);\r
+                       u32 *dst = (u32*)(job->dst);\r
 \r
-                       for ( u32 dx = 0; dx < w; ++dx )\r
+                       for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
                        {\r
-                               const u32 src_x = (u32)(dx*wscale);\r
-                               dst[dx] = src[src_x];\r
+                               src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+\r
+                               f18 src_x = f18_zero;\r
+                               for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
+                               {\r
+                                       dst[dx] = src[f18_floor(src_x)];\r
+                               }\r
+                               dst = (u32*)((u8*)(dst)+job->dstPitch);\r
+                       }\r
+               }\r
+               else if (job->srcPixelMul == 2)\r
+               {\r
+                       const u16 *src = (u16*)(job->src);\r
+                       u16* dst = (u16*)(job->dst);\r
+\r
+                       for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
+                       {\r
+                               src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+\r
+                               f18 src_x = f18_zero;\r
+                               for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
+                               {\r
+                                       dst[dx] = src[f18_floor(src_x)];\r
+                               }\r
+                               dst = (u16*)((u8*)(dst)+job->dstPitch);\r
                        }\r
-                       dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
                }\r
        }\r
        else\r
        {\r
-               const u32 widthPitch = job->width * job->dstPixelMul;\r
+               const size_t widthPitch = job->width * job->dstPixelMul;\r
                const void *src = (void*) job->src;\r
                void *dst = (void*) job->dst;\r
 \r
-               for ( u32 dy = 0; dy != h; ++dy )\r
+               for ( u32 dy = 0; dy < job->height; ++dy )\r
                {\r
-                       memcpy( dst, src, widthPitch );\r
+                       memcpy( dst, src, widthPitch);\r
 \r
                        src = (void*) ( (u8*) (src) + job->srcPitch );\r
                        dst = (void*) ( (u8*) (dst) + job->dstPitch );\r
@@ -516,8 +556,8 @@ static void executeBlit_TextureCopy_32_to_16( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -562,8 +602,8 @@ static void executeBlit_TextureCopy_24_to_16( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 3.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch * 3.f;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -607,8 +647,8 @@ static void executeBlit_TextureCopy_16_to_32( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -647,8 +687,8 @@ static void executeBlit_TextureCopy_16_to_24( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -697,8 +737,8 @@ static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 3.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch * 3.f;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -715,11 +755,11 @@ static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job )
        }\r
        else\r
        {\r
-               for ( s32 dy = 0; dy != job->height; ++dy )\r
+               for ( u32 dy = 0; dy < job->height; ++dy )\r
                {\r
                        const u8* s = src;\r
 \r
-                       for ( s32 dx = 0; dx != job->width; ++dx )\r
+                       for ( u32 dx = 0; dx < job->width; ++dx )\r
                        {\r
                                dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];\r
                                s += 3;\r
@@ -740,8 +780,8 @@ static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -781,54 +821,21 @@ static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job )
 */\r
 static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )\r
 {\r
-       const u32 w = job->width;\r
-       const u32 h = job->height;\r
-       const u32 rdx = w>>1;\r
+       const f18 wscale = f32_to_f18(job->x_stretch);\r
+       const f18 hscale = f32_to_f18(job->y_stretch);\r
 \r
-       const u32 *src = (u32*) job->src;\r
-       u32 *dst = (u32*) job->dst;\r
+       f18 src_y = f18_zero;\r
+       u16 *dst = (u16*)job->dst;\r
 \r
-       if (job->stretch)\r
+       for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
-               const u32 off = core::if_c_a_else_b(w&1, (u32)((w-1)*wscale), 0);\r
-               for ( u32 dy = 0; dy < h; ++dy )\r
+               const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+               f18 src_x = f18_zero;\r
+               for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
                {\r
-                       const u32 src_y = (u32)(dy*hscale);\r
-                       src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );\r
-\r
-                       for ( u32 dx = 0; dx < rdx; ++dx )\r
-                       {\r
-                               const u32 src_x = (u32)(dx*wscale);\r
-                               dst[dx] = PixelBlend16_simd( dst[dx], src[src_x] );\r
-                       }\r
-                       if ( off )\r
-                       {\r
-                               ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );\r
-                       }\r
-\r
-                       dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
-               }\r
-       }\r
-       else\r
-       {\r
-               const u32 off = core::if_c_a_else_b(w&1, w-1, 0);\r
-               for (u32 dy = 0; dy != h; ++dy )\r
-               {\r
-                       for (u32 dx = 0; dx != rdx; ++dx )\r
-                       {\r
-                               dst[dx] = PixelBlend16_simd( dst[dx], src[dx] );\r
-                       }\r
-\r
-                       if ( off )\r
-                       {\r
-                               ((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );\r
-                       }\r
-\r
-                       src = (u32*) ( (u8*) (src) + job->srcPitch );\r
-                       dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
+                       dst[dx] = PixelBlend16(dst[dx], src[f18_floor(src_x)]);\r
                }\r
+               dst = (u16*)((u8*)(dst)+job->dstPitch);\r
        }\r
 }\r
 \r
@@ -836,40 +843,21 @@ static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )
 */\r
 static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )\r
 {\r
-       const u32 w = job->width;\r
-       const u32 h = job->height;\r
-       const u32 *src = (u32*) job->src;\r
-       u32 *dst = (u32*) job->dst;\r
+       const f18 wscale = f32_to_f18(job->x_stretch);\r
+       const f18 hscale = f32_to_f18(job->y_stretch);\r
 \r
-       if (job->stretch)\r
+       f18 src_y = f18_zero;\r
+       u32 *dst = (u32*)job->dst;\r
+       for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
-               for ( u32 dy = 0; dy < h; ++dy )\r
-               {\r
-                       const u32 src_y = (u32)(dy*hscale);\r
-                       src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );\r
-\r
-                       for ( u32 dx = 0; dx < w; ++dx )\r
-                       {\r
-                               const u32 src_x = (u32)(dx*wscale);\r
-                               dst[dx] = PixelBlend32( dst[dx], src[src_x] );\r
-                       }\r
+               const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
 \r
-                       dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
-               }\r
-       }\r
-       else\r
-       {\r
-               for ( u32 dy = 0; dy != h; ++dy )\r
+               f18 src_x = f18_zero;\r
+               for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
                {\r
-                       for ( u32 dx = 0; dx != w; ++dx )\r
-                       {\r
-                               dst[dx] = PixelBlend32( dst[dx], src[dx] );\r
-                       }\r
-                       src = (u32*) ( (u8*) (src) + job->srcPitch );\r
-                       dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
+                       dst[dx] = PixelBlend32(dst[dx], src[f18_floor(src_x)]);\r
                }\r
+               dst = (u32*)((u8*)(dst)+job->dstPitch);\r
        }\r
 }\r
 \r
@@ -877,21 +865,26 @@ static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )
 */\r
 static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job )\r
 {\r
-       u16 *src = (u16*) job->src;\r
-       u16 *dst = (u16*) job->dst;\r
+       const u16 blend = video::A8R8G8B8toA1R5G5B5(job->argb);\r
+\r
+       const f18 wscale = f32_to_f18(job->x_stretch);\r
+       const f18 hscale = f32_to_f18(job->y_stretch);\r
 \r
-       u16 blend = video::A8R8G8B8toA1R5G5B5 ( job->argb );\r
-       for ( s32 dy = 0; dy != job->height; ++dy )\r
+       f18 src_y = f18_zero;\r
+       u16 *dst = (u16*)job->dst;\r
+       for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
        {\r
-               for ( s32 dx = 0; dx != job->width; ++dx )\r
+               const u16* src = (u16*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+               f18 src_x = f18_zero;\r
+               for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
                {\r
-                       if ( 0 == (src[dx] & 0x8000) )\r
+                       register u16 c0 = src[f18_floor(src_x)];\r
+                       if (0 == (c0 & 0x8000))\r
                                continue;\r
 \r
-                       dst[dx] = PixelMul16_2( src[dx], blend );\r
+                       dst[dx] = PixelMul16_2(c0, blend);\r
                }\r
-               src = (u16*) ( (u8*) (src) + job->srcPitch );\r
-               dst = (u16*) ( (u8*) (dst) + job->dstPitch );\r
+               dst = (u16*)((u8*)(dst)+job->dstPitch);\r
        }\r
 }\r
 \r
@@ -900,17 +893,21 @@ static void executeBlit_TextureBlendColor_16_to_16( const SBlitJob * job )
 */\r
 static void executeBlit_TextureBlendColor_32_to_32( const SBlitJob * job )\r
 {\r
-       u32 *src = (u32*) job->src;\r
-       u32 *dst = (u32*) job->dst;\r
+       const f18 wscale = f32_to_f18(job->x_stretch);\r
+       const f18 hscale = f32_to_f18(job->y_stretch);\r
 \r
-       for ( s32 dy = 0; dy != job->height; ++dy )\r
+       u32* dst = (u32*)job->dst;\r
+       f18 src_y = f18_zero;\r
+       for (u32 dy = 0; dy < job->height; ++dy, src_y += hscale)\r
        {\r
-               for ( s32 dx = 0; dx != job->width; ++dx )\r
+               const u32* src = (u32*)((u8*)(job->src) + job->srcPitch*f18_floor(src_y));\r
+\r
+               f18 src_x = f18_zero;\r
+               for (u32 dx = 0; dx < job->width; ++dx, src_x += wscale)\r
                {\r
-                       dst[dx] = PixelBlend32( dst[dx], PixelMul32_2( src[dx], job->argb ) );\r
+                       dst[dx] = PixelBlend32(dst[dx], PixelMul32_2(src[f18_floor(src_x)], job->argb));\r
                }\r
-               src = (u32*) ( (u8*) (src) + job->srcPitch );\r
-               dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
+               dst = (u32*)((u8*)(dst)+job->dstPitch);\r
        }\r
 }\r
 \r
@@ -921,7 +918,7 @@ static void executeBlit_Color_16_to_16( const SBlitJob * job )
        const u16 c = video::A8R8G8B8toA1R5G5B5(job->argb);\r
        u16 *dst = (u16*) job->dst;\r
 \r
-       for ( s32 dy = 0; dy != job->height; ++dy )\r
+       for ( u32 dy = 0; dy < job->height; ++dy )\r
        {\r
                memset16(dst, c, job->srcPitch);\r
                dst = (u16*) ( (u8*) (dst) + job->dstPitch );\r
@@ -934,7 +931,7 @@ static void executeBlit_Color_32_to_32( const SBlitJob * job )
 {\r
        u32 *dst = (u32*) job->dst;\r
 \r
-       for ( s32 dy = 0; dy != job->height; ++dy )\r
+       for ( u32 dy = 0; dy < job->height; ++dy )\r
        {\r
                memset32( dst, job->argb, job->srcPitch );\r
                dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
@@ -952,11 +949,11 @@ static void executeBlit_ColorAlpha_16_to_16( const SBlitJob * job )
                return;\r
        const u32 src = video::A8R8G8B8toA1R5G5B5( job->argb );\r
 \r
-       for ( s32 dy = 0; dy != job->height; ++dy )\r
+       for ( u32 dy = 0; dy != job->height; ++dy )\r
        {\r
-               for ( s32 dx = 0; dx != job->width; ++dx )\r
+               for ( u32 dx = 0; dx != job->width; ++dx )\r
                {\r
-                       dst[dx] = 0x8000 | PixelBlend16( dst[dx], src, alpha );\r
+                       dst[dx] = PixelBlend16( dst[dx], src, alpha );\r
                }\r
                dst = (u16*) ( (u8*) (dst) + job->dstPitch );\r
        }\r
@@ -966,19 +963,33 @@ static void executeBlit_ColorAlpha_16_to_16( const SBlitJob * job )
 */\r
 static void executeBlit_ColorAlpha_32_to_32( const SBlitJob * job )\r
 {\r
-       u32 *dst = (u32*) job->dst;\r
-\r
        const u32 alpha = extractAlpha( job->argb );\r
-       const u32 src = job->argb;\r
+       if (0 == alpha)\r
+               return;\r
 \r
-       for ( s32 dy = 0; dy != job->height; ++dy )\r
+       u32 *dst = (u32*)job->dst;\r
+       for ( u32 dy = 0; dy < job->height; ++dy )\r
        {\r
-               for ( s32 dx = 0; dx != job->width; ++dx )\r
+               for ( u32 dx = 0; dx < job->width; ++dx )\r
                {\r
-                       dst[dx] = (job->argb & 0xFF000000 ) | PixelBlend32( dst[dx], src, alpha );\r
+                       dst[dx] = PixelBlend32( dst[dx], job->argb, alpha );\r
                }\r
                dst = (u32*) ( (u8*) (dst) + job->dstPitch );\r
        }\r
+\r
+}\r
+\r
+/*!\r
+       Pixel =>\r
+                       color = sourceAlpha > 0 ? source, else dest\r
+                       alpha = max(destAlpha, sourceAlpha)\r
+*/\r
+inline u16 PixelCombine16(const u16 c2, const u16 c1)\r
+{\r
+       if (video::getAlpha(c1) > 0)\r
+               return c1;\r
+       else\r
+               return c2;\r
 }\r
 \r
 /*!\r
@@ -1023,8 +1034,8 @@ static void executeBlit_TextureCombineColor_16_to_24( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -1068,6 +1079,58 @@ static void executeBlit_TextureCombineColor_16_to_24( const SBlitJob * job )
        }\r
 }\r
 \r
+/*!\r
+       Pixel =>\r
+                       color = dest * ( 1 - SourceAlpha ) + source * SourceAlpha,\r
+                       alpha = destAlpha * ( 1 - SourceAlpha ) + sourceAlpha\r
+\r
+       where "1" means "full scale" (255)\r
+*/\r
+inline u32 PixelCombine32(const u32 c2, const u32 c1)\r
+{\r
+       // alpha test\r
+       u32 alpha = c1 & 0xFF000000;\r
+\r
+       if (0 == alpha)\r
+               return c2;\r
+       if (0xFF000000 == alpha)\r
+       {\r
+               return c1;\r
+       }\r
+\r
+       alpha >>= 24;\r
+\r
+       // add highbit alpha, if ( alpha > 127 ) alpha += 1;\r
+       // stretches [0;255] to [0;256] to avoid division by 255. use division 256 == shr 8\r
+       alpha += (alpha >> 7);\r
+\r
+       u32 srcRB = c1 & 0x00FF00FF;\r
+       u32 srcXG = c1 & 0x0000FF00;\r
+\r
+       u32 dstRB = c2 & 0x00FF00FF;\r
+       u32 dstXG = c2 & 0x0000FF00;\r
+\r
+\r
+       u32 rb = srcRB - dstRB;\r
+       u32 xg = srcXG - dstXG;\r
+\r
+       rb *= alpha;\r
+       xg *= alpha;\r
+       rb >>= 8;\r
+       xg >>= 8;\r
+\r
+       rb += dstRB;\r
+       xg += dstXG;\r
+\r
+       rb &= 0x00FF00FF;\r
+       xg &= 0x0000FF00;\r
+\r
+       u32 sa = c1 >> 24;\r
+       u32 da = c2 >> 24;\r
+       u32 blendAlpha_fix8 = (sa * 256 + da * (256 - alpha)) >> 8;\r
+       return blendAlpha_fix8 << 24 | rb | xg;\r
+}\r
+\r
 /*!\r
        Combine alpha channels (increases alpha / reduces transparency)\r
        Destination alpha is treated as full 255\r
@@ -1081,8 +1144,8 @@ static void executeBlit_TextureCombineColor_32_to_24( const SBlitJob * job )
 \r
        if (job->stretch)\r
        {\r
-               const float wscale = 1.f/job->x_stretch;\r
-               const float hscale = 1.f/job->y_stretch;\r
+               const float wscale = job->x_stretch;\r
+               const float hscale = job->y_stretch;\r
 \r
                for ( u32 dy = 0; dy < h; ++dy )\r
                {\r
@@ -1130,9 +1193,9 @@ static void executeBlit_TextureCombineColor_32_to_32( const SBlitJob * job )
        u32 *src = (u32*) job->src;\r
        u32 *dst = (u32*) job->dst;\r
 \r
-       for ( s32 dy = 0; dy != job->height; ++dy )\r
+       for ( u32 dy = 0; dy != job->height; ++dy )\r
        {\r
-               for ( s32 dx = 0; dx != job->width; ++dx )\r
+               for (u32 dx = 0; dx != job->width; ++dx )\r
                {\r
                        dst[dx] = PixelCombine32( dst[dx], PixelMul32_2( src[dx], job->argb ) );\r
                }\r
@@ -1220,26 +1283,46 @@ static inline tExecuteBlit getBlitter2( eBlitter operation,const video::IImage *
 \r
 \r
 // bounce clipping to texture\r
-inline void setClip ( AbsRectangle &out, const core::rect<s32> *clip,\r
-                                       const video::IImage * tex, s32 passnative )\r
+inline void setClip(AbsRectangle &out, const core::rect<s32> *clip,\r
+       const video::IImage* tex, s32 passnative, const core::dimension2d<u32>* tex_org)\r
 {\r
-       if ( clip && 0 == tex && passnative )\r
+       if (0 == tex)\r
        {\r
-               out.x0 = clip->UpperLeftCorner.X;\r
-               out.x1 = clip->LowerRightCorner.X;\r
-               out.y0 = clip->UpperLeftCorner.Y;\r
-               out.y1 = clip->LowerRightCorner.Y;\r
+               if (clip && passnative)\r
+               {\r
+                       out.x0 = clip->UpperLeftCorner.X;\r
+                       out.x1 = clip->LowerRightCorner.X;\r
+                       out.y0 = clip->UpperLeftCorner.Y;\r
+                       out.y1 = clip->LowerRightCorner.Y;\r
+               }\r
+               else\r
+               {\r
+                       out.x0 = 0;\r
+                       out.x1 = 0;\r
+                       out.y0 = 0;\r
+                       out.y1 = 0;\r
+               }\r
                return;\r
        }\r
 \r
-       const s32 w = tex ? tex->getDimension().Width : 0;\r
-       const s32 h = tex ? tex->getDimension().Height : 0;\r
-       if ( clip )\r
+       const s32 w = tex->getDimension().Width;\r
+       const s32 h = tex->getDimension().Height;\r
+\r
+       //driver could have changed texture size.\r
+       if (clip && tex_org && ((u32)w != tex_org->Width || (u32)h != tex_org->Height))\r
        {\r
-               out.x0 = core::s32_clamp ( clip->UpperLeftCorner.X, 0, w );\r
-               out.x1 = core::s32_clamp ( clip->LowerRightCorner.X, out.x0, w );\r
-               out.y0 = core::s32_clamp ( clip->UpperLeftCorner.Y, 0, h );\r
-               out.y1 = core::s32_clamp ( clip->LowerRightCorner.Y, out.y0, h );\r
+               out.x0 = core::s32_clamp((clip->UpperLeftCorner.X*w) / tex_org->Width, 0, w - 1);\r
+               out.x1 = core::s32_clamp((clip->LowerRightCorner.X*w) / tex_org->Width, out.x0, w);\r
+               out.y0 = core::s32_clamp((clip->UpperLeftCorner.Y*h) / tex_org->Height, 0, h - 1);\r
+               out.y1 = core::s32_clamp((clip->LowerRightCorner.Y*h) / tex_org->Height, out.y0, h);\r
+       }\r
+       else if (clip)\r
+       {\r
+               //y-1 to prevent starting on illegal memory (not ideal!).\r
+               out.x0 = core::s32_clamp(clip->UpperLeftCorner.X, 0, w - 1);\r
+               out.x1 = core::s32_clamp(clip->LowerRightCorner.X, passnative ? 0 : out.x0, w);\r
+               out.y0 = core::s32_clamp(clip->UpperLeftCorner.Y, 0, h - 1);\r
+               out.y1 = core::s32_clamp(clip->LowerRightCorner.Y, passnative ? 0 : out.y0, h);\r
        }\r
        else\r
        {\r
@@ -1275,8 +1358,8 @@ static s32 Blit(eBlitter operation,
 \r
        SBlitJob job;\r
 \r
-       setClip ( sourceClip, sourceClipping, source, 1 );\r
-       setClip ( destClip, destClipping, dest, 0 );\r
+       setClip ( sourceClip, sourceClipping, source, 1,0 );\r
+       setClip ( destClip, destClipping, dest, 0,0 );\r
 \r
        v.x0 = destPos ? destPos->X : 0;\r
        v.y0 = destPos ? destPos->Y : 0;\r
@@ -1296,6 +1379,10 @@ static s32 Blit(eBlitter operation,
 \r
        job.argb = argb;\r
 \r
+       job.stretch = false;\r
+       job.x_stretch = 1.f;\r
+       job.y_stretch = 1.f;\r
+\r
        if ( source )\r
        {\r
                job.srcPitch = source->getPitch();\r
@@ -1317,9 +1404,10 @@ static s32 Blit(eBlitter operation,
        return 1;\r
 }\r
 \r
+#if defined(SOFTWARE_DRIVER_2_2D_AS_2D)\r
 static s32 StretchBlit(eBlitter operation,\r
-               video::IImage* dest, const core::rect<s32> *destRect,\r
-               const core::rect<s32> *srcRect, video::IImage* const source,\r
+               video::IImage* dest, const core::rect<s32>* destClipping,const core::rect<s32> *destRect,\r
+               video::IImage* const source,const core::rect<s32> *srcRect, const core::dimension2d<u32>* source_org,\r
                u32 argb)\r
 {\r
        tExecuteBlit blitter = getBlitter2( operation, dest, source );\r
@@ -1330,9 +1418,15 @@ static s32 StretchBlit(eBlitter operation,
 \r
        SBlitJob job;\r
 \r
+       AbsRectangle destClip;\r
+       AbsRectangle v;\r
+       setClip(destClip, destClipping, dest, 0, 0);\r
+       setClip(v, destRect, 0, 1, 0);\r
+       if (!intersect(job.Dest, destClip, v))\r
+               return 0;\r
+\r
        // Clipping\r
-       setClip ( job.Source, srcRect, source, 1 );\r
-       setClip ( job.Dest, destRect, dest, 0 );\r
+       setClip ( job.Source, srcRect, source, 1, source_org);\r
 \r
        job.width = job.Dest.x1-job.Dest.x0;\r
        job.height = job.Dest.y1-job.Dest.y0;\r
@@ -1340,14 +1434,25 @@ static s32 StretchBlit(eBlitter operation,
        job.argb = argb;\r
 \r
        // use original dest size, despite any clipping\r
-       job.x_stretch = (float)destRect->getWidth() / (float)(job.Source.x1-job.Source.x0);\r
-       job.y_stretch = (float)destRect->getHeight() / (float)(job.Source.y1-job.Source.y0);\r
-       job.stretch = (job.x_stretch != 1.f) || (job.y_stretch != 1.f);\r
+       const int dst_w = v.x1 - v.x0; // destRect->getWidth();\r
+       const int dst_h = v.y1 - v.y0; // destRect->getHeight();\r
+       const int src_w = job.Source.x1 - job.Source.x0;\r
+       const int src_h = job.Source.y1 - job.Source.y0;\r
+\r
+       job.stretch = dst_w != src_w || dst_h != src_h;\r
+       job.x_stretch = dst_w ? (float)src_w / (float)dst_w : 1.f;\r
+       job.y_stretch = dst_h ? (float)src_h / (float)dst_h : 1.f;\r
+\r
 \r
        if ( source )\r
        {\r
                job.srcPitch = source->getPitch();\r
                job.srcPixelMul = source->getBytesPerPixel();\r
+\r
+               //dest-clippling. advance source. loosing subpixel precision\r
+               job.Source.x0 += (s32)floorf(job.x_stretch * (job.Dest.x0 - v.x0));\r
+               job.Source.y0 += (s32)floorf(job.y_stretch * (job.Dest.y0 - v.y0));\r
+\r
                job.src = (void*) ( (u8*) source->getData() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) );\r
        }\r
        else\r
@@ -1364,7 +1469,7 @@ static s32 StretchBlit(eBlitter operation,
 \r
        return 1;\r
 }\r
-\r
+#endif\r
 \r
 // Methods for Software drivers\r
 //! draws a rectangle\r
index c04db94b348fef48531f23510f7e7e6ebba4ed67..3d9dacc6a09443cec591b1dd4415f2d2c6a9b2c0 100644 (file)
@@ -5,7 +5,7 @@
 #include "IrrCompileConfig.h"\r
 #include "IBurningShader.h"\r
 \r
-#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+#if defined(_IRR_COMPILE_WITH_BURNINGSVIDEO_) && 0\r
 \r
 \r
 namespace irr\r
@@ -558,7 +558,7 @@ void CBurningShader_Raster_Reference::pShader_EMT_LIGHTMAP_M4 ()
        getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );\r
 \r
 \r
-       pShader.dst[pShader.i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+       pShader.dst[pShader.i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
                                                        clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
                                                        clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
                                                );\r
@@ -578,7 +578,7 @@ void CBurningShader_Raster_Reference::pShader_1 ()
        ty0 = tofix ( line.t[0][0].y, inversew );\r
 \r
        getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
-       pShader.dst[pShader.i] = fix_to_color ( r0, g0, b0 );\r
+       pShader.dst[pShader.i] = fix_to_sample( r0, g0, b0 );\r
 \r
 }\r
 \r
@@ -690,15 +690,15 @@ REALINLINE void CBurningShader_Raster_Reference::depthWrite ()
 REALINLINE void CBurningShader_Raster_Reference::scanline2()\r
 {\r
        // apply top-left fill-convention, left\r
-       pShader.xStart = core::ceil32_fast( line.x[0] );\r
-       pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       pShader.xStart = fill_convention_left( line.x[0] );\r
+       pShader.xEnd = fill_convention_right( line.x[1] );\r
 \r
        pShader.dx = pShader.xEnd - pShader.xStart;\r
        if ( pShader.dx < 0 )\r
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
        const f32 subPixel = ( (f32) pShader.xStart ) - line.x[0];\r
 \r
        // store slopes in endpoint, and correct first pixel\r
@@ -707,7 +707,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
 \r
        u32 i;\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
        for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
        {\r
                line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;\r
@@ -721,6 +721,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
                line.t[i][0] += line.t[i][1] * subPixel;\r
        }\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK_REF;\r
        pShader.dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( line.y * RenderTarget->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );\r
        pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );\r
 \r
@@ -734,7 +735,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline2()
                // advance next pixel\r
                line.w[0] += line.w[1];\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                {\r
                        line.c[i][0] += line.c[i][1];\r
@@ -755,15 +756,15 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
        u32 i;\r
 \r
        // apply top-left fill-convention, left\r
-       pShader.xStart = core::ceil32_fast( line.x[0] );\r
-       pShader.xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       pShader.xStart = fill_convention_left( line.x[0] );\r
+       pShader.xEnd = fill_convention_right( line.x[1] );\r
 \r
        pShader.dx = pShader.xEnd - pShader.xStart;\r
        if ( pShader.dx < 0 )\r
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
        // search z-buffer for first not occulled pixel\r
        pShader.z = (fp24*) ( (u8*) DepthBuffer->lock() + ( line.y * DepthBuffer->getPitch() ) + ( pShader.xStart << VIDEO_SAMPLE_GRANULARITY ) );\r
@@ -787,6 +788,9 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
                        case BD3DCMP_EQUAL:\r
                                condition = a != pShader.z[pShader.i];\r
                                break;\r
+                       default:\r
+                               condition = 0;\r
+                               break;\r
                }\r
                while ( a < pShader.z[pShader.i] )\r
                {\r
@@ -807,7 +811,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
 \r
        a = (f32) pShader.i + subPixel;\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
        for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
        {\r
                line.c[i][1] = (line.c[i][1] - line.c[i][0]) * invDeltaX;\r
@@ -832,7 +836,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
 \r
                line.w[0] += line.w[1];\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                {\r
                        line.c[i][0] += line.c[i][1];\r
@@ -847,7 +851,7 @@ REALINLINE void CBurningShader_Raster_Reference::scanline ()
 }\r
 \r
 \r
-void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CBurningShader_Raster_Reference::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        sScanConvertData scan;\r
        u32 i;\r
@@ -859,9 +863,9 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
 \r
 \r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal ( c->Pos.y - a->Pos.y );\r
-       scan.invDeltaY[1] = core::reciprocal ( b->Pos.y - a->Pos.y );\r
-       scan.invDeltaY[2] = core::reciprocal ( c->Pos.y - b->Pos.y );\r
+       scan.invDeltaY[0] = reciprocal_zero2( c->Pos.y - a->Pos.y );\r
+       scan.invDeltaY[1] = reciprocal_zero2( b->Pos.y - a->Pos.y );\r
+       scan.invDeltaY[2] = reciprocal_zero2( c->Pos.y - b->Pos.y );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
                return;\r
@@ -885,7 +889,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
        scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
        scan.w[0] = a->Pos.w;\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
        for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
        {\r
                scan.c[i][0] = a->Color[i];\r
@@ -915,7 +919,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
                scan.w[1] = a->Pos.w;\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                {\r
                        scan.c[i][1] = a->Color[i];\r
@@ -929,8 +933,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                }\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
 \r
@@ -941,12 +945,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                scan.w[0] += scan.slopeW[0] * subPixel;\r
                scan.w[1] += scan.slopeW[1] * subPixel;\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                {\r
                        scan.c[i][0] += scan.slopeC[i][0] * subPixel;\r
                        scan.c[i][1] += scan.slopeC[i][1] * subPixel;\r
                }\r
-\r
+#endif\r
                for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
                {\r
                        scan.t[i][0] += scan.slopeT[i][0] * subPixel;\r
@@ -962,7 +967,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                        line.x[scan.right] = scan.x[1];\r
                        line.w[scan.right] = scan.w[1];\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                        for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                        {\r
                                line.c[i][scan.left] = scan.c[i][0];\r
@@ -984,12 +989,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                        scan.w[0] += scan.slopeW[0];\r
                        scan.w[1] += scan.slopeW[1];\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                        for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                        {\r
                                scan.c[i][0] += scan.slopeC[i][0];\r
                                scan.c[i][1] += scan.slopeC[i][1];\r
                        }\r
-\r
+#endif\r
                        for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
                        {\r
                                scan.t[i][0] += scan.slopeT[i][0];\r
@@ -1010,7 +1016,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                        scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
                        scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                        for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                        {\r
                                scan.c[i][0] = a->Color[i] + scan.slopeC[i][0] * temp[0];\r
@@ -1029,7 +1035,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
                scan.w[1] = b->Pos.w;\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                {\r
                        scan.c[i][1] = b->Color[i];\r
@@ -1043,8 +1049,8 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                }\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 \r
                subPixel = ( (f32) yStart ) - b->Pos.y;\r
@@ -1056,12 +1062,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                scan.w[0] += scan.slopeW[0] * subPixel;\r
                scan.w[1] += scan.slopeW[1] * subPixel;\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                {\r
                        scan.c[i][0] += scan.slopeC[i][0] * subPixel;\r
                        scan.c[i][1] += scan.slopeC[i][1] * subPixel;\r
                }\r
-\r
+#endif\r
                for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
                {\r
                        scan.t[i][0] += scan.slopeT[i][0] * subPixel;\r
@@ -1077,7 +1084,7 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                        line.x[scan.right] = scan.x[1];\r
                        line.w[scan.right] = scan.w[1];\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                        for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                        {\r
                                line.c[i][scan.left] = scan.c[i][0];\r
@@ -1099,12 +1106,13 @@ void CBurningShader_Raster_Reference::drawTriangle ( const s4DVertex *a,const s4
                        scan.w[0] += scan.slopeW[0];\r
                        scan.w[1] += scan.slopeW[1];\r
 \r
-                       for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+                       for ( i = 0; i != ShaderParam.ColorUnits; ++i )\r
                        {\r
                                scan.c[i][0] += scan.slopeC[i][0];\r
                                scan.c[i][1] += scan.slopeC[i][1];\r
                        }\r
-\r
+#endif\r
                        for ( i = 0; i != ShaderParam.TextureUnits; ++i )\r
                        {\r
                                scan.t[i][0] += scan.slopeT[i][0];\r
index e9126bda3d2480523bda9e2a5db6b05e15aec770..eed72345501136db983257a04775d63336598a70 100644 (file)
@@ -30,30 +30,32 @@ CDepthBuffer::CDepthBuffer(const core::dimension2d<u32>& size)
 //! destructor\r
 CDepthBuffer::~CDepthBuffer()\r
 {\r
-       delete [] Buffer;\r
+       if (Buffer)\r
+       {\r
+               delete[] Buffer;\r
+               Buffer = 0;\r
+       }\r
 }\r
 \r
 \r
 \r
 //! clears the zbuffer\r
-void CDepthBuffer::clear()\r
+void CDepthBuffer::clear(f32 value)\r
 {\r
+       ieee754 zMaxValue;\r
 \r
 #ifdef SOFTWARE_DRIVER_2_USE_WBUFFER\r
-       f32 zMax = 0.f;\r
+       zMaxValue.f = 1.f-value;\r
 #else\r
-       f32 zMax = 1.f;\r
+       zMaxValue.f = value;\r
 #endif\r
 \r
-       u32 zMaxValue;\r
-       zMaxValue = IR(zMax);\r
-\r
-       memset32 ( Buffer, zMaxValue, TotalSize );\r
+       memset32 ( Buffer, zMaxValue.u, TotalSize );\r
 }\r
 \r
 \r
 \r
-//! sets the new size of the zbuffer\r
+//! sets the new size of the buffer\r
 void CDepthBuffer::setSize(const core::dimension2d<u32>& size)\r
 {\r
        if (size == Size)\r
@@ -65,13 +67,13 @@ void CDepthBuffer::setSize(const core::dimension2d<u32>& size)
 \r
        Pitch = size.Width * sizeof ( fp24 );\r
        TotalSize = Pitch * size.Height;\r
-       Buffer = new u8[TotalSize];\r
+       Buffer = new u8[align_next(TotalSize,16)];\r
        clear ();\r
 }\r
 \r
 \r
 \r
-//! returns the size of the zbuffer\r
+//! returns the size of the buffer\r
 const core::dimension2d<u32>& CDepthBuffer::getSize() const\r
 {\r
        return Size;\r
@@ -80,11 +82,11 @@ const core::dimension2d<u32>& CDepthBuffer::getSize() const
 // -----------------------------------------------------------------\r
 \r
 //! constructor\r
-CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size)\r
-: Buffer(0), Size(0,0)\r
+CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit)\r
+: Buffer(0), Size(0,0),Bit(bit)\r
 {\r
        #ifdef _DEBUG\r
-       setDebugName("CDepthBuffer");\r
+       setDebugName("CStencilBuffer");\r
        #endif\r
 \r
        setSize(size);\r
@@ -95,20 +97,30 @@ CStencilBuffer::CStencilBuffer(const core::dimension2d<u32>& size)
 //! destructor\r
 CStencilBuffer::~CStencilBuffer()\r
 {\r
-       delete [] Buffer;\r
+       if (Buffer)\r
+       {\r
+               delete[] Buffer;\r
+               Buffer = 0;\r
+       }\r
 }\r
 \r
 \r
 \r
-//! clears the zbuffer\r
-void CStencilBuffer::clear()\r
+//! clears the buffer\r
+void CStencilBuffer::clear(u8 value)\r
 {\r
-       memset32 ( Buffer, 0, TotalSize );\r
+       u32 set = value;\r
+       if (Bit == 8)\r
+       {\r
+               set |= set << 8;\r
+               set |= set << 16;\r
+       }\r
+       memset32 ( Buffer, set, TotalSize );\r
 }\r
 \r
 \r
 \r
-//! sets the new size of the zbuffer\r
+//! sets the new size of the buffer\r
 void CStencilBuffer::setSize(const core::dimension2d<u32>& size)\r
 {\r
        if (size == Size)\r
@@ -118,15 +130,15 @@ void CStencilBuffer::setSize(const core::dimension2d<u32>& size)
 \r
        delete [] Buffer;\r
 \r
-       Pitch = size.Width * sizeof ( u32 );\r
+       Pitch = size.Width * sizeof (tStencilSample);\r
        TotalSize = Pitch * size.Height;\r
-       Buffer = new u8[TotalSize];\r
+       Buffer = new u8[align_next(TotalSize,16)];\r
        clear ();\r
 }\r
 \r
 \r
 \r
-//! returns the size of the zbuffer\r
+//! returns the size of the buffer\r
 const core::dimension2d<u32>& CStencilBuffer::getSize() const\r
 {\r
        return Size;\r
@@ -155,11 +167,11 @@ IDepthBuffer* createDepthBuffer(const core::dimension2d<u32>& size)
 }\r
 \r
 \r
-//! creates a ZBuffer\r
-IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size)\r
+//! creates a Stencil Buffer\r
+IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit)\r
 {\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
-       return new CStencilBuffer(size);\r
+       return new CStencilBuffer(size,bit);\r
        #else\r
        return 0;\r
        #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
index 7964efa659d859f96f487ae6f989dca1099bdae9..aa9c33ded4cb16a877f202fb3d4bba3e10dfee55 100644 (file)
@@ -23,7 +23,7 @@ namespace video
                virtual ~CDepthBuffer();\r
 \r
                //! clears the zbuffer\r
-               virtual void clear() _IRR_OVERRIDE_;\r
+               virtual void clear(f32 value=1.f) _IRR_OVERRIDE_;\r
 \r
                //! sets the new size of the zbuffer\r
                virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;\r
@@ -55,13 +55,13 @@ namespace video
        public:\r
 \r
                //! constructor\r
-               CStencilBuffer(const core::dimension2d<u32>& size);\r
+               CStencilBuffer(const core::dimension2d<u32>& size, unsigned bit);\r
 \r
                //! destructor\r
                virtual ~CStencilBuffer();\r
 \r
                //! clears the zbuffer\r
-               virtual void clear() _IRR_OVERRIDE_;\r
+               virtual void clear(u8 value=0) _IRR_OVERRIDE_;\r
 \r
                //! sets the new size of the zbuffer\r
                virtual void setSize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;\r
@@ -80,11 +80,11 @@ namespace video
 \r
 \r
        private:\r
-\r
                u8* Buffer;\r
                core::dimension2d<u32> Size;\r
                u32 TotalSize;\r
                u32 Pitch;\r
+               u32 Bit;\r
        };\r
 \r
 } // end namespace video\r
index c28d30abb62fe1d1afda70499f1b1d8b139caf58..3a6484be5a80417f22b574e08cc95b505164a78a 100644 (file)
@@ -88,6 +88,7 @@ u32 CGUIContextMenu::insertItem(u32 idx, const wchar_t* text, s32 commandId, boo
        s.IsSeparator = (text == 0);\r
        s.SubMenu = 0;\r
        s.CommandId = commandId;\r
+       s.PosY = 0;\r
 \r
        if (hasSubMenu)\r
        {\r
index c59b0602e19adfb6157e29f4f266a5e0e3eb90a7..ffd23fcb53c9933e7dd13fcd037a8d3a8077238c 100644 (file)
@@ -7,6 +7,7 @@
 #include "CColorConverter.h"\r
 #include "CBlit.h"\r
 #include "os.h"\r
+#include "SoftwareDriver2_helper.h"\r
 \r
 namespace irr\r
 {\r
@@ -25,7 +26,7 @@ CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* d
        {\r
                const u32 dataSize = getDataSizeFromFormat(Format, Size.Width, Size.Height);\r
 \r
-               Data = new u8[dataSize];\r
+               Data = new u8[align_next(dataSize,16)];\r
                memcpy(Data, data, dataSize);\r
                DeleteMemory = true;\r
        }\r
@@ -35,7 +36,7 @@ CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size, void* d
 //! Constructor of empty image\r
 CImage::CImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) : IImage(format, size, true)\r
 {\r
-       Data = new u8[getDataSizeFromFormat(Format, Size.Width, Size.Height)];\r
+       Data = new u8[align_next(getDataSizeFromFormat(Format, Size.Width, Size.Height),16)];\r
        DeleteMemory = true;\r
 }\r
 \r
@@ -133,9 +134,9 @@ void CImage::copyTo(IImage* target, const core::position2d<s32>& pos)
                return;\r
        }\r
 \r
-       if ( !Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)\r
+       if (!Blit(BLITTER_TEXTURE, target, 0, &pos, this, 0, 0)\r
                && target && pos.X == 0 && pos.Y == 0 &&\r
-               CColorConverter::canConvertFormat(Format, target->getColorFormat()) )\r
+               CColorConverter::canConvertFormat(Format, target->getColorFormat()))\r
        {\r
                // No fast blitting, but copyToScaling uses other color conversions and might work\r
                irr::core::dimension2du dim(target->getDimension());\r
@@ -166,16 +167,9 @@ void CImage::copyToWithAlpha(IImage* target, const core::position2d<s32>& pos, c
                return;\r
        }\r
 \r
-       if ( combineAlpha )\r
-       {\r
-               Blit(BLITTER_TEXTURE_COMBINE_ALPHA, target, clipRect, &pos, this, &sourceRect, color.color);\r
-       }\r
-       else\r
-       {\r
-               // color blend only necessary on not full spectrum aka. color.color != 0xFFFFFFFF\r
-               Blit(color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND: BLITTER_TEXTURE_ALPHA_COLOR_BLEND,\r
-                               target, clipRect, &pos, this, &sourceRect, color.color);\r
-       }\r
+       eBlitter op = combineAlpha ? BLITTER_TEXTURE_COMBINE_ALPHA :\r
+               color.color == 0xFFFFFFFF ? BLITTER_TEXTURE_ALPHA_BLEND : BLITTER_TEXTURE_ALPHA_COLOR_BLEND;\r
+       Blit(op,target, clipRect, &pos, this, &sourceRect, color.color);\r
 }\r
 \r
 \r
@@ -386,5 +380,6 @@ inline SColor CImage::getPixelBox( s32 x, s32 y, s32 fx, s32 fy, s32 bias ) cons
 }\r
 \r
 \r
+\r
 } // end namespace video\r
 } // end namespace irr\r
index 1f0b141e1591db9dafd265191c594a4eded50557..dfb4b8b0bcec64f660e7b64416dd626a8c333c72 100644 (file)
@@ -555,7 +555,7 @@ void CImageLoaderRGB::readRGBrow(u8 *buf, int y, int z, io::IReadFile* file, rgb
                // limit the count value to the remaining row size\r
                if (oPtr + count*rgb.Header.BPC > buf + rgb.Header.Xsize * rgb.Header.BPC)\r
                {\r
-                       count = ( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC;\r
+                       count = (s32)( (buf + rgb.Header.Xsize * rgb.Header.BPC) - oPtr ) / rgb.Header.BPC;\r
                }\r
 \r
                if (count<=0)\r
index 0c29802e18a6c822f15eae1145ca2ee26cc26c53..c0369d49e43273345d3e1c5677cfa0ead69d0399 100644 (file)
@@ -92,7 +92,9 @@ private:
        {\r
                SMyMaterialEntry ()\r
                : Texture1FileName("null"), Texture2FileName("null"),\r
-               Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {}\r
+               Texture1(0), Texture2(0), MaterialType(video::EMT_SOLID) {\r
+                       Header.Name[0] = 0;\r
+               }\r
 \r
                SMyMaterialHeader Header;\r
                core::stringc Texture1FileName;\r
index d4ce82ed3d648d76572670167ea1d6cef4f26cd3..17dcec99d98e3cc2d21bffe077130bc607ca2c3e 100644 (file)
@@ -182,6 +182,8 @@ IAnimatedMesh* COBJMeshFileLoader::createMesh(io::IReadFile* file)
                                        smoothingGroup=0;\r
                                else\r
                                        smoothingGroup=core::strtoul10(smooth);\r
+\r
+                               (void)smoothingGroup; // disable unused variable warnings\r
                        }\r
                        break;\r
 \r
index 1bdbdc161fa0efc6043d6b401b249768ac7a4674..6cef827f9b18d89dd4a1971f406c5923238e3304 100644 (file)
@@ -187,7 +187,8 @@ bool COSOperator::getProcessorSpeedMHz(u32* MHz) const
        if (file)\r
        {\r
                char buffer[1024];\r
-               fread(buffer, 1, 1024, file);\r
+               size_t r = fread(buffer, 1, 1023, file);\r
+               buffer[r] = 0;\r
                buffer[1023]=0;\r
                core::stringc str(buffer);\r
                s32 pos = str.find("cpu MHz");\r
index 7a88bc2a36632f543d1dca09dd5c1dff642c18cf..9715dc9d9117e5afe2516089861b754b9f6cdfaf 100644 (file)
@@ -26,6 +26,13 @@ public:
        {\r
        }\r
 \r
+       virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
+               bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_\r
+       {\r
+               if (Driver)\r
+                       Driver->setFallback_Material(material.MaterialType);\r
+       }\r
+\r
 protected:\r
 \r
        video::CBurningVideoDriver* Driver;\r
@@ -47,7 +54,6 @@ public:
 };\r
 \r
 \r
-\r
 //! Transparent material renderer\r
 class CSoftware2MaterialRenderer_TRANSPARENT_ADD_COLOR : public CSoftware2MaterialRenderer\r
 {\r
@@ -75,40 +81,6 @@ public:
 \r
 };\r
 \r
-//! unsupported material renderer\r
-class CBurningShader_REFERENCE : public CSoftware2MaterialRenderer\r
-{\r
-public:\r
-       CBurningShader_REFERENCE ( video::CBurningVideoDriver* driver )\r
-               : CSoftware2MaterialRenderer ( driver ) {}\r
-\r
-       virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
-               bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_\r
-       {\r
-       }\r
-\r
-       virtual void OnUnsetMaterial() _IRR_OVERRIDE_\r
-       {\r
-       }\r
-\r
-       virtual bool isTransparent() const _IRR_OVERRIDE_\r
-       {\r
-               return false;\r
-       }\r
-\r
-       virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_\r
-       {\r
-               return true;\r
-       };\r
-\r
-\r
-       virtual s32 getRenderCapability() const _IRR_OVERRIDE_\r
-       {\r
-               return 1;\r
-       }\r
-\r
-};\r
-\r
 \r
 \r
 } // end namespace video\r
index 8b514c9dffdaf75d2103f459a1929ba34226f538..89f0f7b531d369afad897c056bfa63fc7ffacc9a 100644 (file)
@@ -8,6 +8,7 @@
 #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 "CBlit.h"\r
 \r
 \r
-#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( tex ) )\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
+\r
+#if defined(Tweak_Burning)\r
+\r
+// run time parameter\r
+struct tweakBurning\r
+{\r
+       tweakBurning()\r
+       {\r
+               current = 11;\r
+               step = 0.0001f;\r
+\r
+               ndc_shrink_x = -0.75f;\r
+               ndc_scale_x = 0.5f;\r
+               ndc_trans_x = -0.5f;\r
+\r
+               ndc_shrink_y = -0.75f;\r
+               ndc_scale_y = -0.5f;\r
+               ndc_trans_y = -0.5f;\r
+\r
+               tex_w_add = 0.f;\r
+               tex_h_add = 0.f;\r
+               tex_cx_add = 0.f;\r
+               tex_cy_add = 0.f;\r
+\r
+               AreaMinDrawSize = 0.001f;\r
+       }\r
+       int current;\r
+\r
+       union\r
+       {\r
+               struct {\r
+                       f32 step;\r
+\r
+                       f32 ndc_shrink_x;\r
+                       f32 ndc_scale_x;\r
+                       f32 ndc_trans_x;\r
+\r
+                       f32 ndc_shrink_y;\r
+                       f32 ndc_scale_y;\r
+                       f32 ndc_trans_y;\r
+\r
+                       f32 tex_w_add;\r
+                       f32 tex_cx_add;\r
+                       f32 tex_h_add;\r
+                       f32 tex_cy_add;\r
+\r
+                       f32 AreaMinDrawSize; //! minimal visible covered area for primitive\r
+               };\r
+               f32 val[16];\r
+       };\r
+       static const char* const name[16];\r
+       void postEventFromUser(const SEvent& e);\r
+};\r
+\r
+const char* const tweakBurning::name[] = { "step",\r
+       "ndc_shrink_x","ndc_scale_x","ndc_trans_x",\r
+       "ndc_shrink_y","ndc_scale_y","ndc_trans_y",\r
+       "tex_w_add","tex_cx_add","tex_h_add","tex_cy_add",\r
+       "dc_area",0 };\r
+\r
+void tweakBurning::postEventFromUser(const SEvent& e)\r
+{\r
+       int show = 0;\r
+       if (e.EventType == EET_KEY_INPUT_EVENT)\r
+       {\r
+               switch (e.KeyInput.Key)\r
+               {\r
+               case KEY_KEY_1: step *= 0.9f; if (step < 0.00001f) step = 0.0001f; show = 2; break;\r
+               case KEY_KEY_2: step *= 1.1f; show = 2; break;\r
+\r
+               case KEY_KEY_3: if (!e.KeyInput.PressedDown) { current -= 1; if (current < 1) current = 11; show = 1; } break;\r
+               case KEY_KEY_4: if (!e.KeyInput.PressedDown) { current += 1; if (current > 11) current = 1; show = 1; } break;\r
+\r
+               case KEY_KEY_5: val[current] -= e.KeyInput.Shift ? step * 100.f : step; show = 1; break;\r
+               case KEY_KEY_6: val[current] += e.KeyInput.Shift ? step * 100.f : step; show = 1; break;\r
+               default:\r
+                       break;\r
+               }\r
+       }\r
+       if (show)\r
+       {\r
+               if (step < 0.0001f) step = 0.0001f;\r
+               char buf[256];\r
+               if (show == 2) sprintf(buf, "%s %f\n", name[0], val[0]);\r
+               else sprintf(buf, "%s %f\n", name[current], val[current]);\r
+               os::Printer::print(buf);\r
+       }\r
+}\r
+\r
+void CBurningVideoDriver::postEventFromUser(const void* sevent)\r
+{\r
+       if (sevent) Tweak.postEventFromUser(*(const SEvent*)sevent);\r
+}\r
+\r
+tweakBurning Tweak;\r
+#endif //defined(Tweak_Burning)\r
+\r
 \r
 \r
 namespace irr\r
@@ -28,13 +281,17 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
 : 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
-        CurrentOut ( 16 * 2, 256 ), Temp ( 16 * 2, 256 )\r
+       DepthBuffer(0), StencilBuffer ( 0 )\r
 {\r
+       //enable fpu exception\r
+       //unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM);\r
+\r
        #ifdef _DEBUG\r
        setDebugName("CBurningVideoDriver");\r
        #endif\r
 \r
+       VertexCache_map_source_format();\r
+\r
        // create backbuffer\r
        BackBuffer = new CImage(BURNINGSHADER_COLOR_FORMAT, params.WindowSize);\r
        if (BackBuffer)\r
@@ -47,24 +304,25 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
 \r
                // create stencil buffer\r
                if ( params.Stencilbuffer )\r
-                       StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension());\r
+                       StencilBuffer = video::createStencilBuffer(BackBuffer->getDimension(),8);\r
        }\r
 \r
-       DriverAttributes->setAttribute("MaxTextures", 2);\r
        DriverAttributes->setAttribute("MaxIndices", 1<<16);\r
-       DriverAttributes->setAttribute("MaxTextureSize", SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE);\r
+       DriverAttributes->setAttribute("MaxTextures", BURNING_MATERIAL_MAX_TEXTURES);\r
+       DriverAttributes->setAttribute("MaxTextureSize", SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1<<20);\r
        DriverAttributes->setAttribute("MaxLights", 1024 ); //glsl::gl_MaxLights);\r
        DriverAttributes->setAttribute("MaxTextureLODBias", 16.f);\r
-       DriverAttributes->setAttribute("Version", 49);\r
+       DriverAttributes->setAttribute("Version", 50);\r
 \r
        // create triangle renderers\r
 \r
-       irr::memset32 ( BurningShader, 0, sizeof ( BurningShader ) );\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_ALPHA] = createTriangleRendererGouraudAlpha2(this );\r
-       BurningShader[ETR_GOURAUD_ALPHA_NOZ] = createTRGouraudAlphaNoZ2(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
@@ -89,13 +347,15 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
        BurningShader[ETR_STENCIL_SHADOW] = createTRStencilShadow ( this );\r
        BurningShader[ETR_TEXTURE_BLEND] = createTRTextureBlend( this );\r
 \r
-       BurningShader[ETR_REFERENCE] = createTriangleRendererReference ( this );\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
+       //CSoftware2MaterialRenderer_UNSUPPORTED * umr = new CSoftware2MaterialRenderer_UNSUPPORTED ( this );\r
 \r
        //!TODO: addMaterialRenderer depends on pushing order....\r
        addMaterialRenderer ( smr ); // EMT_SOLID\r
@@ -108,7 +368,7 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
        addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M2,\r
        addMaterialRenderer ( smr ); // EMT_LIGHTMAP_LIGHTING_M4,\r
        addMaterialRenderer ( smr ); // EMT_DETAIL_MAP,\r
-       addMaterialRenderer ( umr ); // EMT_SPHERE_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
@@ -116,7 +376,7 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
        addMaterialRenderer ( tmr ); // EMT_TRANSPARENT_VERTEX_ALPHA,\r
        addMaterialRenderer ( smr ); // EMT_TRANSPARENT_REFLECTION_2_LAYER,\r
        addMaterialRenderer ( smr ); // EMT_NORMAL_MAP_SOLID,\r
-       addMaterialRenderer ( umr ); // EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR,\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
@@ -125,16 +385,17 @@ CBurningVideoDriver::CBurningVideoDriver(const irr::SIrrlichtCreationParameters&
 \r
        smr->drop ();\r
        tmr->drop ();\r
-       umr->drop ();\r
+       //umr->drop ();\r
 \r
        // select render target\r
        setRenderTargetImage(BackBuffer);\r
 \r
        //reset Lightspace\r
-       LightSpace.reset ();\r
+       EyeSpace.reset();\r
+       EyeSpace.resetFog();\r
 \r
        // select the right renderer\r
-       setCurrentShader();\r
+       setMaterial(Material.org);\r
 }\r
 \r
 \r
@@ -143,161 +404,45 @@ CBurningVideoDriver::~CBurningVideoDriver()
 {\r
        // delete Backbuffer\r
        if (BackBuffer)\r
+       {\r
                BackBuffer->drop();\r
+               BackBuffer = 0;\r
+       }\r
 \r
        // delete triangle renderers\r
-\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
-               StencilBuffer->drop();\r
-\r
-       if (DepthBuffer)\r
-               DepthBuffer->drop();\r
-\r
-       if (RenderTargetTexture)\r
-               RenderTargetTexture->drop();\r
-\r
-       if (RenderTargetSurface)\r
-               RenderTargetSurface->drop();\r
-}\r
-\r
-\r
-/*!\r
-       selects the right triangle renderer based on the render states.\r
-*/\r
-void CBurningVideoDriver::setCurrentShader()\r
-{\r
-       ITexture *texture0 = Material.org.getTexture(0);\r
-       ITexture *texture1 = Material.org.getTexture(1);\r
-\r
-       bool zMaterialTest = Material.org.ZBuffer != ECFN_DISABLED &&\r
-                                               Material.org.ZWriteEnable != video::EZW_OFF &&\r
-                                               ( AllowZWriteOnTransparent || !Material.org.isTransparent() );\r
-\r
-       EBurningFFShader shader = zMaterialTest ? ETR_TEXTURE_GOURAUD : ETR_TEXTURE_GOURAUD_NOZ;\r
-\r
-       TransformationFlag[ ETS_TEXTURE_0] &= ~(ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION);\r
-       LightSpace.Flags &= ~VERTEXTRANSFORM;\r
-\r
-       switch ( 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
-                       // fall through\r
-               case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
-                       if ( texture0 && texture0->hasAlpha () )\r
-                       {\r
-                               shader = zMaterialTest ? ETR_TEXTURE_GOURAUD_ALPHA : ETR_TEXTURE_GOURAUD_ALPHA_NOZ;\r
-                               break;\r
-                       }\r
-                       else\r
-                       {\r
-                               shader = ETR_TEXTURE_GOURAUD_VERTEX_ALPHA;\r
-                       }\r
-                       break;\r
-\r
-               case EMT_TRANSPARENT_ADD_COLOR:\r
-                       shader = zMaterialTest ? 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
-                       shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;\r
-                       break;\r
-\r
-               case EMT_LIGHTMAP_M2:\r
-               case EMT_LIGHTMAP_LIGHTING_M2:\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
-                       TransformationFlag[ ETS_TEXTURE_0] |= ETF_TEXGEN_CAMERA_REFLECTION; // ETF_TEXGEN_CAMERA_NORMAL;\r
-                       LightSpace.Flags |= VERTEXTRANSFORM;\r
-                       break;\r
-               case EMT_REFLECTION_2_LAYER:\r
-                       shader = ETR_TEXTURE_GOURAUD_LIGHTMAP_M1;\r
-                       TransformationFlag[ ETS_TEXTURE_1] |= ETF_TEXGEN_CAMERA_REFLECTION;\r
-                       LightSpace.Flags |= VERTEXTRANSFORM;\r
-                       break;\r
-\r
-               case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:\r
-               case EMT_NORMAL_MAP_SOLID:\r
-               case EMT_PARALLAX_MAP_SOLID:\r
-               case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:\r
-                       shader = ETR_NORMAL_MAP_SOLID;\r
-                       LightSpace.Flags |= VERTEXTRANSFORM;\r
-                       break;\r
-\r
-               default:\r
-                       break;\r
-\r
+               StencilBuffer->drop();\r
+               StencilBuffer = 0;\r
        }\r
 \r
-       if ( !texture0 )\r
+       if (DepthBuffer)\r
        {\r
-               shader = ETR_GOURAUD;\r
+               DepthBuffer->drop();\r
+               DepthBuffer = 0;\r
        }\r
 \r
-       if ( Material.org.Wireframe )\r
+       if (RenderTargetTexture)\r
        {\r
-               shader = ETR_TEXTURE_GOURAUD_WIRE;\r
+               RenderTargetTexture->drop();\r
+               RenderTargetTexture = 0;\r
        }\r
 \r
-       //shader = ETR_REFERENCE;\r
-\r
-       // switchToTriangleRenderer\r
-       CurrentShader = BurningShader[shader];\r
-       if ( CurrentShader )\r
+       if (RenderTargetSurface)\r
        {\r
-               CurrentShader->setZCompareFunc ( Material.org.ZBuffer );\r
-               CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);\r
-               CurrentShader->setMaterial ( Material );\r
-\r
-               switch ( shader )\r
-               {\r
-                       case ETR_TEXTURE_GOURAUD_ALPHA:\r
-                       case ETR_TEXTURE_GOURAUD_ALPHA_NOZ:\r
-                       case ETR_TEXTURE_BLEND:\r
-                               CurrentShader->setParam ( 0, Material.org.MaterialTypeParam );\r
-                               break;\r
-                       default:\r
-                       break;\r
-               }\r
+               RenderTargetSurface->drop();\r
+               RenderTargetSurface = 0;\r
        }\r
-\r
 }\r
 \r
 \r
@@ -305,31 +450,63 @@ void CBurningVideoDriver::setCurrentShader()
 //! queries the features of the driver, returns true if feature is available\r
 bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const\r
 {\r
-       if (!FeatureEnabled[feature])\r
-               return false;\r
-\r
+       int on = 0;\r
        switch (feature)\r
        {\r
 #ifdef SOFTWARE_DRIVER_2_BILINEAR\r
        case EVDF_BILINEAR_FILTER:\r
-               return true;\r
+               on = 1;\r
+               break;\r
 #endif\r
 #ifdef SOFTWARE_DRIVER_2_MIPMAPPING\r
        case EVDF_MIP_MAP:\r
-               return true;\r
+               on = 1;\r
+               break;\r
 #endif\r
        case EVDF_STENCIL_BUFFER:\r
-               return StencilBuffer != 0;\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
-               return true;\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_TEXTURE_NPOT: // for 2D\r
+               on = 0;\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)\r
+       case EVDF_TEXTURE_NPOT:\r
+       case EVDF_ARB_GLSL:\r
+               on = 1;\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
-               return false;\r
+               on = 0;\r
+               break;\r
        }\r
+\r
+       return on && FeatureEnabled[feature];\r
 }\r
 \r
 \r
@@ -344,100 +521,208 @@ IRenderTarget* CBurningVideoDriver::addRenderTarget()
 }\r
 \r
 \r
-\r
-//! sets transformation\r
-void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)\r
+//matrix multiplication\r
+void CBurningVideoDriver::transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state)\r
 {\r
-       Transformation[state] = mat;\r
-       core::setbit_cond ( TransformationFlag[state], mat.isIdentity(), ETF_IDENTITY );\r
+       size_t* flag = TransformationFlag[TransformationStack];\r
+       if (flag[state] & ETF_VALID ) return;\r
 \r
+       //check\r
+       int ok = 0;\r
        switch ( state )\r
        {\r
-               case ETS_VIEW:\r
-                       Transformation[ETS_VIEW_PROJECTION].setbyproduct_nocheck (\r
-                               Transformation[ETS_PROJECTION],\r
-                               Transformation[ETS_VIEW]\r
-                       );\r
-                       getCameraPosWorldSpace ();\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
-               case ETS_WORLD:\r
-                       if ( TransformationFlag[state] & ETF_IDENTITY )\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
-                               Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD];\r
-                               TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY;\r
-                               Transformation[ETS_CURRENT] = Transformation[ETS_VIEW_PROJECTION];\r
+                               matrix[state] = matrix[ETS_VIEW_PROJECTION];\r
                        }\r
                        else\r
                        {\r
-                               //Transformation[ETS_WORLD].getInversePrimitive ( Transformation[ETS_WORLD_INVERSE] );\r
-                               Transformation[ETS_CURRENT].setbyproduct_nocheck (\r
-                                       Transformation[ETS_VIEW_PROJECTION],\r
-                                       Transformation[ETS_WORLD]\r
-                               );\r
+                               matrix[state].setbyproduct_nocheck(matrix[ETS_VIEW_PROJECTION], matrix[ETS_WORLD]);\r
                        }\r
-                       TransformationFlag[ETS_CURRENT] = 0;\r
-                       //getLightPosObjectSpace ();\r
                        break;\r
-               case ETS_TEXTURE_0:\r
-               case ETS_TEXTURE_1:\r
-               case ETS_TEXTURE_2:\r
-               case ETS_TEXTURE_3:\r
-                       if ( 0 == (TransformationFlag[state] & ETF_IDENTITY ) )\r
-                               LightSpace.Flags |= VERTEXTRANSFORM;\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
-bool CBurningVideoDriver::beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil, const SExposedVideoData& videoData, core::rect<s32>* sourceRect)\r
-{\r
-       CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);\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
-bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)\r
+//! sets transformation\r
+void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)\r
 {\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
-\r
-       if (RenderTargetTexture)\r
-               RenderTargetTexture->drop();\r
-\r
-       CSoftwareRenderTarget2* renderTarget = static_cast<CSoftwareRenderTarget2*>(target);\r
-       RenderTargetTexture = (renderTarget) ? renderTarget->getTexture() : 0;\r
+       size_t* flag = TransformationFlag[TransformationStack];\r
+       core::matrix4* matrix = Transformation[TransformationStack];\r
 \r
-       if (RenderTargetTexture)\r
+#if 0\r
+       int changed = 1;\r
+       if (flag[state] & ETF_VALID)\r
        {\r
-               RenderTargetTexture->grab();\r
-               setRenderTargetImage(((CSoftwareTexture2*)RenderTargetTexture)->getTexture());\r
+               changed = memcmp(mat.pointer(), matrix[state].pointer(), sizeof(mat));\r
        }\r
-       else\r
+       if (changed)\r
+#endif\r
        {\r
-               setRenderTargetImage(BackBuffer);\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
+       CNullDriver::beginScene(clearFlag, clearColor, clearDepth, clearStencil, videoData, sourceRect);\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
+bool CBurningVideoDriver::setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)\r
+{\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
+\r
+       if (RenderTargetTexture)\r
+               RenderTargetTexture->drop();\r
+\r
+       CSoftwareRenderTarget2* renderTarget = static_cast<CSoftwareRenderTarget2*>(target);\r
+       RenderTargetTexture = (renderTarget) ? renderTarget->getTexture() : 0;\r
+\r
+       if (RenderTargetTexture)\r
+       {\r
+               RenderTargetTexture->grab();\r
+               setRenderTargetImage(((CSoftwareTexture2*)RenderTargetTexture)->getTexture());\r
+       }\r
+       else\r
+       {\r
+               setRenderTargetImage(BackBuffer);\r
+       }\r
+\r
+       clearBuffers(clearFlag, clearColor, clearDepth, clearStencil);\r
+\r
+       return true;\r
+}\r
 \r
 //! sets a render target\r
 void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)\r
@@ -445,6 +730,7 @@ void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)
        if (RenderTargetSurface)\r
                RenderTargetSurface->drop();\r
 \r
+       core::dimension2d<u32> current = RenderTargetSize;\r
        RenderTargetSurface = image;\r
        RenderTargetSize.Width = 0;\r
        RenderTargetSize.Height = 0;\r
@@ -455,7 +741,11 @@ void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)
                RenderTargetSize = RenderTargetSurface->getDimension();\r
        }\r
 \r
-       setViewPort(core::rect<s32>(0,0,RenderTargetSize.Width,RenderTargetSize.Height));\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
@@ -465,6 +755,67 @@ void CBurningVideoDriver::setRenderTargetImage(video::CImage* image)
 }\r
 \r
 \r
+//--------- Transform from NDC to DC, transform TexCoo ----------------------------------------------\r
+\r
+// controls subtexel and fill convention\r
+#if defined(SOFTWARE_DRIVER_2_SUBTEXEL)\r
+#define SOFTWARE_DRIVER_2_PIXEL_CENTER -0.5f\r
+#else\r
+#define SOFTWARE_DRIVER_2_PIXEL_CENTER -0.5f\r
+#endif\r
+\r
+#if 1\r
+\r
+// used to scale <-1,-1><1,1> to viewport\r
+void buildNDCToDCMatrix(f32* m, const core::rect<s32>& viewport, f32 tx)\r
+{\r
+       m[0] = (viewport.getWidth() + tx) * 0.5f;\r
+       m[1] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ((viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X) * 0.5f);\r
+\r
+       m[2] = (viewport.getHeight() + tx) * -0.5f;\r
+       m[3] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ((viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y) * 0.5f);\r
+}\r
+\r
+\r
+#else\r
+// used to scale <-1,-1><1,1> to viewport\r
+void buildNDCToDCMatrix( core::matrix4& out, const core::rect<s32>& viewport)\r
+{\r
+       //guard band to stay in screen bounds.(empirical). get holes left side otherwise or out of screen\r
+       //TODO: match openGL or D3D.\r
+       //assumption pixel center, top-left rule and rounding error projection deny exact match without additional clipping\r
+       //or triangle render scanline doesn't step on correct texel center\r
+       //or sampler is not on texel center\r
+\r
+       f32* m = out.pointer();\r
+#if defined(Tweak_Burning) && 0\r
+       m[0]  = (viewport.getWidth() + Tweak.ndc_shrink_x ) * Tweak.ndc_scale_x;\r
+       m[5]  = (viewport.getHeight() + Tweak.ndc_shrink_y ) * Tweak.ndc_scale_y;\r
+       m[12] = Tweak.ndc_trans_x + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f );\r
+       m[13] = Tweak.ndc_trans_y + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f );\r
+#endif\r
+\r
+       m[0]  = (viewport.getWidth() - 0.75f ) * 0.5f;\r
+       m[1]  = 0.f;\r
+       m[2]  = 0.f;\r
+       m[3]  = 0.f;\r
+       m[4]  = 0.f;\r
+       m[5]  = (viewport.getHeight() - 0.75f ) * -0.5f;\r
+       m[6]  = 0.f;\r
+       m[7]  = 0.f;\r
+       m[8]  = 0.f;\r
+       m[9]  = 0.f;\r
+       m[10] = 1.f;\r
+       m[11] = 0.f;\r
+       m[12] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ( (viewport.UpperLeftCorner.X + viewport.LowerRightCorner.X ) * 0.5f );\r
+       m[13] = SOFTWARE_DRIVER_2_PIXEL_CENTER + ( (viewport.UpperLeftCorner.Y + viewport.LowerRightCorner.Y ) * 0.5f );\r
+       m[14] = 0.f;\r
+       m[15] = 1.f;\r
+}\r
+#endif\r
+\r
+\r
+//--------- Transform from NCD to DC ----------------------------------------------\r
 \r
 //! sets a viewport\r
 void CBurningVideoDriver::setViewPort(const core::rect<s32>& area)\r
@@ -474,19 +825,40 @@ void CBurningVideoDriver::setViewPort(const core::rect<s32>& area)
        core::rect<s32> rendert(0,0,RenderTargetSize.Width,RenderTargetSize.Height);\r
        ViewPort.clipAgainst(rendert);\r
 \r
-       Transformation [ ETS_CLIPSCALE ].buildNDCToDCMatrix ( ViewPort, 1 );\r
+       buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[0], ViewPort,-0.375f);\r
+       buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[1], ViewPort, 0.f); // OverrideMaterial2DEnabled ? -0.375f : 0.f);\r
 \r
        if (CurrentShader)\r
                CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);\r
 }\r
 \r
+void CBurningVideoDriver::setScissor(int x, int y, int width, int height)\r
+{\r
+       AbsRectangle v0;\r
+       v0.x0 = x;\r
+       v0.y0 = y;\r
+       v0.x1 = x+width;\r
+       v0.y1 = y+width;\r
+\r
+       const core::dimension2d<u32>& rt = getCurrentRenderTargetSize();\r
+       AbsRectangle v1;\r
+       v1.x0 = 0;\r
+       v1.y0 = 0;\r
+       v1.x1 = rt.Width;\r
+       v1.y1 = rt.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] =\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
@@ -497,7 +869,6 @@ const sVec4 CBurningVideoDriver::NDCPlane[6] =
 };\r
 \r
 \r
-\r
 /*\r
        test a vertex if it's inside the standard frustum\r
 \r
@@ -507,24 +878,24 @@ const sVec4 CBurningVideoDriver::NDCPlane[6] =
        for ( u32 i = 0; i!= 6; ++i )\r
        {\r
                dotPlane = v->Pos.dotProduct ( NDCPlane[i] );\r
-               core::setbit_cond( flag, dotPlane <= 0.f, 1 << 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
-       core::setbit_cond( flag, ( v->Pos.z - v->Pos.w ) <= 0.f, 1 );\r
-       core::setbit_cond( flag, (-v->Pos.z - v->Pos.w ) <= 0.f, 2 );\r
-       core::setbit_cond( flag, ( v->Pos.x - v->Pos.w ) <= 0.f, 4 );\r
-       core::setbit_cond( flag, (-v->Pos.x - v->Pos.w ) <= 0.f, 8 );\r
-       core::setbit_cond( flag, ( v->Pos.y - v->Pos.w ) <= 0.f, 16 );\r
-       core::setbit_cond( flag, (-v->Pos.y - v->Pos.w ) <= 0.f, 32 );\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 u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v  ) const\r
+REALINLINE size_t CBurningVideoDriver::clipToFrustumTest ( const s4DVertex* v  ) const\r
 {\r
-       f32 test[6];\r
-       u32 flag;\r
+       register 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
@@ -538,13 +909,22 @@ REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v  ) c
        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
 /*\r
        flag  = F32_LOWER_EQUAL_0 ( test[0] );\r
        flag |= F32_LOWER_EQUAL_0 ( test[1] ) << 1;\r
@@ -559,33 +939,24 @@ REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v  ) c
 #else\r
 \r
 \r
-REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v  ) const\r
+REALINLINE size_t clipToFrustumTest ( const s4DVertex* v  )\r
 {\r
-       u32 flag = 0;\r
-\r
-       flag |= v->Pos.z <= v->Pos.w ? 1 : 0;\r
-       flag |= -v->Pos.z <= v->Pos.w ? 2 : 0;\r
+       size_t flag = 0;\r
 \r
-       flag |= v->Pos.x <= v->Pos.w ? 4 : 0;\r
-       flag |= -v->Pos.x <= v->Pos.w ? 8 : 0;\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.y <= v->Pos.w ? 16 : 0;\r
-       flag |= -v->Pos.y <= v->Pos.w ? 32 : 0;\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
-/*\r
-       if ( v->Pos.z <= v->Pos.w ) flag |= 1;\r
-       if (-v->Pos.z <= v->Pos.w ) flag |= 2;\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
-       if ( v->Pos.x <= v->Pos.w ) flag |= 4;\r
-       if (-v->Pos.x <= v->Pos.w ) flag |= 8;\r
 \r
-       if ( v->Pos.y <= v->Pos.w ) flag |= 16;\r
-       if (-v->Pos.y <= v->Pos.w ) flag |= 32;\r
-*/\r
 /*\r
-       for ( u32 i = 0; i!= 6; ++i )\r
+       for ( u32 i = 0; i <= 6; ++i )\r
        {\r
-               core::setbit_cond( flag, v->Pos.dotProduct ( NDCPlane[i] ) <= 0.f, 1 << i );\r
+               if (v->Pos.dot_xyzw(NDCPlane[i]) <= 0.f) flag |= ((size_t)1) << i;\r
        }\r
 */\r
        return flag;\r
@@ -593,87 +964,136 @@ REALINLINE u32 CBurningVideoDriver::clipToFrustumTest ( const s4DVertex * v  ) c
 \r
 #endif // _MSC_VER\r
 \r
-u32 CBurningVideoDriver::clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane )\r
-{\r
-       u32 outCount = 0;\r
-       s4DVertex * out = dest;\r
 \r
-       const s4DVertex * a;\r
-       const s4DVertex * b = source;\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
-       f32 bDotPlane;\r
+       const s4DVertex* a;\r
+       const s4DVertex* b = source;\r
 \r
-       bDotPlane = b->Pos.dotProduct ( plane );\r
+       ipoltype bDotPlane;\r
+       bDotPlane = b->Pos.dot_xyzw( plane );\r
 \r
+/*\r
        for( u32 i = 1; i < inCount + 1; ++i)\r
        {\r
-               // i really have problem\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
-\r
-               a = &source[ index ];\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 ( a->Pos.dotProduct ( plane ) <= 0.f )\r
+               if (ipol_lower_equal_0(a->Pos.dot_xyzw( plane )) )\r
                {\r
                        // last point outside\r
-                       if ( F32_GREATER_0 ( bDotPlane ) )\r
+                       if (ipol_greater_0( bDotPlane ) )\r
                        {\r
                                // intersect line segment with plane\r
-                               out->interpolate ( *b, *a, bDotPlane / (b->Pos - a->Pos).dotProduct ( plane ) );\r
-                               out += 2;\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
-                       irr::memcpy32_small ( out, a, SIZEOF_SVERTEX * 2 );\r
+                       memcpy_s4DVertexPair( out, a);\r
                        b = out;\r
 \r
-                       out += 2;\r
+                       out += sizeof_s4DVertexPairRel;\r
                        outCount += 1;\r
                }\r
                else\r
                {\r
                        // current point outside\r
-\r
-                       if ( F32_LOWER_EQUAL_0 (  bDotPlane ) )\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).dotProduct ( plane ) );\r
-                               out += 2;\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.dotProduct ( plane );\r
-\r
+               bDotPlane = b->Pos.dot_xyzw( plane );\r
        }\r
 \r
        return outCount;\r
 }\r
 \r
 \r
-u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u32 vIn )\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
-       u32 vOut = vIn;\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
-       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
        return vOut;\r
 }\r
 \r
 /*!\r
  Part I:\r
        apply Clip Scale matrix\r
-       From Normalized Device Coordiante ( NDC ) Space to Device Coordinate Space ( DC )\r
+       From Normalized Device Coordiante ( NDC ) Space to Device Coordinate ( DC ) Space\r
 \r
  Part II:\r
        Project homogeneous vector\r
@@ -682,279 +1102,618 @@ u32 CBurningVideoDriver::clipToFrustum ( s4DVertex *v0, s4DVertex * v1, const u3
        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
-\r
        replace w/w by 1/w\r
 */\r
-inline void CBurningVideoDriver::ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const\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
-       u32 g;\r
+       const f32* dc = Transformation_ETS_CLIPSCALE[TransformationStack];\r
 \r
-       for ( g = 0; g != vIn; g += 2 )\r
+       for ( size_t g = 0; g != vIn; g += sizeof_s4DVertexPairRel)\r
        {\r
-               if ( (dest[g].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED )\r
-                       continue;\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
-               dest[g].flag = source[g].flag | VERTEX4D_PROJECTED;\r
-\r
-               const f32 w = source[g].Pos.w;\r
-               const f32 iw = core::reciprocal ( w );\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 * Transformation [ ETS_CLIPSCALE ][ 0] + w * Transformation [ ETS_CLIPSCALE ][12] );\r
-               dest[g].Pos.y = iw * ( source[g].Pos.y * Transformation [ ETS_CLIPSCALE ][ 5] + w * Transformation [ ETS_CLIPSCALE ][13] );\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
-#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER\r
-               dest[g].Pos.z = iw * source[g].Pos.z;\r
 #endif\r
 \r
-       #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
                #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-                       dest[g].Color[0] = source[g].Color[0] * iw;\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
-       #endif\r
-               dest[g].LightTangent[0] = source[g].LightTangent[0] * iw;\r
-               dest[g].Pos.w = iw;\r
-       }\r
-}\r
-\r
-\r
-inline void CBurningVideoDriver::ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const\r
-{\r
-       u32 g;\r
-\r
-       for ( g = 0; g != size; g += 1 )\r
-       {\r
-               s4DVertex * a = (s4DVertex*) v[g];\r
-\r
-               if ( (a[1].flag & VERTEX4D_PROJECTED ) == VERTEX4D_PROJECTED )\r
-                       continue;\r
-\r
-               a[1].flag = a->flag | VERTEX4D_PROJECTED;\r
-\r
-               // project homogenous vertex, store 1/w\r
-               const f32 w = a->Pos.w;\r
-               const f32 iw = core::reciprocal ( w );\r
-\r
-               // to device coordinates\r
-               const f32 * p = Transformation [ ETS_CLIPSCALE ].pointer();\r
-               a[1].Pos.x = iw * ( a->Pos.x * p[ 0] + w * p[12] );\r
-               a[1].Pos.y = iw * ( a->Pos.y * p[ 5] + w * p[13] );\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
-#ifndef SOFTWARE_DRIVER_2_USE_WBUFFER\r
-               a[1].Pos.z = a->Pos.z * iw;\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
-       #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-               #ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-                       a[1].Color[0] = a->Color[0] * iw;\r
-               #else\r
-                       a[1].Color[0] = a->Color[0];\r
-               #endif\r
-       #endif\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
-               a[1].LightTangent[0] = a[0].LightTangent[0] * iw;\r
-               a[1].Pos.w = iw;\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
+\r
 /*!\r
-       crossproduct in projected 2D -> screen area triangle\r
+       crossproduct in projected 2D, face\r
 */\r
-inline f32 CBurningVideoDriver::screenarea ( const s4DVertex *v ) const\r
+REALINLINE f32 CBurningVideoDriver::screenarea_inside(const s4DVertexPair* burning_restrict const face[] ) const\r
 {\r
-       return  ( ( v[3].Pos.x - v[1].Pos.x ) * ( v[5].Pos.y - v[1].Pos.y ) ) -\r
-                       ( ( v[3].Pos.y - v[1].Pos.y ) * ( v[5].Pos.x - v[1].Pos.x ) );\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
+#if 0\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
-/*!\r
-*/\r
-inline f32 CBurningVideoDriver::texelarea ( const s4DVertex *v, int tex ) const\r
+f32 MipmapLevel(const sVec2& uv, const sVec2& textureSize)\r
 {\r
-       f32 z;\r
-\r
-       z =             ( (v[2].Tex[tex].x - v[0].Tex[tex].x ) * (v[4].Tex[tex].y - v[0].Tex[tex].y ) )\r
-                -      ( (v[4].Tex[tex].x - v[0].Tex[tex].x ) * (v[2].Tex[tex].y - v[0].Tex[tex].y ) );\r
-\r
-       return MAT_TEXTURE ( tex )->getLODFactor ( z );\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
-/*!\r
-       crossproduct in projected 2D\r
-*/\r
-inline f32 CBurningVideoDriver::screenarea2 ( const s4DVertex **v ) const\r
-{\r
-       return  ( (( v[1] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) * ( (v[2] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) ) -\r
-                       ( (( v[1] + 1 )->Pos.y - (v[0] + 1 )->Pos.y ) * ( (v[2] + 1 )->Pos.x - (v[0] + 1 )->Pos.x ) );\r
-}\r
+#define MAT_TEXTURE(tex) ( (video::CSoftwareTexture2*) Material.org.getTexture ( (u32)tex ) )\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
-inline f32 CBurningVideoDriver::texelarea2 ( const s4DVertex **v, s32 tex ) const\r
+REALINLINE s32 CBurningVideoDriver::lodFactor_inside(const s4DVertexPair* burning_restrict const face[],\r
+       const size_t m, f32 dc_area, f32 lod_bias) const\r
 {\r
-       f32 z;\r
-       z =             ( (v[1]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[2]->Tex[tex].y - v[0]->Tex[tex].y ) )\r
-                -      ( (v[2]->Tex[tex].x - v[0]->Tex[tex].x ) * (v[1]->Tex[tex].y - v[0]->Tex[tex].y ) );\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
-       return MAT_TEXTURE ( tex )->getLODFactor ( z );\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
-/*!\r
-*/\r
-inline void CBurningVideoDriver::select_polygon_mipmap ( s4DVertex *v, u32 vIn, u32 tex, const core::dimension2du& texSize ) const\r
-{\r
-       f32 f[2];\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
-       f[0] = (f32) texSize.Width - 0.25f;\r
-       f[1] = (f32) texSize.Height - 0.25f;\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
-#ifdef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-       for ( u32 g = 0; g != vIn; g += 2 )\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
-               (v + g + 1 )->Tex[tex].x        = (v + g + 0)->Tex[tex].x * ( v + g + 1 )->Pos.w * f[0];\r
-               (v + g + 1 )->Tex[tex].y        = (v + g + 0)->Tex[tex].y * ( v + g + 1 )->Pos.w * f[1];\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
-#else\r
-       for ( u32 g = 0; g != vIn; g += 2 )\r
+\r
+       //only guessing: take more detail (lower mipmap) in light+bump textures\r
+       //assume transparent add is ~50% transparent -> more detail\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
+#if 0\r
+       if (ratio.fields.exp == 0)\r
        {\r
-               (v + g + 1 )->Tex[tex].x        = (v + g + 0)->Tex[tex].x * f[0];\r
-               (v + g + 1 )->Tex[tex].y        = (v + g + 0)->Tex[tex].y * f[1];\r
+               int g = 1;\r
        }\r
 #endif\r
-}\r
+       //log2\r
+       return (ratio.fields.exp & 0x80) ? ratio.fields.exp - 127 : 0; /*denormal very high lod*/\r
 \r
-inline void CBurningVideoDriver::select_polygon_mipmap2 ( s4DVertex **v, u32 tex, const core::dimension2du& texSize ) const\r
-{\r
-       f32 f[2];\r
+       //return (ratio.f <= 1.f) ? 0 : 1;\r
+       //f32 texArea = MAT_TEXTURE(m)->getLODFactor(signedArea); // texelarea_inside(face, m);\r
+       //s32 lodFactor = s32_log2_f32(texArea * dc_area); /* avoid denorm */\r
+\r
+       //return MAT_TEXTURE(m)->getLODFactor(signedArea);\r
+}\r
 \r
-       f[0] = (f32) texSize.Width - 0.25f;\r
-       f[1] = (f32) texSize.Height - 0.25f;\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
-       (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * ( v[0] + 1 )->Pos.w * f[0];\r
-       (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * ( v[0] + 1 )->Pos.w * f[1];\r
+#if defined(Tweak_Burning)\r
+       (face[0] + 1)->Tex[tex].x = face[0]->Tex[tex].x * (face[0] + 1)->Pos.w * (b.w + Tweak.tex_w_add) + (b.cx + Tweak.tex_cx_add);\r
+       (face[0] + 1)->Tex[tex].y = face[0]->Tex[tex].y * (face[0] + 1)->Pos.w * (b.h + Tweak.tex_h_add) + (b.cy + Tweak.tex_cy_add);\r
+\r
+       (face[1] + 1)->Tex[tex].x = face[1]->Tex[tex].x * (face[1] + 1)->Pos.w * (b.w + Tweak.tex_w_add) + (b.cx + Tweak.tex_cx_add);\r
+       (face[1] + 1)->Tex[tex].y = face[1]->Tex[tex].y * (face[1] + 1)->Pos.w * (b.h + Tweak.tex_h_add) + (b.cy + Tweak.tex_cy_add);\r
 \r
-       (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * ( v[1] + 1 )->Pos.w * f[0];\r
-       (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * ( v[1] + 1 )->Pos.w * f[1];\r
+       (face[2] + 1)->Tex[tex].x = face[2]->Tex[tex].x * (face[2] + 1)->Pos.w * (b.w + Tweak.tex_w_add) + (b.cx + Tweak.tex_cx_add);\r
+       (face[2] + 1)->Tex[tex].y = face[2]->Tex[tex].y * (face[2] + 1)->Pos.w * (b.h + Tweak.tex_h_add) + (b.cy + Tweak.tex_cy_add);\r
+#else\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
-       (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * ( v[2] + 1 )->Pos.w * f[0];\r
-       (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * ( v[2] + 1 )->Pos.w * f[1];\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
+#endif\r
 #else\r
-       (v[0] + 1 )->Tex[tex].x = v[0]->Tex[tex].x * f[0];\r
-       (v[0] + 1 )->Tex[tex].y = v[0]->Tex[tex].y * f[1];\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
-       (v[1] + 1 )->Tex[tex].x = v[1]->Tex[tex].x * f[0];\r
-       (v[1] + 1 )->Tex[tex].y = v[1]->Tex[tex].y * f[1];\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
-       (v[2] + 1 )->Tex[tex].x = v[2]->Tex[tex].x * f[0];\r
-       (v[2] + 1 )->Tex[tex].y = v[2]->Tex[tex].y * f[1];\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
-// Vertex Cache\r
-const SVSize CBurningVideoDriver::vSize[] =\r
-{\r
-       { VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 1 },\r
-       { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex2TCoords),2 },\r
-       { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1 | VERTEX4D_FORMAT_BUMP_DOT3, sizeof(S3DVertexTangents),2 },\r
-       { VERTEX4D_FORMAT_TEXTURE_2 | VERTEX4D_FORMAT_COLOR_1, sizeof(S3DVertex), 2 },  // reflection map\r
-       { 0, sizeof(f32) * 3, 0 },      // core::vector3df*\r
-};\r
+}\r
 \r
 \r
+// Vertex Cache\r
 \r
-/*!\r
-       fill a cache line with transformed, light and clipp test triangles\r
-*/\r
-void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 destIndex)\r
+//! setup Vertex Format\r
+void CBurningVideoDriver::VertexCache_map_source_format()\r
 {\r
-       u8 * source;\r
-       s4DVertex *dest;\r
+       u32 s0 = sizeof(s4DVertex);\r
+       u32 s1 = sizeof(s4DVertex_proxy);\r
 \r
-       source = (u8*) VertexCache.vertices + ( sourceIndex * vSize[VertexCache.vType].Pitch );\r
+       if ( s1 <= sizeof_s4DVertex /2 )\r
+       {\r
+               os::Printer::log ( "BurningVideo vertex format unnecessary to large", ELL_WARNING );\r
+       }\r
 \r
-       // it's a look ahead so we never hit it..\r
-       // but give priority...\r
-       //VertexCache.info[ destIndex ].hit = hitCount;\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
-       // store info\r
-       VertexCache.info[ destIndex ].index = sourceIndex;\r
-       VertexCache.info[ destIndex ].hit = 0;\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
+#endif\r
 \r
-       // destination Vertex\r
-       dest = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( destIndex << ( SIZEOF_SVERTEX_LOG2 + 1  ) ) );\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
+\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 S3DVertex *base = ((S3DVertex*) source );\r
-       Transformation [ ETS_CURRENT].transformVect ( &dest->Pos.x, base->Pos );\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
-       //mhm ;-) maybe no goto\r
-       if ( VertexCache.vType == 4 ) goto clipandproject;\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 space\r
-       if ( Material.org.Lighting || (LightSpace.Flags & VERTEXTRANSFORM) )\r
+       // vertex, normal in light(eye) space\r
+       if ( Material.org.Lighting || (EyeSpace.TL_Flag & (TL_TEXTURE_TRANSFORM|TL_FOG)) )\r
        {\r
-               if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY )\r
-               {\r
-                       LightSpace.normal.set ( base->Normal.X, base->Normal.Y, base->Normal.Z, 1.f );\r
-                       LightSpace.vertex.set ( base->Pos.X, base->Pos.Y, base->Pos.Z, 1.f );\r
-               }\r
-               else\r
-               {\r
-                       Transformation[ETS_WORLD].rotateVect ( &LightSpace.normal.x, base->Normal );\r
+               sVec4 vertex4; //eye coordinate position of vertex\r
+               matrix[ETS_MODEL_VIEW].transformVect ( &vertex4.x, base->Pos );\r
 \r
-                       // vertex in light space\r
-                       if ( LightSpace.Flags & ( POINTLIGHT | FOG | SPECULAR | VERTEXTRANSFORM) )\r
-                               Transformation[ETS_WORLD].transformVect ( &LightSpace.vertex.x, base->Pos );\r
-               }\r
+               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
-               if ( LightSpace.Flags & NORMALIZE )\r
-                       LightSpace.normal.normalize_xyz();\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 defined ( SOFTWARE_DRIVER_2_USE_VERTEX_COLOR )\r
-       // apply lighting model\r
-       #if defined (SOFTWARE_DRIVER_2_LIGHTING)\r
-               if ( Material.org.Lighting )\r
-               {\r
-                       lightVertex ( dest, base->Color.color );\r
-               }\r
-               else\r
-               {\r
-                       dest->Color[0].setA8R8G8B8 ( base->Color.color );\r
-               }\r
-       #else\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
-       #endif\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 = core::clamp(fog_factor, 0.f, 1.f);\r
+       }\r
 \r
        // Texture Transform\r
-#if !defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
-       irr::memcpy32_small ( &dest->Tex[0],&base->TCoords,\r
-                                       vSize[VertexCache.vType].TexSize << 3 //  * ( sizeof ( f32 ) * 2 )\r
-                               );\r
-#else\r
+#if defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
 \r
-       if ( 0 == (LightSpace.Flags & VERTEXTRANSFORM) )\r
+       if ( 0 == (EyeSpace.TL_Flag & TL_TEXTURE_TRANSFORM) )\r
+#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
        {\r
-               irr::memcpy32_small ( &dest->Tex[0],&base->TCoords,\r
-                                               vSize[VertexCache.vType].TexSize << 3 //  * ( sizeof ( f32 ) * 2 )\r
-                                       );\r
+               // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address!\r
+               const f32* baseTCoord = &base->TCoords.X;\r
+\r
+               switch (VertexCache.vSize[VertexCache.vType].TexCooSize)\r
+               {\r
+#if BURNING_MATERIAL_MAX_TEXTURES == 4\r
+               case 0:\r
+                       dest->Tex[0].x = 0.f;\r
+                       dest->Tex[0].y = 0.f;\r
+                       dest->Tex[1].x = 0.f;\r
+                       dest->Tex[1].y = 0.f;\r
+                       dest->Tex[2].x = 0.f;\r
+                       dest->Tex[2].y = 0.f;\r
+                       dest->Tex[3].x = 0.f;\r
+                       dest->Tex[3].y = 0.f;\r
+                       break;\r
+               case 1:\r
+                       dest->Tex[0].x = baseTCoord[0];\r
+                       dest->Tex[0].y = baseTCoord[1];\r
+                       dest->Tex[1].x = 0.f;\r
+                       dest->Tex[1].y = 0.f;\r
+                       dest->Tex[2].x = 0.f;\r
+                       dest->Tex[2].y = 0.f;\r
+                       dest->Tex[3].x = 0.f;\r
+                       dest->Tex[3].y = 0.f;\r
+                       break;\r
+               case 2:\r
+                       dest->Tex[0].x = baseTCoord[0];\r
+                       dest->Tex[0].y = baseTCoord[1];\r
+                       dest->Tex[1].x = baseTCoord[2];\r
+                       dest->Tex[1].y = baseTCoord[3];\r
+                       dest->Tex[2].x = 0.f;\r
+                       dest->Tex[2].y = 0.f;\r
+                       dest->Tex[3].x = 0.f;\r
+                       dest->Tex[3].y = 0.f;\r
+                       break;\r
+               case 3:\r
+                       dest->Tex[0].x = baseTCoord[0];\r
+                       dest->Tex[0].y = baseTCoord[1];\r
+                       dest->Tex[1].x = baseTCoord[2];\r
+                       dest->Tex[1].y = baseTCoord[3];\r
+                       dest->Tex[2].x = baseTCoord[4];\r
+                       dest->Tex[2].y = baseTCoord[5];\r
+                       dest->Tex[3].x = 0.f;\r
+                       dest->Tex[3].y = 0.f;\r
+                       break;\r
+               case 4:\r
+                       dest->Tex[0].x = baseTCoord[0];\r
+                       dest->Tex[0].y = baseTCoord[1];\r
+                       dest->Tex[1].x = baseTCoord[2];\r
+                       dest->Tex[1].y = baseTCoord[3];\r
+                       dest->Tex[2].x = baseTCoord[4];\r
+                       dest->Tex[2].y = baseTCoord[5];\r
+                       dest->Tex[3].x = baseTCoord[6];\r
+                       dest->Tex[3].y = baseTCoord[7];\r
+                       break;\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_TEXTURES == 2\r
+               case 0:\r
+                       dest->Tex[0].x = 0.f;\r
+                       dest->Tex[0].y = 0.f;\r
+                       dest->Tex[1].x = 0.f;\r
+                       dest->Tex[1].y = 0.f;\r
+                       break;\r
+\r
+               case 1:\r
+                       dest->Tex[0].x = baseTCoord[0];\r
+                       dest->Tex[0].y = baseTCoord[1];\r
+                       dest->Tex[1].x = 0.f;\r
+                       dest->Tex[1].y = 0.f;\r
+                       break;\r
+               case 2:\r
+                       dest->Tex[0].x = baseTCoord[0];\r
+                       dest->Tex[0].y = baseTCoord[1];\r
+                       dest->Tex[1].x = baseTCoord[2];\r
+                       dest->Tex[1].y = baseTCoord[3];\r
+                       break;\r
+#endif\r
+#if BURNING_MATERIAL_MAX_TEXTURES == 1\r
+               case 0:\r
+                       dest->Tex[0].x = 0.f;\r
+                       dest->Tex[0].y = 0.f;\r
+                       break;\r
+               case 1:\r
+                       dest->Tex[0].x = baseTCoord[0];\r
+                       dest->Tex[0].y = baseTCoord[1];\r
+                       break;\r
+#endif\r
+               default:\r
+                       break;\r
+               }\r
        }\r
+#if defined ( SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM )\r
        else\r
        {\r
        /*\r
@@ -968,222 +1727,195 @@ void CBurningVideoDriver::VertexCache_fill(const u32 sourceIndex, const u32 dest
                                Uw  Vw  0  0\r
        */\r
 \r
-               u32 t;\r
-               sVec4 n;\r
-               sVec2 srcT;\r
+               const sVec4& u = EyeSpace.cam_dir; // EyeSpace.vertex.normalized\r
+               const sVec4& n = EyeSpace.normal;\r
+               sVec4 r;\r
 \r
-               for ( t = 0; t != vSize[VertexCache.vType].TexSize; ++t )\r
+               const size_t* flag = TransformationFlag[TransformationStack];\r
+               for ( u32 t = 0; t != VertexCache.vSize[VertexCache.vType].TexSize; ++t )\r
                {\r
-                       const core::matrix4& M = Transformation [ ETS_TEXTURE_0 + t ];\r
-\r
                        // texgen\r
-                       if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & (ETF_TEXGEN_CAMERA_NORMAL|ETF_TEXGEN_CAMERA_REFLECTION) )\r
+                       if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_SPHERE )\r
                        {\r
-                               n.x = LightSpace.campos.x - LightSpace.vertex.x;\r
-                               n.y = LightSpace.campos.x - LightSpace.vertex.y;\r
-                               n.z = LightSpace.campos.x - LightSpace.vertex.z;\r
-                               n.normalize_xyz();\r
-                               n.x += LightSpace.normal.x;\r
-                               n.y += LightSpace.normal.y;\r
-                               n.z += LightSpace.normal.z;\r
-                               n.normalize_xyz();\r
-\r
-                               const f32 *view = Transformation[ETS_VIEW].pointer();\r
-\r
-                               if ( TransformationFlag [ ETS_TEXTURE_0 + t ] & ETF_TEXGEN_CAMERA_REFLECTION )\r
-                               {\r
-                                       srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[4] + n.z * view[8] ));\r
-                                       srcT.y = 0.5f * ( 1.f + (n.x * view[1] + n.y * view[5] + n.z * view[9] ));\r
-                               }\r
-                               else\r
-                               {\r
-                                       srcT.x = 0.5f * ( 1.f + (n.x * view[0] + n.y * view[1] + n.z * view[2] ));\r
-                                       srcT.y = 0.5f * ( 1.f + (n.x * view[4] + n.y * view[5] + n.z * view[6] ));\r
-                               }\r
+                               //reflect(u,N) u - 2.0 * dot(N, u) * N\r
+                               // cam is (0,0,-1), tex flipped\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
+                               dest[0].Tex[t].x = r.x / m + 0.5f;\r
+                               dest[0].Tex[t].y = -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\r
+                       else if (flag[ETS_TEXTURE_0+t] & ETF_TEXGEN_CAMERA_REFLECTION )\r
                        {\r
-                               irr::memcpy32_small ( &srcT,(&base->TCoords) + t,\r
-                                       sizeof ( f32 ) * 2 );\r
+                               //reflect(u,N) u - 2.0 * dot(N, u) * N\r
+                               // cam is (0,0,-1), tex flipped\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
+                               dest[0].Tex[t].x = r.x;\r
+                               dest[0].Tex[t].y = -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
-\r
-                       switch ( Material.org.TextureLayer[t].TextureWrapU )\r
+                       else if (VertexCache.vSize[VertexCache.vType].TexCooSize > t)\r
                        {\r
-                               case ETC_CLAMP:\r
-                               case ETC_CLAMP_TO_EDGE:\r
-                               case ETC_CLAMP_TO_BORDER:\r
-                                       dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
+                               const f32* M = matrix[ETS_TEXTURE_0 + t].pointer();\r
+\r
+                               // Irrlicht TCoords and TCoords2 must be contiguous memory. baseTCoord has no 4 byte aligned start address!\r
+                               const f32* baseTCoord = &base->TCoords.X;\r
+\r
+                               sVec4 srcT;\r
+                               srcT.x = baseTCoord[(t * 2) + 0];\r
+                               srcT.y = baseTCoord[(t * 2) + 1];\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
+                                               dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
+                                               break;\r
+                                       case ETC_MIRROR:\r
+                                               dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\r
+                                               if (core::fract(dest->Tex[t].x)>0.5f)\r
+                                                       dest->Tex[t].x=1.f-dest->Tex[t].x;\r
                                        break;\r
-                               case ETC_MIRROR:\r
-                                       dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\r
-                                       if (core::fract(dest->Tex[t].x)>0.5f)\r
-                                               dest->Tex[t].x=1.f-dest->Tex[t].x;\r
-                               break;\r
-                               case ETC_MIRROR_CLAMP:\r
-                               case ETC_MIRROR_CLAMP_TO_EDGE:\r
-                               case ETC_MIRROR_CLAMP_TO_BORDER:\r
-                                       dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
-                                       if (core::fract(dest->Tex[t].x)>0.5f)\r
-                                               dest->Tex[t].x=1.f-dest->Tex[t].x;\r
-                               break;\r
-                               case ETC_REPEAT:\r
-                               default:\r
-                                       dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\r
+                                       case ETC_MIRROR_CLAMP:\r
+                                       case ETC_MIRROR_CLAMP_TO_EDGE:\r
+                                       case ETC_MIRROR_CLAMP_TO_BORDER:\r
+                                               dest->Tex[t].x = core::clamp ( (f32) ( M[0] * srcT.x + M[4] * srcT.y + M[8] ), 0.f, 1.f );\r
+                                               if (core::fract(dest->Tex[t].x)>0.5f)\r
+                                                       dest->Tex[t].x=1.f-dest->Tex[t].x;\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
-                                       dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
+                                       case ETC_REPEAT:\r
+                                       default:\r
+                                               dest->Tex[t].x = M[0] * srcT.x + M[4] * srcT.y + M[8];\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
+                                               dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
+                                               break;\r
+                                       case ETC_MIRROR:\r
+                                               dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
+                                               if (core::fract(dest->Tex[t].y)>0.5f)\r
+                                                       dest->Tex[t].y=1.f-dest->Tex[t].y;\r
                                        break;\r
-                               case ETC_MIRROR:\r
-                                       dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
-                                       if (core::fract(dest->Tex[t].y)>0.5f)\r
-                                               dest->Tex[t].y=1.f-dest->Tex[t].y;\r
-                               break;\r
-                               case ETC_MIRROR_CLAMP:\r
-                               case ETC_MIRROR_CLAMP_TO_EDGE:\r
-                               case ETC_MIRROR_CLAMP_TO_BORDER:\r
-                                       dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
-                                       if (core::fract(dest->Tex[t].y)>0.5f)\r
-                                               dest->Tex[t].y=1.f-dest->Tex[t].y;\r
-                               break;\r
-                               case ETC_REPEAT:\r
-                               default:\r
-                                       dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
+                                       case ETC_MIRROR_CLAMP:\r
+                                       case ETC_MIRROR_CLAMP_TO_EDGE:\r
+                                       case ETC_MIRROR_CLAMP_TO_BORDER:\r
+                                               dest->Tex[t].y = core::clamp ( (f32) ( M[1] * srcT.x + M[5] * srcT.y + M[9] ), 0.f, 1.f );\r
+                                               if (core::fract(dest->Tex[t].y)>0.5f)\r
+                                                       dest->Tex[t].y=1.f-dest->Tex[t].y;\r
                                        break;\r
+                                       case ETC_REPEAT:\r
+                                       default:\r
+                                               dest->Tex[t].y = M[1] * srcT.x + M[5] * srcT.y + M[9];\r
+                                               break;\r
+                               }\r
                        }\r
                }\r
        }\r
 \r
-#if 0\r
-       // tangent space light vector, emboss\r
-       if ( Lights.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) )\r
-       {\r
-               const S3DVertexTangents *tangent = ((S3DVertexTangents*) source );\r
-               const SBurningShaderLight &light = LightSpace.Light[0];\r
-\r
-               sVec4 vp;\r
-\r
-               vp.x = light.pos.x - LightSpace.vertex.x;\r
-               vp.y = light.pos.y - LightSpace.vertex.y;\r
-               vp.z = light.pos.z - LightSpace.vertex.z;\r
-\r
-               vp.normalize_xyz();\r
-\r
-               LightSpace.tangent.x = vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z;\r
-               LightSpace.tangent.y = vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z;\r
-               //LightSpace.tangent.z = vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z;\r
-               LightSpace.tangent.z = 0.f;\r
-               LightSpace.tangent.normalize_xyz();\r
-\r
-               f32 scale = 1.f / 128.f;\r
-               if ( Material.org.MaterialTypeParam > 0.f )\r
-                       scale = Material.org.MaterialTypeParam;\r
-\r
-               // emboss, shift coordinates\r
-               dest->Tex[1].x = dest->Tex[0].x + LightSpace.tangent.x * scale;\r
-               dest->Tex[1].y = dest->Tex[0].y + LightSpace.tangent.y * scale;\r
-               //dest->Tex[1].z = LightSpace.tangent.z * scale;\r
-       }\r
-#endif\r
 \r
-       if ( LightSpace.Light.size () && ( vSize[VertexCache.vType].Format & VERTEX4D_FORMAT_BUMP_DOT3 ) )\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
-\r
-               dest->LightTangent[0].x = 0.f;\r
-               dest->LightTangent[0].y = 0.f;\r
-               dest->LightTangent[0].z = 0.f;\r
-               for ( u32 i = 0; i < 2 && i < LightSpace.Light.size (); ++i )\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 = LightSpace.Light[i];\r
-\r
+                       const SBurningShaderLight &light = EyeSpace.Light[i];\r
                        if ( !light.LightIsOn )\r
                                continue;\r
 \r
-                       vp.x = light.pos.x - LightSpace.vertex.x;\r
-                       vp.y = light.pos.y - LightSpace.vertex.y;\r
-                       vp.z = light.pos.z - LightSpace.vertex.z;\r
-\r
-       /*\r
-                       vp.x = light.pos_objectspace.x - base->Pos.X;\r
-                       vp.y = light.pos_objectspace.y - base->Pos.Y;\r
-                       vp.z = light.pos_objectspace.z - base->Pos.Z;\r
-       */\r
-\r
-                       vp.normalize_xyz();\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
-                       sVec3 l;\r
-       #if 1\r
-                       l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Tangent.Y + vp.z * tangent->Tangent.Z );\r
-                       l.y = (vp.x * tangent->Binormal.X + vp.y * tangent->Binormal.Y + vp.z * tangent->Binormal.Z );\r
-                       l.z = (vp.x * tangent->Normal.X + vp.y * tangent->Normal.Y + vp.z * tangent->Normal.Z );\r
-       #else\r
-                       l.x = (vp.x * tangent->Tangent.X + vp.y * tangent->Binormal.X + vp.z * tangent->Normal.X );\r
-                       l.y = (vp.x * tangent->Tangent.Y + vp.y * tangent->Binormal.Y + vp.z * tangent->Normal.Y );\r
-                       l.z = (vp.x * tangent->Tangent.Z + vp.y * tangent->Binormal.Z + vp.z * tangent->Normal.Z );\r
-       #endif\r
-\r
-\r
-       /*\r
-                       f32 scale = 1.f / 128.f;\r
-                       scale /= dest->LightTangent[0].b;\r
-\r
-                       // emboss, shift coordinates\r
-                       dest->Tex[1].x = dest->Tex[0].x + l.r * scale;\r
-                       dest->Tex[1].y = dest->Tex[0].y + l.g * scale;\r
-       */\r
-                       dest->Tex[1].x = dest->Tex[0].x;\r
-                       dest->Tex[1].y = dest->Tex[0].y;\r
-\r
-                       // scale bias\r
-                       dest->LightTangent[0].x += l.x;\r
-                       dest->LightTangent[0].y += l.y;\r
-                       dest->LightTangent[0].z += l.z;\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
-               dest->LightTangent[0].setLength ( 0.5f );\r
-               dest->LightTangent[0].x += 0.5f;\r
-               dest->LightTangent[0].y += 0.5f;\r
-               dest->LightTangent[0].z += 0.5f;\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\r
+#endif // SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
 \r
 clipandproject:\r
-       dest[0].flag = dest[1].flag = vSize[VertexCache.vType].Format;\r
 \r
-       // test vertex\r
-       dest[0].flag |= clipToFrustumTest ( dest);\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_project2 ( (const s4DVertex**) &dest, 1 );\r
+               ndc_2_dc_and_project ( dest+1, dest, s4DVertex_ofs(1));\r
        }\r
 \r
-       //return dest;\r
 }\r
 \r
-//\r
 \r
-REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex )\r
+//todo: this should return only index\r
+s4DVertexPair* CBurningVideoDriver::VertexCache_getVertex ( const u32 sourceIndex ) const\r
 {\r
-       for ( s32 i = 0; i < VERTEXCACHE_ELEMENT; ++i )\r
+       for ( size_t i = 0; i < VERTEXCACHE_ELEMENT; ++i )\r
        {\r
                if ( VertexCache.info[ i ].index == sourceIndex )\r
                {\r
-                       return (s4DVertex *) ( (u8*) VertexCache.mem.data + ( i << ( SIZEOF_SVERTEX_LOG2 + 1  ) ) );\r
+                       return VertexCache.mem.data + s4DVertex_ofs(i);\r
                }\r
        }\r
-       return 0;\r
+       return VertexCache.mem.data; //error\r
 }\r
 \r
 \r
@@ -1192,24 +1924,29 @@ REALINLINE s4DVertex * CBurningVideoDriver::VertexCache_getVertex ( const u32 so
        fill blockwise on the next 16(Cache_Size) unique vertices in indexlist\r
        merge the next 16 vertices with the current\r
 */\r
-REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)\r
+void CBurningVideoDriver::VertexCache_get(s4DVertexPair* face[4])\r
 {\r
-       SCacheInfo info[VERTEXCACHE_ELEMENT];\r
-\r
        // next primitive must be complete in cache\r
-       if (    VertexCache.indicesIndex - VertexCache.indicesRun < 3 &&\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
-               irr::memset32 ( info, VERTEXCACHE_MISS, sizeof ( info ) );\r
 \r
                // get the next unique vertices cache line\r
                u32 fillIndex = 0;\r
                u32 dIndex = 0;\r
-               u32 i = 0;\r
                u32 sourceIndex = 0;\r
 \r
                while ( VertexCache.indicesIndex < VertexCache.indexCount &&\r
@@ -1218,13 +1955,14 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
                {\r
                        switch ( VertexCache.iType )\r
                        {\r
-                               case 1:\r
+                               case E4IT_16BIT:\r
                                        sourceIndex =  ((u16*)VertexCache.indices) [ VertexCache.indicesIndex ];\r
                                        break;\r
-                               case 2:\r
+                               case E4IT_32BIT:\r
                                        sourceIndex =  ((u32*)VertexCache.indices) [ VertexCache.indicesIndex ];\r
                                        break;\r
-                               case 4:\r
+                               default:\r
+                               case E4IT_NONE:\r
                                        sourceIndex = VertexCache.indicesIndex;\r
                                        break;\r
                        }\r
@@ -1235,7 +1973,7 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
                        s32 exist = 0;\r
                        for ( dIndex = 0;  dIndex < fillIndex; ++dIndex )\r
                        {\r
-                               if ( info[ dIndex ].index == sourceIndex )\r
+                               if (VertexCache.info_temp[ dIndex ].index == sourceIndex )\r
                                {\r
                                        exist = 1;\r
                                        break;\r
@@ -1244,7 +1982,7 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
 \r
                        if ( 0 == exist )\r
                        {\r
-                               info[fillIndex++].index = sourceIndex;\r
+                               VertexCache.info_temp[fillIndex++].index = sourceIndex;\r
                        }\r
                }\r
 \r
@@ -1259,9 +1997,9 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
                {\r
                        for ( dIndex = 0;  dIndex < VERTEXCACHE_ELEMENT; ++dIndex )\r
                        {\r
-                               if ( VertexCache.info[ dIndex ].index == info[i].index )\r
+                               if ( VertexCache.info[ dIndex ].index == VertexCache.info_temp[i].index )\r
                                {\r
-                                       info[i].hit = dIndex;\r
+                                       VertexCache.info_temp[i].hit = dIndex;\r
                                        VertexCache.info[ dIndex ].hit = 1;\r
                                        break;\r
                                }\r
@@ -1271,45 +2009,46 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
                // fill new\r
                for ( i = 0; i!= fillIndex; ++i )\r
                {\r
-                       if ( info[i].hit != VERTEXCACHE_MISS )\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 ( info[i].index, dIndex );\r
+                                       VertexCache_fill (VertexCache.info_temp[i].index, dIndex );\r
                                        VertexCache.info[dIndex].hit += 1;\r
-                                       info[i].hit = dIndex;\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 = 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 1:\r
+               case E4IT_16BIT:\r
                {\r
-                       const u16 *p = (const u16 *) VertexCache.indices;\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 2:\r
+               case E4IT_32BIT:\r
                {\r
-                       const u32 *p = (const u32 *) VertexCache.indices;\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 4:\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
@@ -1318,122 +2057,149 @@ REALINLINE void CBurningVideoDriver::VertexCache_get(const s4DVertex ** face)
                        face[0] = face[1] = face[2] = VertexCache_getVertex(VertexCache.indicesRun + 0);\r
                break;\r
        }\r
-\r
-       VertexCache.indicesRun += VertexCache.primitivePitch;\r
+       face[3] = face[0]; // quad unsupported\r
+       VertexCache.indicesRun += VertexCache.indicesPitch;\r
 }\r
 \r
-/*!\r
-*/\r
-REALINLINE void CBurningVideoDriver::VertexCache_getbypass ( s4DVertex ** face )\r
-{\r
-       const u32 i0 = core::if_c_a_else_0 ( VertexCache.pType != scene::EPT_TRIANGLE_FAN, VertexCache.indicesRun );\r
-\r
-       if ( VertexCache.iType == 1 )\r
-       {\r
-               const u16 *p = (const u16 *) VertexCache.indices;\r
-               VertexCache_fill ( p[ i0    ], 0 );\r
-               VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 );\r
-               VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 );\r
-       }\r
-       else\r
-       {\r
-               const u32 *p = (const u32 *) VertexCache.indices;\r
-               VertexCache_fill ( p[ i0    ], 0 );\r
-               VertexCache_fill ( p[ VertexCache.indicesRun + 1], 1 );\r
-               VertexCache_fill ( p[ VertexCache.indicesRun + 2], 2 );\r
-       }\r
-\r
-       VertexCache.indicesRun += VertexCache.primitivePitch;\r
-\r
-       face[0] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1  ) ) );\r
-       face[1] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1  ) ) );\r
-       face[2] = (s4DVertex *) ( (u8*) VertexCache.mem.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1  ) ) );\r
-\r
-}\r
 \r
 /*!\r
 */\r
-void CBurningVideoDriver::VertexCache_reset ( const void* vertices, u32 vertexCount,\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
-       if ( Material.org.MaterialType == video::EMT_REFLECTION_2_LAYER )\r
-               VertexCache.vType = 3;\r
-       else\r
-               VertexCache.vType = vType;\r
-       VertexCache.pType = pType;\r
-\r
        switch ( iType )\r
        {\r
-               case EIT_16BIT: VertexCache.iType = 1; break;\r
-               case EIT_32BIT: VertexCache.iType = 2; break;\r
+               case EIT_16BIT: VertexCache.iType = E4IT_16BIT; break;\r
+               case EIT_32BIT: VertexCache.iType = E4IT_32BIT; break;\r
                default:\r
-                       VertexCache.iType = iType; break;\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.primitivePitch = 1;\r
+                       VertexCache.indicesPitch = 1;\r
+                       VertexCache.primitiveHasVertex = 1;\r
                        break;\r
                case scene::EPT_LINE_STRIP:\r
                        VertexCache.indexCount = primitiveCount+1;\r
-                       VertexCache.primitivePitch = 1;\r
+                       VertexCache.indicesPitch = 1;\r
+                       VertexCache.primitiveHasVertex = 2;\r
                        break;\r
                case scene::EPT_LINE_LOOP:\r
                        VertexCache.indexCount = primitiveCount+1;\r
-                       VertexCache.primitivePitch = 1;\r
+                       VertexCache.indicesPitch = 1;\r
+                       VertexCache.primitiveHasVertex = 2;\r
                        break;\r
                case scene::EPT_LINES:\r
                        VertexCache.indexCount = 2*primitiveCount;\r
-                       VertexCache.primitivePitch = 2;\r
+                       VertexCache.indicesPitch = 2;\r
+                       VertexCache.primitiveHasVertex = 2;\r
                        break;\r
                case scene::EPT_TRIANGLE_STRIP:\r
                        VertexCache.indexCount = primitiveCount+2;\r
-                       VertexCache.primitivePitch = 1;\r
+                       VertexCache.indicesPitch = 1;\r
+                       VertexCache.primitiveHasVertex = 3;\r
                        break;\r
                case scene::EPT_TRIANGLES:\r
                        VertexCache.indexCount = primitiveCount + primitiveCount + primitiveCount;\r
-                       VertexCache.primitivePitch = 3;\r
+                       VertexCache.indicesPitch = 3;\r
+                       VertexCache.primitiveHasVertex = 3;\r
                        break;\r
                case scene::EPT_TRIANGLE_FAN:\r
                        VertexCache.indexCount = primitiveCount + 2;\r
-                       VertexCache.primitivePitch = 1;\r
+                       VertexCache.indicesPitch = 1;\r
+                       VertexCache.primitiveHasVertex = 3;\r
                        break;\r
                case scene::EPT_QUAD_STRIP:\r
                        VertexCache.indexCount = 2*primitiveCount + 2;\r
-                       VertexCache.primitivePitch = 2;\r
+                       VertexCache.indicesPitch = 2;\r
+                       VertexCache.primitiveHasVertex = 4;\r
                        break;\r
                case scene::EPT_QUADS:\r
                        VertexCache.indexCount = 4*primitiveCount;\r
-                       VertexCache.primitivePitch = 4;\r
+                       VertexCache.indicesPitch = 4;\r
+                       VertexCache.primitiveHasVertex = 4;\r
                        break;\r
                case scene::EPT_POLYGON:\r
                        VertexCache.indexCount = primitiveCount+1;\r
-                       VertexCache.primitivePitch = 1;\r
+                       VertexCache.indicesPitch = 1;\r
+                       VertexCache.primitiveHasVertex = primitiveCount;\r
                        break;\r
                case scene::EPT_POINT_SPRITES:\r
                        VertexCache.indexCount = primitiveCount;\r
-                       VertexCache.primitivePitch = 1;\r
+                       VertexCache.indicesPitch = 1;\r
+                       VertexCache.primitiveHasVertex = 1;\r
                        break;\r
        }\r
 \r
-       irr::memset32 ( VertexCache.info, VERTEXCACHE_MISS, sizeof ( VertexCache.info ) );\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
@@ -1444,134 +2210,138 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
 \r
        CNullDriver::drawVertexPrimitiveList(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType);\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 (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
+       if (VertexCache_reset(vertices, vertexCount, indexList, primitiveCount, vType, pType, iType))\r
                return;\r
 \r
-       if ( 0 == CurrentShader )\r
-               return;\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
-       VertexCache_reset ( vertices, vertexCount, indexList, primitiveCount, vType, pType, iType );\r
 \r
-       const s4DVertex * face[3];\r
+       s4DVertexPair* face[4];\r
 \r
-       f32 dc_area;\r
-       s32 lodLevel;\r
-       u32 i;\r
-       u32 g;\r
-       u32 m;\r
-       video::CSoftwareTexture2* tex;\r
+       size_t vOut;\r
+       size_t vertex_from_clipper; // from VertexCache or CurrentOut\r
+       size_t has_vertex_run;\r
 \r
-       for ( i = 0; i < (u32) primitiveCount; ++i )\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
-               // if fully outside or outside on same side\r
-               if ( ( (face[0]->flag | face[1]->flag | face[2]->flag) & VERTEX4D_CLIPMASK )\r
-                               != VERTEX4D_INSIDE\r
-                       )\r
-                       continue;\r
+               register size_t clipMask_i;\r
+               register size_t clipMask_o;\r
 \r
-               // if fully inside\r
-               if ( ( face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE )\r
-               {\r
-                       dc_area = screenarea2 ( face );\r
-                       if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0( dc_area ) )\r
-                               continue;\r
-                       else\r
-                       if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )\r
-                               continue;\r
+               clipMask_i = face[0]->flag;\r
+               clipMask_o = face[0]->flag;\r
 \r
-                       // select mipmap\r
-                       dc_area = core::reciprocal ( dc_area );\r
-                       for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m )\r
-                       {\r
-                               if ( 0 == (tex = MAT_TEXTURE ( m )) )\r
-                               {\r
-                                       CurrentShader->setTextureParam(m, 0, 0);\r
-                                       continue;\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
-                               lodLevel = s32_log2_f32 ( texelarea2 ( face, m ) * dc_area  );\r
-                               CurrentShader->setTextureParam(m, tex, lodLevel );\r
-                               select_polygon_mipmap2 ( (s4DVertex**) face, m, tex->getSize() );\r
-                       }\r
+               clipMask_i &= VERTEX4D_CLIPMASK;\r
+               clipMask_o &= VERTEX4D_CLIPMASK;\r
 \r
-                       // rasterize\r
-                       CurrentShader->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 );\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
-               // else if not complete inside clipping necessary\r
-               irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 0 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[0], SIZEOF_SVERTEX * 2 );\r
-               irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 1 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[1], SIZEOF_SVERTEX * 2 );\r
-               irr::memcpy32_small ( ( (u8*) CurrentOut.data + ( 2 << ( SIZEOF_SVERTEX_LOG2 + 1 ) ) ), face[2], SIZEOF_SVERTEX * 2 );\r
-\r
-               const u32 flag = CurrentOut.data->flag & VERTEX4D_FORMAT_MASK;\r
+                       vOut = clipToFrustum(VertexCache.primitiveHasVertex);\r
+                       vertex_from_clipper = 1;\r
 \r
-               for ( g = 0; g != CurrentOut.ElementSize; ++g )\r
+                       // to DC Space, project homogenous vertex\r
+                       ndc_2_dc_and_project(Clipper.data + s4DVertex_proj(0), Clipper.data, s4DVertex_ofs(vOut));\r
+               }\r
+#else\r
                {\r
-                       CurrentOut.data[g].flag = flag;\r
-                       Temp.data[g].flag = flag;\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
-               u32 vOut;\r
-               vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 );\r
-               if ( vOut < 3 )\r
-                       continue;\r
+                       //area of primitive in device space\r
+                       f32 dc_area = screenarea_inside(face);\r
 \r
-               vOut <<= 1;\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
-               // to DC Space, project homogenous vertex\r
-               ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );\r
+                       //select mipmap ratio between drawing space and texture space\r
+                       dc_area = reciprocal_zero(dc_area);\r
 \r
-               // check 2d backface culling on first\r
-               dc_area = screenarea ( CurrentOut.data );\r
-               if ( Material.org.BackfaceCulling && F32_LOWER_EQUAL_0 ( dc_area ) )\r
-                       continue;\r
-               else if ( Material.org.FrontfaceCulling && F32_GREATER_EQUAL_0( dc_area ) )\r
-                       continue;\r
-\r
-               // select mipmap\r
-               dc_area = core::reciprocal ( dc_area );\r
-               for ( m = 0; m != vSize[VertexCache.vType].TexSize; ++m )\r
-               {\r
-                       if ( 0 == (tex = MAT_TEXTURE ( m )) )\r
+                       // select mipmap\r
+                       for (size_t m = 0; m < VertexCache.vSize[VertexCache.vType].TexSize; ++m)\r
                        {\r
-                               CurrentShader->setTextureParam(m, 0, 0);\r
-                               continue;\r
-                       }\r
+                               video::CSoftwareTexture2* tex = MAT_TEXTURE(m);\r
 \r
-                       lodLevel = s32_log2_f32 ( texelarea ( CurrentOut.data, m ) * dc_area );\r
-                       CurrentShader->setTextureParam(m, tex, lodLevel );\r
-                       select_polygon_mipmap ( CurrentOut.data, vOut, m, tex->getSize() );\r
-               }\r
+                               //only guessing: take more detail (lower mipmap) in light+bump textures\r
+                               //assume transparent add is ~50% transparent -> more detail\r
+                               f32 lod_bias = Material.org.MaterialType == EMT_TRANSPARENT_ADD_COLOR ? 0.1f : 0.33f;\r
+                               lod_bias *= tex->get_lod_bias();\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
-               // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )\r
-               for ( g = 0; g <= vOut - 6; g += 2 )\r
-               {\r
-                       // rasterize\r
-                       CurrentShader->drawTriangle ( CurrentOut.data + 0 + 1,\r
-                                                       CurrentOut.data + g + 3,\r
-                                                       CurrentOut.data + g + 5);\r
+                       CurrentShader->drawWireFrameTriangle(face[0] + 1, face[1] + 1, face[2] + 1);\r
+                       vertex_from_clipper = 1;\r
                }\r
 \r
        }\r
 \r
-       // dump statistics\r
-/*\r
-       char buf [64];\r
-       sprintf ( buf,"VCount:%d PCount:%d CacheMiss: %d",\r
-                                       vertexCount, primitiveCount,\r
-                                       VertexCache.CacheMiss\r
-                               );\r
-       os::Printer::log( buf );\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
@@ -1581,8 +2351,7 @@ void CBurningVideoDriver::drawVertexPrimitiveList(const void* vertices, u32 vert
 //! \param color: New color of the ambient light.\r
 void CBurningVideoDriver::setAmbientLight(const SColorf& color)\r
 {\r
-       CNullDriver::setAmbientLight(color);\r
-       LightSpace.Global_AmbientLight.setColorf ( color );\r
+       EyeSpace.Global_AmbientLight.setColorf ( color );\r
 }\r
 \r
 \r
@@ -1600,54 +2369,102 @@ s32 CBurningVideoDriver::addDynamicLight(const SLight& dl)
        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 video::ELT_DIRECTIONAL:\r
-                       l.pos.x = -dl.Direction.X;\r
-                       l.pos.y = -dl.Direction.Y;\r
-                       l.pos.z = -dl.Direction.Z;\r
-                       l.pos.w = 1.f;\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
-               case ELT_SPOT:\r
-                       LightSpace.Flags |= POINTLIGHT;\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.radius = (1.f / dl.Attenuation.Y) * (1.f / dl.Attenuation.Y);\r
+\r
                        l.constantAttenuation = dl.Attenuation.X;\r
                        l.linearAttenuation = dl.Attenuation.Y;\r
                        l.quadraticAttenuation = dl.Attenuation.Z;\r
-*/\r
-                       l.radius = dl.Radius * dl.Radius;\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 = 1.f / dl.Radius;\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
-       LightSpace.Light.push_back ( l );\r
-       return LightSpace.Light.size() - 1;\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(lightIndex > -1 && lightIndex < (s32)LightSpace.Light.size())\r
+       if((u32)lightIndex < EyeSpace.Light.size())\r
        {\r
-               LightSpace.Light[lightIndex].LightIsOn = turnOn;\r
+               EyeSpace.Light[lightIndex].LightIsOn = turnOn;\r
        }\r
 }\r
 \r
 //! deletes all dynamic lights there are\r
 void CBurningVideoDriver::deleteAllDynamicLights()\r
 {\r
-       LightSpace.reset ();\r
+       EyeSpace.reset ();\r
        CNullDriver::deleteAllDynamicLights();\r
 \r
 }\r
@@ -1655,315 +2472,972 @@ void CBurningVideoDriver::deleteAllDynamicLights()
 //! returns the maximal amount of dynamic lights the device can handle\r
 u32 CBurningVideoDriver::getMaximalDynamicLightAmount() const\r
 {\r
-       return 8;\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 i = 0; i < 2; ++i)\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 + i),\r
-                               material.getTextureMatrix(i));\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
-       Material.AmbientColor.setR8G8B8 ( Material.org.AmbientColor.color );\r
-       Material.DiffuseColor.setR8G8B8 ( Material.org.DiffuseColor.color );\r
-       Material.EmissiveColor.setR8G8B8 ( Material.org.EmissiveColor.color );\r
-       Material.SpecularColor.setR8G8B8 ( Material.org.SpecularColor.color );\r
 \r
-       core::setbit_cond ( LightSpace.Flags, Material.org.Shininess != 0.f, SPECULAR );\r
-       core::setbit_cond ( LightSpace.Flags, Material.org.FogEnable, FOG );\r
-       core::setbit_cond ( LightSpace.Flags, Material.org.NormalizeNormals, NORMALIZE );\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
+       //--------------- 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);\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_zero2(FogEnd - FogStart);\r
 }\r
 \r
 \r
+\r
+#if defined(SOFTWARE_DRIVER_2_LIGHTING) && BURNING_MATERIAL_MAX_COLORS > 0\r
+\r
+\r
 /*!\r
-       Camera Position in World Space\r
+       applies lighting model\r
 */\r
-void CBurningVideoDriver::getCameraPosWorldSpace ()\r
+void CBurningVideoDriver::lightVertex_eye(s4DVertex *dest, u32 vertexargb)\r
 {\r
-       Transformation[ETS_VIEW_INVERSE] = Transformation[ ETS_VIEW ];\r
-       Transformation[ETS_VIEW_INVERSE].makeInverse ();\r
-       TransformationFlag[ETS_VIEW_INVERSE] = 0;\r
+       //gl_FrontLightModelProduct.sceneColor = gl_FrontMaterial.emission + gl_FrontMaterial.ambient * gl_LightModel.ambient\r
 \r
-       const f32 *M = Transformation[ETS_VIEW_INVERSE].pointer ();\r
+       sVec3Color ambient;\r
+       sVec3Color diffuse;\r
+       sVec3Color specular;\r
 \r
-       /*      The  viewpoint is at (0., 0., 0.) in eye space.\r
-               Turning this into a vector [0 0 0 1] and multiply it by\r
-               the inverse of the view matrix, the resulting vector is the\r
-               object space location of the camera.\r
-       */\r
 \r
-       LightSpace.campos.x = M[12];\r
-       LightSpace.campos.y = M[13];\r
-       LightSpace.campos.z = M[14];\r
-       LightSpace.campos.w = 1.f;\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
-void CBurningVideoDriver::getLightPosObjectSpace ()\r
+#endif\r
+\r
+CImage* getImage(const video::ITexture* texture)\r
 {\r
-       if ( TransformationFlag[ETS_WORLD] & ETF_IDENTITY )\r
+       if (!texture) return 0;\r
+\r
+       CImage* img = 0;\r
+       switch (texture->getDriverType())\r
        {\r
-               Transformation[ETS_WORLD_INVERSE] = Transformation[ETS_WORLD];\r
-               TransformationFlag[ETS_WORLD_INVERSE] |= ETF_IDENTITY;\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
+\r
+\r
+#if 0\r
+void transform_for_BlitJob2D( SBlitJob& out,\r
+       const S3DVertex quad2DVertices[4], const core::dimension2d<u32>& renderTargetSize,\r
+       CBurningVideoDriver* driver\r
+)\r
+{\r
+       //assume. z = 0.f, w = 1.f\r
+       //MVP 2D\r
+       core::matrix4 m;\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
+\r
+       //setTransform(ETS_WORLD, m);\r
+       //m.setTranslation(core::vector3df(0.375f, 0.375f, 0.0f));\r
+       //setTransform(ETS_VIEW, m);\r
+\r
+       s4DVertexPair v[4*sizeof_s4DVertexPairRel];\r
+       for (int i = 0; i < 4; ++i)\r
+       {\r
+               m.transformVect(&v[s4DVertex_ofs(i)].Pos.x, quad2DVertices[i].Pos);\r
+               v[s4DVertex_ofs(i)].Tex[0].x = quad2DVertices[i].TCoords.X;\r
+               v[s4DVertex_ofs(i)].Tex[0].y = quad2DVertices[i].TCoords.Y;\r
+               v[s4DVertex_ofs(i)].Color[0].setA8R8G8B8(quad2DVertices[i].Color.color);\r
+               v[s4DVertex_ofs(i)].flag = VERTEX4D_FORMAT_TEXTURE_1 | VERTEX4D_FORMAT_COLOR_1;\r
+               v[s4DVertex_ofs(i)].flag |= clipToFrustumTest(v + i);\r
+       }\r
+\r
+       size_t vOut = driver->clipToFrustum(4);\r
+\r
+       struct s2DVertex\r
+       {\r
+               union\r
+               {\r
+                       struct {\r
+                               f32 x, y;\r
+                               f32 u, v;\r
+                               f32 a, r, g, b;\r
+                       };\r
+                       f32 attr[8];\r
+               };\r
+\r
+               // f = a * t + b * ( 1 - t )\r
+               void interpolate(const s2DVertex& b, const s2DVertex& a, const f32 t)\r
+               {\r
+                       for (int i = 0; i < 8; ++i)\r
+                       {\r
+                               attr[i] = b.attr[i] + ((a.attr[i] - b.attr[i]) * t);\r
+                       }\r
+               }\r
+\r
+       };\r
+\r
+       // 0 5\r
+       f32 m2[2];\r
+       m2[0] = renderTargetSize.Width ? 2.f / renderTargetSize.Width : 0.f;\r
+       m2[1] = renderTargetSize.Height ? -2.f / renderTargetSize.Height : 0.f;\r
+\r
+       s2DVertex p[4];\r
+       for (int i = 0; i < 4; ++i)\r
+       {\r
+               p[i].x = quad2DVertices[i].Pos.X*m2[0] - 1.f;\r
+               p[i].y = quad2DVertices[i].Pos.Y*m2[1] + 1.f;\r
+               p[i].u = quad2DVertices[i].TCoords.X;\r
+               p[i].v = quad2DVertices[i].TCoords.Y;\r
+\r
+               p[i].a = quad2DVertices[i].Color.getAlpha() * (1.f / 255.f);\r
+               p[i].r = quad2DVertices[i].Color.getRed() * (1.f / 255.f);\r
+               p[i].g = quad2DVertices[i].Color.getBlue() * (1.f / 255.f);\r
+               p[i].b = quad2DVertices[i].Color.getGreen() * (1.f / 255.f);\r
+\r
+       }\r
+\r
+}\r
+#endif\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, 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
-               Transformation[ETS_WORLD].getInverse ( Transformation[ETS_WORLD_INVERSE] );\r
-               TransformationFlag[ETS_WORLD_INVERSE] &= ~ETF_IDENTITY;\r
+               Material.mat2D.MaterialType = EMT_SOLID;\r
        }\r
 \r
-       for ( u32 i = 0; i < 1 && i < LightSpace.Light.size(); ++i )\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].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
-               SBurningShaderLight &l = LightSpace.Light[i];\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 ) m.setTranslation(core::vector3df(0.375f, 0.375f, 0.0f));\r
 \r
-               Transformation[ETS_WORLD_INVERSE].transformVec3 ( &l.pos_objectspace.x, &l.pos.x );\r
+               setTransform(ETS_VIEW, m);\r
+\r
+               buildNDCToDCMatrix(Transformation_ETS_CLIPSCALE[TransformationStack], ViewPort, mip ? -0.187f : 0.f);\r
+\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
        }\r
+\r
 }\r
 \r
+void CBurningVideoDriver::setRenderStates3DMode()\r
+{\r
+       //restoreRenderStates3DMode\r
 \r
-#ifdef SOFTWARE_DRIVER_2_LIGHTING\r
+       //setMaterial(Material.save3D);\r
+       //switch to 3D Matrix Stack\r
+       TransformationStack = 0;\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
+//! 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
-       CNullDriver::setFog(color, fogType, start, end, density, pixelFog, rangeFog);\r
-       LightSpace.FogColor.setA8R8G8B8 ( color.color );\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
-/*!\r
-       applies lighting model\r
-*/\r
-void CBurningVideoDriver::lightVertex ( s4DVertex *dest, u32 vertexargb )\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
-       sVec3 dColor;\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
+       //SBlitJob job;\r
+       //transform_for_BlitJob2D(job, Quad2DVertices, renderTargetSize,this);\r
+\r
+       setRenderStates2DMode(color, (video::ITexture*) 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
-       dColor = LightSpace.Global_AmbientLight;\r
-       dColor.add ( Material.EmissiveColor );\r
+       const video::SColor* const useColor = colors ? colors : temp;\r
 \r
-       if ( Lights.size () == 0 )\r
-       {\r
-               dColor.saturate( dest->Color[0], vertexargb);\r
-               return;\r
-       }\r
 \r
-       sVec3 ambient;\r
-       sVec3 diffuse;\r
-       sVec3 specular;\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
-       // the universe started in darkness..\r
-       ambient.set ( 0.f, 0.f, 0.f );\r
-       diffuse.set ( 0.f, 0.f, 0.f );\r
-       specular.set ( 0.f, 0.f, 0.f );\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
-       u32 i;\r
-       f32 dot;\r
-       f32 len;\r
-       f32 attenuation;\r
-       sVec4 vp;                       // unit vector vertex to light\r
-       sVec4 lightHalf;        // blinn-phong reflection\r
+       const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();\r
 \r
-       for ( i = 0; i!= LightSpace.Light.size (); ++i )\r
+       if (clipRect)\r
        {\r
-               const SBurningShaderLight &light = LightSpace.Light[i];\r
+               if (!clipRect->isValid())\r
+                       return;\r
 \r
-               if ( !light.LightIsOn )\r
-                       continue;\r
+               //glEnable(GL_SCISSOR_TEST);\r
+               EyeSpace.TL_Flag |= TL_SCISSOR;\r
+               setScissor(clipRect->UpperLeftCorner.X, renderTargetSize.Height - clipRect->LowerRightCorner.Y,\r
+                       clipRect->getWidth(), clipRect->getHeight());\r
+       }\r
 \r
-               // accumulate ambient\r
-               ambient.add ( light.AmbientColor );\r
+       video::SColor alphaTest;\r
+       alphaTest.color = useColor[0].color & useColor[0].color & useColor[0].color & useColor[0].color;\r
 \r
-               switch ( light.Type )\r
-               {\r
-                       case video::ELT_SPOT:\r
-                       case video::ELT_POINT:\r
-                               // surface to light\r
-                               vp.x = light.pos.x - LightSpace.vertex.x;\r
-                               vp.y = light.pos.y - LightSpace.vertex.y;\r
-                               vp.z = light.pos.z - LightSpace.vertex.z;\r
-                               //vp.x = light.pos_objectspace.x - LightSpace.vertex.x;\r
-                               //vp.y = light.pos_objectspace.y - LightSpace.vertex.x;\r
-                               //vp.z = light.pos_objectspace.z - LightSpace.vertex.x;\r
-\r
-                               len = vp.get_length_xyz_square();\r
-                               if ( light.radius < len )\r
-                                       continue;\r
-\r
-                               len = core::reciprocal_squareroot ( len );\r
-\r
-                               // build diffuse reflection\r
-\r
-                               //angle between normal and light vector\r
-                               vp.mul ( len );\r
-                               dot = LightSpace.normal.dot_xyz ( vp );\r
-                               if ( dot < 0.f )\r
-                                       continue;\r
-\r
-                               attenuation = light.constantAttenuation + ( 1.f - ( len * light.linearAttenuation ) );\r
-\r
-                               // diffuse component\r
-                               diffuse.mulAdd ( light.DiffuseColor, 3.f * dot * attenuation );\r
-\r
-                               if ( !(LightSpace.Flags & SPECULAR) )\r
-                                       continue;\r
-\r
-                               // build specular\r
-                               // surface to view\r
-                               lightHalf.x = LightSpace.campos.x - LightSpace.vertex.x;\r
-                               lightHalf.y = LightSpace.campos.y - LightSpace.vertex.y;\r
-                               lightHalf.z = LightSpace.campos.z - LightSpace.vertex.z;\r
-                               lightHalf.normalize_xyz();\r
-                               lightHalf += vp;\r
-                               lightHalf.normalize_xyz();\r
-\r
-                               // specular\r
-                               dot = LightSpace.normal.dot_xyz ( lightHalf );\r
-                               if ( dot < 0.f )\r
-                                       continue;\r
-\r
-                               //specular += light.SpecularColor * ( powf ( Material.org.Shininess ,dot ) * attenuation );\r
-                               specular.mulAdd ( light.SpecularColor, dot * attenuation );\r
-                               break;\r
-\r
-                       case video::ELT_DIRECTIONAL:\r
-\r
-                               //angle between normal and light vector\r
-                               dot = LightSpace.normal.dot_xyz ( light.pos );\r
-                               if ( dot < 0.f )\r
-                                       continue;\r
-\r
-                               // diffuse component\r
-                               diffuse.mulAdd ( light.DiffuseColor, dot );\r
-                               break;\r
-                       default:\r
-                               break;\r
-               }\r
+       //SBlitJob job;\r
+       //transform_for_BlitJob2D(job, Quad2DVertices, renderTargetSize, this);\r
 \r
-       }\r
+       setRenderStates2DMode(alphaTest, (video::ITexture*) texture, useAlphaChannelOfTexture);\r
 \r
-       // sum up lights\r
-       dColor.mulAdd (ambient, Material.AmbientColor );\r
-       dColor.mulAdd (diffuse, Material.DiffuseColor);\r
-       dColor.mulAdd (specular, Material.SpecularColor);\r
+       drawVertexPrimitiveList(Quad2DVertices, 4,\r
+               quad_triangle_indexList, 2,\r
+               EVT_STANDARD, scene::EPT_TRIANGLES, EIT_16BIT);\r
 \r
-       dColor.saturate ( dest->Color[0], vertexargb );\r
-}\r
 \r
-#endif\r
+       if (clipRect)\r
+               EyeSpace.TL_Flag &= ~TL_SCISSOR;\r
 \r
+       setRenderStates3DMode();\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->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 0\r
-               // 2d methods don't use viewPort\r
-               core::position2di dest = destPos;\r
-               core::recti clip=ViewPort;\r
-               if (ViewPort.getSize().Width != ScreenSize.Width)\r
-               {\r
-                       dest.X=ViewPort.UpperLeftCorner.X+core::round32_fast(destPos.X*ViewPort.getWidth()/(f32)ScreenSize.Width);\r
-                       dest.Y=ViewPort.UpperLeftCorner.Y+core::round32_fast(destPos.Y*ViewPort.getHeight()/(f32)ScreenSize.Height);\r
-                       if (clipRect)\r
-                       {\r
-                               clip.constrainTo(*clipRect);\r
-                       }\r
-                       clipRect = &clip;\r
-               }\r
-#endif\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
+//!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
-       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
+       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
-       if (useAlphaChannelOfTexture)\r
-               StretchBlit(BLITTER_TEXTURE_ALPHA_BLEND, RenderTargetSurface, &destRect, &sourceRect,\r
-                           ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0));\r
-       else\r
-               StretchBlit(BLITTER_TEXTURE, RenderTargetSurface, &destRect, &sourceRect,\r
-                           ((CSoftwareTexture2*)texture)->getImage(), (colors ? colors[0].color : 0));\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(BackBuffer, start, end, color );\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
-       BackBuffer->setPixel(x, y, color, true);\r
-}\r
-\r
-\r
-//! draw an 2d rectangle\r
-void CBurningVideoDriver::draw2DRectangle(SColor color, const core::rect<s32>& pos,\r
-                                                                        const core::rect<s32>* clip)\r
-{\r
-       if (clip)\r
-       {\r
-               core::rect<s32> p(pos);\r
-\r
-               p.clipAgainst(*clip);\r
-\r
-               if(!p.isValid())\r
-                       return;\r
-\r
-               drawRectangle(BackBuffer, p, color);\r
-       }\r
-       else\r
-       {\r
-               if(!pos.isValid())\r
-                       return;\r
-\r
-               drawRectangle(BackBuffer, pos, color);\r
-       }\r
+       RenderTargetSurface->setPixel(x, y, color, true);\r
 }\r
 \r
 \r
@@ -1973,13 +3447,13 @@ void CBurningVideoDriver::OnResize(const core::dimension2d<u32>& size)
 {\r
        // make sure width and height are multiples of 2\r
        core::dimension2d<u32> realSize(size);\r
-\r
+/*\r
        if (realSize.Width % 2)\r
                realSize.Width += 1;\r
 \r
        if (realSize.Height % 2)\r
                realSize.Height += 1;\r
-\r
+*/\r
        if (ScreenSize != realSize)\r
        {\r
                if (ViewPort.getWidth() == (s32)ScreenSize.Width &&\r
@@ -2012,164 +3486,73 @@ const core::dimension2d<u32>& CBurningVideoDriver::getCurrentRenderTargetSize()
 }\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
+//! Draws a 3d line.\r
+void CBurningVideoDriver::draw3DLine(const core::vector3df& start,\r
+       const core::vector3df& end, SColor color_start)\r
 {\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-\r
-       core::rect<s32> pos = position;\r
-\r
-       if (clip)\r
-               pos.clipAgainst(*clip);\r
-\r
-       if (!pos.isValid())\r
-               return;\r
-\r
-       const core::dimension2d<s32> renderTargetSize ( ViewPort.getSize() );\r
-\r
-       const s32 xPlus = -(renderTargetSize.Width>>1);\r
-       const f32 xFact = 1.0f / (renderTargetSize.Width>>1);\r
-\r
-       const s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1);\r
-       const f32 yFact = 1.0f / (renderTargetSize.Height>>1);\r
+       SColor color_end = color_start;\r
 \r
-       // fill VertexCache direct\r
-       s4DVertex *v;\r
+       VertexCache.primitiveHasVertex = 2;\r
+       VertexCache.vType = E4VT_LINE;\r
 \r
-       VertexCache.vertexCount = 4;\r
+       s4DVertex* v = Clipper.data;\r
 \r
-       VertexCache.info[0].index = 0;\r
-       VertexCache.info[1].index = 1;\r
-       VertexCache.info[2].index = 2;\r
-       VertexCache.info[3].index = 3;\r
+       transform_calc(ETS_PROJ_MODEL_VIEW);\r
+       const core::matrix4* matrix = Transformation[TransformationStack];\r
+       matrix[ETS_PROJ_MODEL_VIEW].transformVect ( &v[0].Pos.x, start );\r
+       matrix[ETS_PROJ_MODEL_VIEW].transformVect ( &v[2].Pos.x, end );\r
 \r
-       v = &VertexCache.mem.data [ 0 ];\r
-\r
-       v[0].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f );\r
-       v[0].Color[0].setA8R8G8B8 ( colorLeftUp.color );\r
-\r
-       v[2].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.f, 1.f );\r
-       v[2].Color[0].setA8R8G8B8 ( colorRightUp.color );\r
-\r
-       v[4].Pos.set ( (f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f ,1.f );\r
-       v[4].Color[0].setA8R8G8B8 ( colorRightDown.color );\r
-\r
-       v[6].Pos.set ( (f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.f, 1.f );\r
-       v[6].Color[0].setA8R8G8B8 ( colorLeftDown.color );\r
-\r
-       s32 i;\r
-       u32 g;\r
-\r
-       for ( i = 0; i!= 8; i += 2 )\r
-       {\r
-               v[i + 0].flag = clipToFrustumTest ( v + i );\r
-               v[i + 1].flag = 0;\r
-               if ( (v[i].flag & VERTEX4D_INSIDE ) == VERTEX4D_INSIDE )\r
-               {\r
-                       ndc_2_dc_and_project ( v + i + 1, v + i, 2 );\r
-               }\r
-       }\r
-\r
-\r
-       IBurningShader * render;\r
-\r
-       render = BurningShader [ ETR_GOURAUD_ALPHA_NOZ ];\r
-       render->setRenderTarget(RenderTargetSurface, ViewPort);\r
-\r
-       static const s16 indexList[6] = {0,1,2,0,2,3};\r
-\r
-       s4DVertex * face[3];\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+       v[0].Color[0].setA8R8G8B8 ( color_start.color );\r
+       v[2].Color[0].setA8R8G8B8 ( color_end.color );\r
+#endif\r
 \r
-       for ( i = 0; i!= 6; i += 3 )\r
+       u32 i;\r
+       for (i = 0; i < 4; i += sizeof_s4DVertexPairRel)\r
        {\r
-               face[0] = VertexCache_getVertex ( indexList [ i + 0 ] );\r
-               face[1] = VertexCache_getVertex ( indexList [ i + 1 ] );\r
-               face[2] = VertexCache_getVertex ( indexList [ i + 2 ] );\r
-\r
-               // test clipping\r
-               u32 test = face[0]->flag & face[1]->flag & face[2]->flag & VERTEX4D_INSIDE;\r
-\r
-               if ( test == VERTEX4D_INSIDE )\r
-               {\r
-                       render->drawTriangle ( face[0] + 1, face[1] + 1, face[2] + 1 );\r
-                       continue;\r
-               }\r
-               // Todo: all vertices are clipped in 2d..\r
-               // is this true ?\r
-               u32 vOut = 6;\r
-               memcpy ( CurrentOut.data + 0, face[0], sizeof ( s4DVertex ) * 2 );\r
-               memcpy ( CurrentOut.data + 2, face[1], sizeof ( s4DVertex ) * 2 );\r
-               memcpy ( CurrentOut.data + 4, face[2], sizeof ( s4DVertex ) * 2 );\r
-\r
-               vOut = clipToFrustum ( CurrentOut.data, Temp.data, 3 );\r
-               if ( vOut < 3 )\r
-                       continue;\r
-\r
-               vOut <<= 1;\r
-               // to DC Space, project homogenous vertex\r
-               ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );\r
-\r
-               // re-tesselate ( triangle-fan, 0-1-2,0-2-3.. )\r
-               for ( g = 0; g <= vOut - 6; g += 2 )\r
-               {\r
-                       // rasterize\r
-                       render->drawTriangle ( CurrentOut.data + 1, &CurrentOut.data[g + 3], &CurrentOut.data[g + 5] );\r
-               }\r
-\r
+               v[i + 0].flag = (u32)(VertexCache.vSize[VertexCache.vType].Format);\r
+               v[i + 1].flag = v[i + 0].flag;\r
        }\r
-#else\r
-       draw2DRectangle ( colorLeftUp, position, clip );\r
-#endif\r
-}\r
 \r
 \r
-//! Draws a 3d line.\r
-void CBurningVideoDriver::draw3DLine(const core::vector3df& start,\r
-       const core::vector3df& end, SColor color)\r
-{\r
-       Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[0].Pos.x, start );\r
-       Transformation [ ETS_CURRENT].transformVect ( &CurrentOut.data[2].Pos.x, end );\r
-\r
-       u32 g;\r
-       u32 vOut;\r
-\r
-       // no clipping flags\r
-       for ( g = 0; g != CurrentOut.ElementSize; ++g )\r
-       {\r
-               CurrentOut.data[g].flag = 0;\r
-               Temp.data[g].flag = 0;\r
-       }\r
+       size_t g;\r
+       size_t vOut;\r
 \r
        // vertices count per line\r
-       vOut = clipToFrustum ( CurrentOut.data, Temp.data, 2 );\r
-       if ( vOut < )\r
+       vOut = clipToFrustum (VertexCache.primitiveHasVertex);\r
+       if ( vOut < VertexCache.primitiveHasVertex)\r
                return;\r
 \r
-       vOut <<= 1;\r
-\r
-       IBurningShader * line;\r
-       line = BurningShader [ ETR_TEXTURE_GOURAUD_WIRE ];\r
-       line->setRenderTarget(RenderTargetSurface, ViewPort);\r
+       vOut *= sizeof_s4DVertexPairRel;\r
 \r
        // to DC Space, project homogenous vertex\r
-       ndc_2_dc_and_project ( CurrentOut.data + 1, CurrentOut.data, vOut );\r
+       ndc_2_dc_and_project ( v + 1, v, vOut );\r
 \r
        // unproject vertex color\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if 0\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
        for ( g = 0; g != vOut; g+= 2 )\r
        {\r
-               CurrentOut.data[ g + 1].Color[0].setA8R8G8B8 ( color.color );\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);\r
 \r
-       for ( g = 0; g <= vOut - 4; g += )\r
+       for ( g = 0; g <= vOut - 4; g += sizeof_s4DVertexPairRel)\r
        {\r
-               // rasterize\r
-               line->drawLine ( CurrentOut.data + 1, CurrentOut.data + g + 3 );\r
+               shader->drawLine ( v + 1 + g, v + 1 + g + sizeof_s4DVertexPairRel);\r
        }\r
+\r
+       shader->popEdgeTest();\r
+\r
 }\r
 \r
 \r
@@ -2178,20 +3561,22 @@ void CBurningVideoDriver::draw3DLine(const core::vector3df& start,
 const wchar_t* CBurningVideoDriver::getName() const\r
 {\r
 #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
-       return L"Burning's Video 0.49 beautiful";\r
+       return L"Burning's Video 0.51 beautiful";\r
 #elif defined ( BURNINGVIDEO_RENDERER_ULTRA_FAST )\r
-       return L"Burning's Video 0.49 ultra fast";\r
+       return L"Burning's Video 0.51 ultra fast";\r
 #elif defined ( BURNINGVIDEO_RENDERER_FAST )\r
-       return L"Burning's Video 0.49 fast";\r
+       return L"Burning's Video 0.51 fast";\r
+#elif defined ( BURNINGVIDEO_RENDERER_CE )\r
+       return L"Burning's Video 0.51 CE";\r
 #else\r
-       return L"Burning's Video 0.49";\r
+       return L"Burning's Video 0.51";\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-2015";\r
+       return "Burning's Video: Ing. Thomas Alten (c) 2006-2020";\r
 }\r
 \r
 \r
@@ -2209,19 +3594,12 @@ ECOLOR_FORMAT CBurningVideoDriver::getColorFormat() const
 }\r
 \r
 \r
-//! Returns the transformation set by setTransform\r
-const core::matrix4& CBurningVideoDriver::getTransform(E_TRANSFORMATION_STATE state) const\r
-{\r
-       return Transformation[state];\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
 {\r
        IImage* img = createImage(BURNINGSHADER_COLOR_FORMAT, size);\r
-       ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET );\r
+       ITexture* tex = new CSoftwareTexture2(img, name, CSoftwareTexture2::IS_RENDERTARGET,this);\r
        img->drop();\r
        addTexture(tex);\r
        tex->drop();\r
@@ -2234,12 +3612,31 @@ void CBurningVideoDriver::clearBuffers(u16 flag, SColor color, f32 depth, u8 ste
                RenderTargetSurface->fill(color);\r
 \r
        if ((flag & ECBF_DEPTH) && DepthBuffer)\r
-               DepthBuffer->clear();\r
+               DepthBuffer->clear(depth);\r
 \r
        if ((flag & ECBF_STENCIL) && StencilBuffer)\r
-               StencilBuffer->clear();\r
+               StencilBuffer->clear(stencil);\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
@@ -2259,9 +3656,17 @@ IImage* CBurningVideoDriver::createScreenShot(video::ECOLOR_FORMAT format, video
 \r
 ITexture* CBurningVideoDriver::createDeviceDependentTexture(const io::path& name, IImage* image)\r
 {\r
-       CSoftwareTexture2* texture = new CSoftwareTexture2(image, name, (getTextureCreationFlag(ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0) |\r
-               (getTextureCreationFlag(ETCF_ALLOW_NON_POWER_2) ? 0 : CSoftwareTexture2::NP2_SIZE));\r
+       u32 flags =\r
+                 ((TextureCreationFlags & ETCF_CREATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP : 0)\r
+               | ((TextureCreationFlags & ETCF_AUTO_GENERATE_MIP_MAPS) ? CSoftwareTexture2::GEN_MIPMAP_AUTO : 0)\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
@@ -2275,7 +3680,7 @@ ITexture* CBurningVideoDriver::createDeviceDependentTextureCubemap(const io::pat
 //! call.\r
 u32 CBurningVideoDriver::getMaximalPrimitiveCount() const\r
 {\r
-       return 0xFFFFFFFF;\r
+       return 0x7FFFFFFF;\r
 }\r
 \r
 \r
@@ -2285,58 +3690,61 @@ u32 CBurningVideoDriver::getMaximalPrimitiveCount() const
 void CBurningVideoDriver::drawStencilShadowVolume(const core::array<core::vector3df>& triangles, bool zfail, u32 debugDataVisible)\r
 {\r
        const u32 count = triangles.size();\r
-       IBurningShader *shader = BurningShader [ ETR_STENCIL_SHADOW ];\r
-\r
-       CurrentShader = shader;\r
-       shader->setRenderTarget(RenderTargetSurface, ViewPort);\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_LESSEQUAL;\r
-       LightSpace.Flags &= ~VERTEXTRANSFORM;\r
+       Material.org.ZBuffer = ECFN_LESS;\r
+\r
+       CurrentShader = BurningShader[ETR_STENCIL_SHADOW];\r
+\r
+       CurrentShader->setRenderTarget(RenderTargetSurface, ViewPort);\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
-       if (true)// zpass does not work yet\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
-               shader->setParam ( 0, 0 );\r
-               shader->setParam ( 1, 1 );\r
-               shader->setParam ( 2, 0 );\r
-               drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );\r
-               //glStencilOp(GL_KEEP, incr, GL_KEEP);\r
-               //glDrawArrays(GL_TRIANGLES,0,count);\r
+               Material.CullFlag = CULL_BACK | CULL_INVISIBLE;\r
 \r
-               Material.org.BackfaceCulling = false;\r
-               Material.org.FrontfaceCulling = true;\r
-               shader->setParam ( 0, 0 );\r
-               shader->setParam ( 1, 2 );\r
-               shader->setParam ( 2, 0 );\r
-               drawVertexPrimitiveList (triangles.const_pointer(), count, 0, count/3, (video::E_VERTEX_TYPE) 4, scene::EPT_TRIANGLES, (video::E_INDEX_TYPE) 4 );\r
-               //glStencilOp(GL_KEEP, decr, GL_KEEP);\r
-               //glDrawArrays(GL_TRIANGLES,0,count);\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
-               shader->setParam ( 0, 0 );\r
-               shader->setParam ( 1, 0 );\r
-               shader->setParam ( 2, 1 );\r
-               //glStencilOp(GL_KEEP, GL_KEEP, incr);\r
-               //glDrawArrays(GL_TRIANGLES,0,count);\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
-               shader->setParam ( 0, 0 );\r
-               shader->setParam ( 1, 0 );\r
-               shader->setParam ( 2, 2 );\r
-               //glStencilOp(GL_KEEP, GL_KEEP, decr);\r
-               //glDrawArrays(GL_TRIANGLES,0,count);\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
@@ -2351,30 +3759,44 @@ void CBurningVideoDriver::drawStencilShadow(bool clearStencilBuffer, video::SCol
        const u32 h = RenderTargetSurface->getDimension().Height;\r
        const u32 w = RenderTargetSurface->getDimension().Width;\r
        tVideoSample *dst;\r
-       u32 *stencil;\r
-       u32* const stencilBase=(u32*) StencilBuffer->lock();\r
+       const tStencilSample* stencil;\r
+\r
+#if defined(SOFTWARE_DRIVER_2_32BIT)\r
+       const u32 alpha = extractAlpha(leftUpEdge.color);\r
+       const u32 src = leftUpEdge.color;\r
+#else\r
+       const u16 alpha = extractAlpha( leftUpEdge.color ) >> 3;\r
+       const u32 src = video::A8R8G8B8toA1R5G5B5( leftUpEdge.color );\r
+#endif\r
+\r
 \r
        for ( u32 y = 0; y < h; ++y )\r
        {\r
                dst = (tVideoSample*)RenderTargetSurface->getData() + ( y * w );\r
-               stencil =  stencilBase + ( y * w );\r
+               stencil = (tStencilSample*)StencilBuffer->lock() + (y * w);\r
 \r
                for ( u32 x = 0; x < w; ++x )\r
                {\r
-                       if ( stencil[x] > 1 )\r
+                       if ( stencil[x] )\r
                        {\r
-                               dst[x] = PixelBlend32 ( dst[x], leftUpEdge.color );\r
+#if defined(SOFTWARE_DRIVER_2_32BIT)\r
+                               dst[x] = PixelBlend32 ( dst[x], src,alpha );\r
+#else\r
+                               dst[x] = PixelBlend16( dst[x], src, alpha );\r
+#endif\r
                        }\r
                }\r
        }\r
 \r
-       StencilBuffer->clear();\r
+       if ( clearStencilBuffer )\r
+               StencilBuffer->clear(0);\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
+       return core::dimension2du(SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1 << 20,\r
+               SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE ? SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE : 1 << 20);\r
 }\r
 \r
 bool CBurningVideoDriver::queryTextureFormat(ECOLOR_FORMAT format) const\r
@@ -2384,50 +3806,140 @@ bool CBurningVideoDriver::queryTextureFormat(ECOLOR_FORMAT format) const
 \r
 bool CBurningVideoDriver::needsTransparentRenderPass(const irr::video::SMaterial& material) const\r
 {\r
-       return CNullDriver::needsTransparentRenderPass(material) || material.isTransparent();\r
+       return CNullDriver::needsTransparentRenderPass(material) || material.isAlphaBlendOperation(); // || material.isTransparent();\r
 }\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
-} // end namespace video\r
-} // end namespace irr\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
-#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\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
+       )\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
-#if defined(_IRR_WINDOWS_) && defined(_IRR_COMPILE_WITH_BURNINGSVIDEO_)\r
-       #include <windows.h>\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
-struct dreadglobal\r
+void CBurningVideoDriver::setBasicRenderStates(const SMaterial& material,\r
+       const SMaterial& lastMaterial,\r
+       bool resetAllRenderstates)\r
 {\r
-       DWORD dreadid;\r
-       HANDLE dread;\r
-       irr::video::CBurningVideoDriver *driver;\r
-       HANDLE sync;\r
 \r
-       const irr::SIrrlichtCreationParameters* params;\r
-       irr::io::IFileSystem* io;\r
-       irr::video::IImagePresenter* presenter;\r
-};\r
+}\r
 \r
-namespace\r
+//! Return an index constant for the vertex shader based on a name.\r
+s32 CBurningVideoDriver::getVertexShaderConstantID(const c8* name)\r
 {\r
-       dreadglobal burning_dread;\r
+       return -1;\r
 }\r
 \r
-DWORD WINAPI dreadFun( void *p)\r
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const f32* floats, int count)\r
 {\r
-    printf("Hi This is burning dread\n");\r
-       burning_dread.driver = new irr::video::CBurningVideoDriver(*burning_dread.params, burning_dread.io, burning_dread.presenter);\r
+       return true;\r
+}\r
 \r
-       SetEvent (burning_dread.sync );\r
-       while ( 1 )\r
-       {\r
-               Sleep ( 1000 );\r
-       }\r
-       return 0;\r
+bool CBurningVideoDriver::setVertexShaderConstant(s32 index, const s32* ints, int count)\r
+{\r
+       return true;\r
 }\r
 \r
-#endif\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
@@ -2438,21 +3950,9 @@ namespace video
 IVideoDriver* createBurningVideoDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, video::IImagePresenter* presenter)\r
 {\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
-\r
-       #ifdef _IRR_WINDOWS_\r
-       burning_dread.sync = CreateEventA ( 0, 0, 0, "burnevent0" );\r
-       burning_dread.params = &params;\r
-       burning_dread.io = io;\r
-       burning_dread.presenter = presenter;\r
-       burning_dread.dread = CreateThread ( 0, 0, dreadFun, 0, 0, &burning_dread.dreadid );\r
-       WaitForSingleObject (burning_dread.sync, INFINITE );\r
-       return burning_dread.driver;\r
-       #else\r
-       return new CBurningVideoDriver(params, io, presenter);\r
-       #endif\r
-\r
+               return new CBurningVideoDriver(params, io, presenter);\r
        #else\r
-       return 0;\r
+               return 0;\r
        #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
 }\r
 \r
index 3e9d2aaf22d02f737f544b7c0e8ecc0d152bbcc5..803deae6de3ae9df868bbd32a13434375d6d3333 100644 (file)
 #include "irrString.h"\r
 #include "SIrrCreationParameters.h"\r
 \r
+\r
 namespace irr\r
 {\r
 namespace video\r
 {\r
-       class CBurningVideoDriver : public CNullDriver\r
+       class CBurningVideoDriver : public CNullDriver, public IMaterialRendererServices\r
        {\r
        public:\r
 \r
@@ -39,14 +40,15 @@ namespace video
                //! sets a material\r
                virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;\r
 \r
-               virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),\r
-                       f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;\r
+               virtual bool setRenderTargetEx(IRenderTarget* target, u16 clearFlag, SColor clearColor,\r
+                       f32 clearDepth, u8 clearStencil) _IRR_OVERRIDE_;\r
 \r
                //! sets a viewport\r
                virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;\r
+               virtual void setScissor(int x, int y, int width, int height);\r
 \r
-               virtual bool beginScene(u16 clearFlag, SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0,\r
-                       const SExposedVideoData& videoData = SExposedVideoData(), core::rect<s32>* sourceRect = 0) _IRR_OVERRIDE_;\r
+               virtual bool beginScene(u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil,\r
+                       const SExposedVideoData& videoData, core::rect<s32>* sourceRect) _IRR_OVERRIDE_;\r
 \r
                virtual bool endScene() _IRR_OVERRIDE_;\r
 \r
@@ -83,23 +85,44 @@ namespace video
                                const void* indexList, u32 primitiveCount,\r
                                E_VERTEX_TYPE vType, scene::E_PRIMITIVE_TYPE pType, E_INDEX_TYPE iType) _IRR_OVERRIDE_;\r
 \r
+               //! draws a vertex primitive list in 2d\r
+               virtual void 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) _IRR_OVERRIDE_;\r
+\r
+\r
+               //! draws an 2d image\r
+               //virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos, bool useAlphaChannelOfTexture) _IRR_OVERRIDE_;\r
+\r
+               /* NullDriver calls\r
+               draw2DImage(texture, destPos,\r
+                       core::rect<s32>(core::position2d<s32>(0, 0), core::dimension2di(texture->getOriginalSize())),\r
+                       0,\r
+                       SColor(255, 255, 255, 255),\r
+                       useAlphaChannelOfTexture\r
+               */\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
                virtual void draw2DImage(const video::ITexture* texture, const core::position2d<s32>& destPos,\r
                        const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,\r
                        SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;\r
 \r
-       //! Draws a part of the texture into the rectangle.\r
+               //! Draws a part of the texture into the rectangle.\r
                virtual void draw2DImage(const video::ITexture* texture, const core::rect<s32>& destRect,\r
                                const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect = 0,\r
                                const video::SColor* const colors=0, bool useAlphaChannelOfTexture=false) _IRR_OVERRIDE_;\r
 \r
                //! Draws a 3d line.\r
                virtual void draw3DLine(const core::vector3df& start,\r
-                       const core::vector3df& end, SColor color = SColor(255,255,255,255)) _IRR_OVERRIDE_;\r
+                       const core::vector3df& end, SColor color_start) _IRR_OVERRIDE_;\r
 \r
                //! draw an 2d rectangle\r
-               virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,\r
-                       const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;\r
+               //virtual void draw2DRectangle(SColor color, const core::rect<s32>& pos,\r
+               //      const core::rect<s32>* clip = 0) _IRR_OVERRIDE_;\r
+\r
+               /* NullDriver calls\r
+               draw2DRectangle(pos, color, color, color, color, clip);\r
+               */\r
 \r
                //!Draws an 2d rectangle with a gradient.\r
                virtual void draw2DRectangle(const core::rect<s32>& pos,\r
@@ -131,7 +154,7 @@ namespace video
                virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,\r
                        const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;\r
 \r
-               virtual void clearBuffers(u16 flag, SColor color = SColor(255,0,0,0), f32 depth = 1.f, u8 stencil = 0) _IRR_OVERRIDE_;\r
+               virtual void clearBuffers(u16 flag, SColor color, f32 depth, u8 stencil) _IRR_OVERRIDE_;\r
 \r
                //! Returns an image created from the last rendered frame.\r
                virtual IImage* createScreenShot(video::ECOLOR_FORMAT format=video::ECF_UNKNOWN, video::E_RENDER_TARGET target=video::ERT_FRAME_BUFFER) _IRR_OVERRIDE_;\r
@@ -155,6 +178,9 @@ namespace video
                        video::SColor leftDownEdge = video::SColor(0,0,0,0),\r
                        video::SColor rightDownEdge = video::SColor(0,0,0,0)) _IRR_OVERRIDE_;\r
 \r
+               //! Enable the 2d override material\r
+               virtual void enableMaterial2D(bool enable = true) _IRR_OVERRIDE_;\r
+\r
                //! Returns the graphics card vendor name.\r
                virtual core::stringc getVendorInfo() _IRR_OVERRIDE_;\r
 \r
@@ -170,8 +196,70 @@ namespace video
                IDepthBuffer * getDepthBuffer () { return DepthBuffer; }\r
                IStencilBuffer * getStencilBuffer () { return StencilBuffer; }\r
 \r
+               //#define Tweak_Burning\r
+#if defined(Tweak_Burning)\r
+               virtual void postEventFromUser(const void* sevent)  _IRR_OVERRIDE_;\r
+#endif\r
+\r
+               //! Adds a new material renderer to the VideoDriver, using pixel and/or\r
+               //! vertex shaders to render geometry.\r
+               virtual s32 addShaderMaterial(const c8* vertexShaderProgram,\r
+                       const c8* pixelShaderProgram,\r
+                       IShaderConstantSetCallBack* callback,\r
+                       E_MATERIAL_TYPE baseMaterial,\r
+                       s32 userData) _IRR_OVERRIDE_;\r
+\r
+               //! Adds a new material renderer to the VideoDriver, based on a high level shading\r
+               //! language. Currently only HLSL in D3D9 is supported.\r
+               virtual s32 addHighLevelShaderMaterial(\r
+                       const c8* vertexShaderProgram,\r
+                       const c8* vertexShaderEntryPointName = 0,\r
+                       E_VERTEX_SHADER_TYPE vsCompileTarget = EVST_VS_1_1,\r
+                       const c8* pixelShaderProgram = 0,\r
+                       const c8* pixelShaderEntryPointName = 0,\r
+                       E_PIXEL_SHADER_TYPE psCompileTarget = EPST_PS_1_1,\r
+                       const c8* geometryShaderProgram = 0,\r
+                       const c8* geometryShaderEntryPointName = "main",\r
+                       E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,\r
+                       scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,\r
+                       scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,\r
+                       u32 verticesOut = 0,\r
+                       IShaderConstantSetCallBack* callback = 0,\r
+                       E_MATERIAL_TYPE baseMaterial = video::EMT_SOLID,\r
+                       s32 userData = 0) _IRR_OVERRIDE_;\r
+\r
+               //IMaterialRendererService\r
+\r
+               virtual void setBasicRenderStates(const SMaterial& material,\r
+                       const SMaterial& lastMaterial,\r
+                       bool resetAllRenderstates) _IRR_OVERRIDE_;\r
+\r
+               //pass BaseMaterialID\r
+               void setFallback_Material(E_MATERIAL_TYPE fallback_MaterialType);\r
+\r
+               //! Return an index constant for the vertex shader based on a name.\r
+               virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+               virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+               virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+               virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;\r
+               virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;\r
+\r
+               //! Return an index constant for the pixel shader based on a name.\r
+               virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+               virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+               virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+               virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;\r
+               \r
+               virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount) _IRR_OVERRIDE_;\r
+\r
+               //! Get pointer to the IVideoDriver interface\r
+               /** \return Pointer to the IVideoDriver interface */\r
+               virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;\r
+\r
        protected:\r
 \r
+               void saveBuffer();\r
+\r
                //! sets a render target\r
                void setRenderTargetImage(video::CImage* image);\r
 \r
@@ -191,9 +279,6 @@ namespace video
                video::IImage* RenderTargetSurface;\r
                core::dimension2d<u32> RenderTargetSize;\r
 \r
-               //! selects the right triangle renderer based on the render states.\r
-               void setCurrentShader();\r
-\r
                IBurningShader* CurrentShader;\r
                IBurningShader* BurningShader[ETR2_COUNT];\r
 \r
@@ -210,78 +295,89 @@ namespace video
                enum E_TRANSFORMATION_STATE_BURNING_VIDEO\r
                {\r
                        ETS_VIEW_PROJECTION = ETS_COUNT,\r
-                       ETS_CURRENT,\r
-                       ETS_CLIPSCALE,\r
-                       ETS_VIEW_INVERSE,\r
-                       ETS_WORLD_INVERSE,\r
+                       ETS_PROJ_MODEL_VIEW,\r
+                       ETS_MODEL_VIEW,\r
+                       ETS_NORMAL, //3x3 ModelView Tansposed Inverse\r
 \r
-                       ETS_COUNT_BURNING\r
+                       ETS_COUNT_BURNING = 16\r
                };\r
 \r
                enum E_TRANSFORMATION_FLAG\r
                {\r
-                       ETF_IDENTITY = 1,\r
-                       ETF_TEXGEN_CAMERA_NORMAL = 2,\r
-                       ETF_TEXGEN_CAMERA_REFLECTION = 4,\r
+                       ETF_VALID = 1,\r
+                       ETF_IDENTITY = 2,\r
+                       ETF_TEXGEN_CAMERA_SPHERE = 4,\r
+                       ETF_TEXGEN_CAMERA_REFLECTION = 8,\r
+                       ETF_TEXGEN_WRAP = 16,\r
+                       ETF_TEXGEN_MASK = ETF_TEXGEN_CAMERA_SPHERE | ETF_TEXGEN_CAMERA_REFLECTION | ETF_TEXGEN_WRAP\r
                };\r
-               u32 TransformationFlag[ETS_COUNT_BURNING];\r
-               core::matrix4 Transformation[ETS_COUNT_BURNING];\r
+               core::matrix4 Transformation[2][ETS_COUNT_BURNING];\r
+               size_t TransformationFlag[2][ETS_COUNT_BURNING]; // E_TRANSFORMATION_FLAG\r
 \r
-               void getCameraPosWorldSpace ();\r
-               void getLightPosObjectSpace ();\r
+               size_t TransformationStack; // 0 .. 3D , 1 .. 2D\r
 \r
+               void setRenderStates2DMode(const video::SColor& color,video::ITexture* texture,bool useAlphaChannelOfTexture);\r
+               void setRenderStates3DMode();\r
 \r
-               // Vertex Cache\r
-               static const SVSize vSize[];\r
+               //ETS_CLIPSCALE, // moved outside to stay at 16 matrices\r
+               f32 Transformation_ETS_CLIPSCALE[2][4];\r
+               void transform_calc(E_TRANSFORMATION_STATE_BURNING_VIDEO state);\r
+\r
+               //core::recti ViewPort;\r
+               AbsRectangle Scissor;\r
 \r
+               // Vertex Cache\r
                SVertexCache VertexCache;\r
 \r
-               void VertexCache_reset (const void* vertices, u32 vertexCount,\r
+               int VertexCache_reset (const void* vertices, u32 vertexCount,\r
                                        const void* indices, u32 indexCount,\r
                                        E_VERTEX_TYPE vType,scene::E_PRIMITIVE_TYPE pType,\r
                                        E_INDEX_TYPE iType);\r
-               void VertexCache_get ( const s4DVertex ** face );\r
-               void VertexCache_getbypass ( s4DVertex ** face );\r
+               void VertexCache_get (s4DVertexPair* face[4] );\r
 \r
+               void VertexCache_map_source_format();\r
                void VertexCache_fill ( const u32 sourceIndex,const u32 destIndex );\r
-               s4DVertex * VertexCache_getVertex ( const u32 sourceIndex );\r
+               s4DVertexPair* VertexCache_getVertex ( const u32 sourceIndex ) const;\r
 \r
 \r
                // culling & clipping\r
-               u32 clipToHyperPlane ( s4DVertex * dest, const s4DVertex * source, u32 inCount, const sVec4 &plane );\r
-               u32 clipToFrustumTest ( const s4DVertex * v  ) const;\r
-               u32 clipToFrustum ( s4DVertex *source, s4DVertex * temp, const u32 vIn );\r
+               //size_t inline clipToHyperPlane (s4DVertexPair* burning_restrict dest, const s4DVertexPair* burning_restrict source, const size_t inCount, const sVec4 &plane );\r
+               //size_t inline clipToFrustumTest ( const s4DVertex * v  ) const;\r
+               public:\r
+               size_t clipToFrustum( const size_t vIn /*, const size_t clipmask_for_face*/ );\r
+               protected:\r
+\r
+               // holds transformed, clipped vertices for a triangle. triangle expands on clipping\r
+               // Buffer is in in pairs of 4DVertex (0 ... ndc, 1 .. dc and projected)\r
+               SAligned4DVertex Clipper;\r
+               SAligned4DVertex Clipper_temp;\r
 \r
 \r
 #ifdef SOFTWARE_DRIVER_2_LIGHTING\r
+               void lightVertex_eye ( s4DVertex *dest, u32 vertexargb );\r
+#endif\r
 \r
-               void lightVertex ( s4DVertex *dest, u32 vertexargb );\r
                //! Sets the fog mode.\r
                virtual void setFog(SColor color, E_FOG_TYPE fogType, f32 start,\r
                        f32 end, f32 density, bool pixelFog, bool rangeFog) _IRR_OVERRIDE_;\r
-#endif\r
 \r
 \r
-               // holds transformed, clipped vertices\r
-               SAlignedVertex CurrentOut;\r
-               SAlignedVertex Temp;\r
+               void ndc_2_dc_and_project (s4DVertexPair* dest,const s4DVertexPair* source, const size_t vIn ) const;\r
 \r
-               void ndc_2_dc_and_project ( s4DVertex *dest,s4DVertex *source, u32 vIn ) const;\r
-               f32 screenarea ( const s4DVertex *v0 ) const;\r
-               void select_polygon_mipmap ( s4DVertex *source, u32 vIn, u32 tex, const core::dimension2du& texSize ) const;\r
-               f32 texelarea ( const s4DVertex *v0, int tex ) const;\r
+               //const is misleading. **v is const that true, but not *v..\r
+               f32 screenarea_inside (const s4DVertexPair* burning_restrict const face[] ) const;\r
+               s32 lodFactor_inside ( const s4DVertexPair* burning_restrict const face[], const size_t tex, f32 dc_area, f32 lod_bias ) const;\r
+               void select_polygon_mipmap_inside ( s4DVertex* burning_restrict face[], const size_t tex, const CSoftwareTexture2_Bound& b ) const;\r
 \r
+               void getCameraPosWorldSpace();\r
+               SBurningShaderEyeSpace EyeSpace;\r
+               SBurningShaderMaterial Material;\r
 \r
-               void ndc_2_dc_and_project2 ( const s4DVertex **v, const u32 size ) const;\r
-               f32 screenarea2 ( const s4DVertex **v ) const;\r
-               f32 texelarea2 ( const s4DVertex **v, int tex ) const;\r
-               void select_polygon_mipmap2 ( s4DVertex **source, u32 tex, const core::dimension2du& texSize ) const;\r
-\r
+               static const sVec4 NDCPlane[6+2];\r
 \r
-               SBurningShaderLightSpace LightSpace;\r
-               SBurningShaderMaterial Material;\r
+               //! Built-in 2D quad for 2D rendering.\r
+               S3DVertex Quad2DVertices[4];\r
 \r
-               static const sVec4 NDCPlane[6];\r
        };\r
 \r
 } // end namespace video\r
index 44a7e6bef9835b4d38650afc6018f2ba06c051be..b17e462de20e6c7c7513b50494a5df2e7b40acdb 100644 (file)
@@ -9,6 +9,7 @@
 #include "SoftwareDriver2_helper.h"\r
 #include "CSoftwareTexture2.h"\r
 #include "CSoftwareDriver2.h"\r
+#include "CBlit.h"\r
 #include "os.h"\r
 \r
 namespace irr\r
@@ -16,125 +17,204 @@ namespace irr
 namespace video\r
 {\r
 \r
+//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)\r
+void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect, const video::IImage* src, const core::rect<s32>* srcRect, size_t flags);\r
+\r
 //! constructor\r
-CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags)\r
-       : ITexture(name, ETT_2D), MipMapLOD(0), Flags ( flags ), OriginalFormat(video::ECF_UNKNOWN)\r
+CSoftwareTexture2::CSoftwareTexture2(IImage* image, const io::path& name, u32 flags, CBurningVideoDriver* driver)\r
+       : ITexture(name\r
+#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
+               , ETT_2D\r
+#endif\r
+       )\r
+       ,MipMapLOD(0), Flags(flags), Driver(driver)\r
 {\r
        #ifdef _DEBUG\r
        setDebugName("CSoftwareTexture2");\r
        #endif\r
 \r
 #ifndef SOFTWARE_DRIVER_2_MIPMAPPING\r
-       Flags &= ~GEN_MIPMAP;\r
+       Flags &= ~(GEN_MIPMAP| GEN_MIPMAP_AUTO);\r
 #endif\r
-\r
+       //set baseclass properties\r
        DriverType = EDT_BURNINGSVIDEO;\r
        ColorFormat = BURNINGSHADER_COLOR_FORMAT;\r
        IsRenderTarget = (Flags & IS_RENDERTARGET) != 0;\r
-       \r
-       memset32 ( MipMap, 0, sizeof ( MipMap ) );\r
-\r
-       if (image)\r
+       HasMipMaps = (Flags & GEN_MIPMAP) != 0;\r
+       MipMap0_Area[0] = 1;\r
+       MipMap0_Area[1] = 1;\r
+       LodBIAS = 0.75f;\r
+       for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i ) MipMap[i] = 0;\r
+       if (!image) return;\r
+\r
+       OriginalSize = image->getDimension();\r
+       OriginalColorFormat = image->getColorFormat();\r
+\r
+\r
+#if defined(IRRLICHT_sRGB)\r
+       if ( Flags & IMAGE_IS_LINEAR ) image->set_sRGB(0);\r
+#else\r
+       //guessing linear image\r
+       if (name.find("light") >= 0 ||\r
+               name.find("bump") >= 0 ||\r
+               name.find("height") >= 0\r
+               )\r
        {\r
-               bool IsCompressed = false;\r
-\r
-               if (IImage::isCompressedFormat(image->getColorFormat()))\r
-               {\r
-                       os::Printer::log("Texture compression not available.", ELL_ERROR);\r
-                       IsCompressed = true;\r
-               }\r
-\r
-               OriginalSize = image->getDimension();\r
-               OriginalFormat = image->getColorFormat();\r
-\r
-               core::dimension2d<u32> optSize(\r
-                               OriginalSize.getOptimalSize(0 != (Flags & NP2_SIZE),\r
-                               false, true,\r
-                               SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE)\r
-                       );\r
+               Flags |= TEXTURE_IS_LINEAR | IMAGE_IS_LINEAR;\r
+       }\r
+#endif\r
 \r
-               if (OriginalSize == optSize)\r
-               {\r
-                       MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());\r
+       bool isCompressed = IImage::isCompressedFormat(OriginalColorFormat);\r
+       if (isCompressed)\r
+       {\r
+               os::Printer::log("Texture compression not available.", ELL_ERROR);\r
+       }\r
 \r
-                       if (!IsCompressed)\r
-                               image->copyTo(MipMap[0]);\r
-               }\r
-               else\r
+       //visual studio code warning\r
+       u32 maxTexSize = SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE;\r
+       core::dimension2d<u32> optSize( OriginalSize.getOptimalSize(\r
+                       (Flags & ALLOW_NPOT) ? 0 : 1, // requirePowerOfTwo\r
+                       false, // requireSquare\r
+                       (Flags & ALLOW_NPOT) ? 1 : maxTexSize == 0, // larger\r
+                       (Flags & ALLOW_NPOT) ? 0 : maxTexSize // maxValue\r
+               )\r
+       );\r
+\r
+       if (OriginalSize == optSize)\r
+       {\r
+               MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, image->getDimension());\r
+#if defined(IRRLICHT_sRGB)\r
+               MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB()  );\r
+#endif         \r
+               if (!isCompressed)\r
+                       image->copyTo(MipMap[0]);\r
+       }\r
+       else\r
+       {\r
+               char buf[256];\r
+               core::stringw showName ( name );\r
+               snprintf_irr ( buf, sizeof(buf), "Burningvideo: Warning Texture %ls reformat %ux%u,%d -> %ux%u,%d",\r
+                                               showName.c_str(),\r
+                                               OriginalSize.Width, OriginalSize.Height, OriginalColorFormat,\r
+                                               optSize.Width, optSize.Height,BURNINGSHADER_COLOR_FORMAT\r
+                                       );\r
+\r
+               os::Printer::log ( buf, ELL_WARNING );\r
+               MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);\r
+#if defined(IRRLICHT_sRGB)\r
+               MipMap[0]->set_sRGB( (Flags & TEXTURE_IS_LINEAR ) ? 0 : image->get_sRGB()  );\r
+#endif\r
+               if (!isCompressed)\r
                {\r
-                       char buf[256];\r
-                       core::stringw showName ( name );\r
-                       snprintf_irr ( buf, 256, "Burningvideo: Warning Texture %ls reformat %dx%d -> %dx%d,%d",\r
-                                                       showName.c_str(),\r
-                                                       OriginalSize.Width, OriginalSize.Height, optSize.Width, optSize.Height,\r
-                                                       BURNINGSHADER_COLOR_FORMAT\r
-                                               );\r
-\r
-                       OriginalSize = optSize;\r
-                       os::Printer::log ( buf, ELL_WARNING );\r
-                       MipMap[0] = new CImage(BURNINGSHADER_COLOR_FORMAT, optSize);\r
-\r
-                       if (!IsCompressed)\r
-                               image->copyToScalingBoxFilter ( MipMap[0],0, false );\r
+                       //image->copyToScalingBoxFilter ( MipMap[0],0, false );\r
+                       Resample_subSampling(BLITTER_TEXTURE,MipMap[0],0,image,0, Flags);\r
                }\r
-\r
-               Size = MipMap[MipMapLOD]->getDimension();\r
-               Pitch = MipMap[MipMapLOD]->getPitch();\r
-\r
-               OrigImageDataSizeInPixels = (f32) 0.3f * MipMap[0]->getImageDataSizeInPixels();\r
-\r
-               HasMipMaps = (Flags & GEN_MIPMAP) != 0;\r
-\r
-               regenerateMipMapLevels(image->getMipMapsData());\r
+               // if Original Size is used for calculation ( 2D position, font) it will be wrong\r
+               //OriginalSize = optSize;\r
        }\r
+\r
+       //select highest mipmap 0\r
+       regenerateMipMapLevels(image->getMipMapsData());\r
 }\r
 \r
 \r
 //! destructor\r
 CSoftwareTexture2::~CSoftwareTexture2()\r
 {\r
-       for ( s32 i = 0; i!= SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
+       for ( size_t i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
        {\r
                if ( MipMap[i] )\r
+               {\r
                        MipMap[i]->drop();\r
+                       MipMap[i] = 0;\r
+               }\r
        }\r
 }\r
 \r
 \r
+\r
 //! Regenerates the mip map levels of the texture. Useful after locking and\r
 //! modifying the texture\r
+#if !defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
 void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)\r
+#else\r
+void CSoftwareTexture2::regenerateMipMapLevels(void* data)\r
+#endif\r
 {\r
-       if (!hasMipMaps())\r
-               return;\r
-\r
-       s32 i;\r
+       int i;\r
 \r
        // release\r
        for ( i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
        {\r
                if ( MipMap[i] )\r
+               {\r
                        MipMap[i]->drop();\r
+                       MipMap[i] = 0;\r
+               }\r
        }\r
 \r
        core::dimension2d<u32> newSize;\r
-       core::dimension2d<u32> origSize = Size;\r
 \r
-       for (i=1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+       if (HasMipMaps && ( (Flags & GEN_MIPMAP_AUTO) || 0 == data ) )\r
        {\r
-               newSize = MipMap[i-1]->getDimension();\r
-               newSize.Width = core::s32_max ( 1, newSize.Width >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );\r
-               newSize.Height = core::s32_max ( 1, newSize.Height >> SOFTWARE_DRIVER_2_MIPMAPPING_SCALE );\r
-               origSize.Width = core::s32_max(1, origSize.Width >> 1);\r
-               origSize.Height = core::s32_max(1, origSize.Height >> 1);\r
+               //need memory also if autogen mipmap disabled\r
+               for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+               {\r
+                       const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();\r
+                       //isotropic\r
+                       newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);\r
+                       newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);\r
+                       if (upperDim == newSize)\r
+                               break;\r
 \r
-               if (data)\r
+                       MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
+#if defined(IRRLICHT_sRGB)\r
+                       MipMap[i]->set_sRGB(MipMap[i - 1]->get_sRGB());\r
+#endif\r
+                       //MipMap[i]->fill ( 0xFFFF4040 );\r
+                       //MipMap[i-1]->copyToScalingBoxFilter( MipMap[i], 0, false );\r
+                       Resample_subSampling(BLITTER_TEXTURE, MipMap[i], 0, MipMap[0], 0, Flags);\r
+               }\r
+       }\r
+       else if (HasMipMaps && data)\r
+       {\r
+               //deactivated outside mipdata until TA knows how to handle this.\r
+\r
+               //query mipmap dimension\r
+               u8* mip_current = (u8*)data;\r
+               const u8* mip_end = (u8*)data;\r
+\r
+               core::dimension2d<u32> origSize = OriginalSize;\r
+               i = 1;\r
+               do\r
                {\r
-                       if (OriginalFormat != BURNINGSHADER_COLOR_FORMAT)\r
+                       if (origSize.Width > 1) origSize.Width >>= 1;\r
+                       if (origSize.Height > 1) origSize.Height >>= 1;\r
+                       mip_end += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);\r
+                       i += 1;\r
+               } while ((origSize.Width != 1 || origSize.Height != 1) && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX);\r
+\r
+               //TODO: this is not true\r
+               LodBIAS = i*0.75f;\r
+\r
+               origSize = OriginalSize;\r
+               for (i = 1; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX && mip_current < mip_end; ++i)\r
+               {\r
+                       const core::dimension2du& upperDim = MipMap[i - 1]->getDimension();\r
+                       //isotropic\r
+                       newSize.Width = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Width >> 1);\r
+                       newSize.Height = core::s32_max(SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE, upperDim.Height >> 1);\r
+                       if (upperDim == newSize)\r
+                               break;\r
+\r
+                       if (origSize.Width > 1) origSize.Width >>= 1;\r
+                       if (origSize.Height > 1) origSize.Height >>= 1;\r
+\r
+                       if (OriginalColorFormat != BURNINGSHADER_COLOR_FORMAT)\r
                        {\r
-                               IImage* tmpImage = new CImage(OriginalFormat, origSize, data, true, false);\r
+                               IImage* tmpImage = new CImage(OriginalColorFormat, origSize, mip_current, true, false);\r
                                MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
-                               if (origSize==newSize)\r
+                               if (origSize == newSize)\r
                                        tmpImage->copyTo(MipMap[i]);\r
                                else\r
                                        tmpImage->copyToScalingBoxFilter(MipMap[i]);\r
@@ -142,33 +222,121 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* data, u32 layer)
                        }\r
                        else\r
                        {\r
-                               if (origSize==newSize)\r
-                                       MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, data, false);\r
+                               if (origSize == newSize)\r
+                                       MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize, mip_current, false);\r
                                else\r
                                {\r
                                        MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
-                                       IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, data, true, false);\r
+                                       IImage* tmpImage = new CImage(BURNINGSHADER_COLOR_FORMAT, origSize, mip_current, true, false);\r
                                        tmpImage->copyToScalingBoxFilter(MipMap[i]);\r
                                        tmpImage->drop();\r
                                }\r
                        }\r
-                       data = (u8*)data +origSize.getArea()*IImage::getBitsPerPixelFromFormat(OriginalFormat)/8;\r
+                       mip_current += IImage::getDataSizeFromFormat(OriginalColorFormat, origSize.Width, origSize.Height);\r
                }\r
-               else\r
+       }\r
+\r
+\r
+       //visualize mipmap\r
+       for (i=1; i < 0 && i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+       {\r
+/*\r
+               static u32 color[] = { \r
+                       0x30bf7f00,0x3040bf00,0x30bf00bf,0x3000bf00,\r
+                       0x300080bf,0x30bf4000,0x300040bf,0x307f00bf,\r
+                       0x30bf0000,0x3000bfbf,0x304000bf,0x307fbf00,\r
+                       0x8000bf7f,0x80bf0040,0x80bfbf00,0x800000bf\r
+               };\r
+*/\r
+               static u32 color[] = { \r
+                       0xFFFFFFFF,0xFFFF0000,0xFF00FF00,0xFF0000FF,\r
+                       0xFFFFFF00,0xFF00FFFF,0xFFFF00FF,0xFF0000FF,\r
+                       0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFF0000FF,\r
+                       0xFF0000FF,0xFF0000FF,0xFF0000FF,0xFFFF00FF\r
+               };\r
+\r
+               if ( MipMap[i] )\r
                {\r
-                       MipMap[i] = new CImage(BURNINGSHADER_COLOR_FORMAT, newSize);\r
+                       core::rect<s32> p (core::position2di(0,0),MipMap[i]->getDimension());\r
+                       SColor c((color[i & 15] & 0x00FFFFFF) | 0xFF000000);\r
+                       Blit(BLITTER_TEXTURE_ALPHA_COLOR_BLEND, MipMap[i], 0, 0, MipMap[i], &p, c.color);\r
+               }\r
+       }\r
 \r
-                       //static u32 color[] = { 0, 0xFFFF0000, 0xFF00FF00,0xFF0000FF,0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0xFF0F0F0F };\r
-                       MipMap[i]->fill ( 0 );\r
-                       MipMap[0]->copyToScalingBoxFilter( MipMap[i], 0, false );\r
+       //save mipmap chain\r
+       if ( 0 )\r
+       {\r
+               char buf[256];\r
+               const char* name = getName().getPath().c_str();\r
+               int filename = 0;\r
+               //int ext = -1;\r
+               i = 0;\r
+               while (name[i])\r
+               {\r
+                       if (name[i] == '/' || name[i] == '\\') filename = i + 1;\r
+                       //if (name[i] == '.') ext = i;\r
+                       i += 1;\r
+               }\r
+               for (i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i)\r
+               {\r
+                       if (MipMap[i])\r
+                       {\r
+                               snprintf_irr(buf, sizeof(buf),"mip/%s_%02d.png", name + filename,i);\r
+                               Driver->writeImageToFile(MipMap[i], buf);\r
+                       }\r
                }\r
        }\r
+\r
+       calcDerivative();\r
+}\r
+\r
+void CSoftwareTexture2::calcDerivative()\r
+{\r
+       //reset current MipMap\r
+       MipMapLOD = 0;\r
+       if (MipMap[0])\r
+       {\r
+               const core::dimension2du& dim = MipMap[0]->getDimension();\r
+               MipMap0_Area[0] = dim.Width;\r
+               MipMap0_Area[1] = dim.Height; // screensize of a triangle\r
+\r
+               Size = dim; // MipMap[MipMapLOD]->getDimension();\r
+               Pitch = MipMap[MipMapLOD]->getPitch();\r
+       }\r
+\r
+       //preCalc mipmap texel center boundaries\r
+       for ( s32 i = 0; i < SOFTWARE_DRIVER_2_MIPMAPPING_MAX; ++i )\r
+       {\r
+               CSoftwareTexture2_Bound& b = TexBound[i];\r
+               if (MipMap[i])\r
+               {\r
+                       const core::dimension2du& dim = MipMap[i]->getDimension();\r
+                       //f32 u = 1.f / dim.Width;\r
+                       //f32 v = 1.f / dim.Height;\r
+\r
+                       b.w = dim.Width - 1.f;\r
+                       b.h = dim.Height - 1.f;\r
+                       b.cx = 0.f; //u*0.005f;\r
+                       b.cy = 0.f; //v*0.005f;\r
+               }\r
+               else\r
+               {\r
+                       b.w = 0.f;\r
+                       b.h = 0.f;\r
+                       b.cx = 0.f;\r
+                       b.cy = 0.f;\r
+               }\r
+       }\r
+\r
 }\r
 \r
 \r
 /* Software Render Target 2 */\r
 \r
 CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver)\r
+#if defined(PATCH_SUPERTUX_8_0_1_with_1_9_0)\r
+, IRenderTarget(0)\r
+#endif\r
 {\r
        DriverType = EDT_BURNINGSVIDEO;\r
 \r
@@ -216,6 +384,290 @@ ITexture* CSoftwareRenderTarget2::getTexture() const
 }\r
 \r
 \r
+\r
+static const float srgb_8bit_to_linear_float[1 << 8] = {\r
+       0.0f, 3.03527e-4f, 6.07054e-4f, 9.10581e-4f,\r
+       0.001214108f, 0.001517635f, 0.001821162f, 0.0021246888f,\r
+       0.002428216f, 0.002731743f, 0.00303527f, 0.0033465358f,\r
+       0.0036765074f, 0.004024717f, 0.004391442f, 0.0047769537f,\r
+       0.005181517f, 0.005605392f, 0.0060488335f, 0.006512091f,\r
+       0.0069954107f, 0.007499032f, 0.008023193f, 0.008568126f,\r
+       0.009134059f, 0.009721218f, 0.010329823f, 0.010960095f,\r
+       0.011612245f, 0.012286489f, 0.0129830325f, 0.013702083f,\r
+       0.014443845f, 0.015208516f, 0.015996294f, 0.016807377f,\r
+       0.017641956f, 0.018500222f, 0.019382363f, 0.020288564f,\r
+       0.021219011f, 0.022173885f, 0.023153368f, 0.024157634f,\r
+       0.025186861f, 0.026241222f, 0.027320893f, 0.02842604f,\r
+       0.029556835f, 0.030713445f, 0.031896032f, 0.033104766f,\r
+       0.034339808f, 0.035601314f, 0.036889452f, 0.038204372f,\r
+       0.039546236f, 0.0409152f, 0.04231141f, 0.04373503f,\r
+       0.045186203f, 0.046665087f, 0.048171826f, 0.049706567f,\r
+       0.051269464f, 0.05286065f, 0.05448028f, 0.056128494f,\r
+       0.057805438f, 0.059511244f, 0.06124606f, 0.06301002f,\r
+       0.06480327f, 0.066625945f, 0.068478175f, 0.0703601f,\r
+       0.07227185f, 0.07421357f, 0.07618539f, 0.07818743f,\r
+       0.08021983f, 0.082282715f, 0.084376216f, 0.086500466f,\r
+       0.08865559f, 0.09084172f, 0.093058966f, 0.09530747f,\r
+       0.097587354f, 0.09989873f, 0.10224174f, 0.10461649f,\r
+       0.107023105f, 0.10946172f, 0.111932434f, 0.11443538f,\r
+       0.11697067f, 0.119538434f, 0.122138776f, 0.12477182f,\r
+       0.12743768f, 0.13013647f, 0.13286832f, 0.13563333f,\r
+       0.13843162f, 0.14126329f, 0.14412847f, 0.14702727f,\r
+       0.14995979f, 0.15292616f, 0.15592647f, 0.15896083f,\r
+       0.16202939f, 0.1651322f, 0.1682694f, 0.17144111f,\r
+       0.1746474f, 0.17788842f, 0.18116425f, 0.18447499f,\r
+       0.18782078f, 0.19120169f, 0.19461784f, 0.19806932f,\r
+       0.20155625f, 0.20507874f, 0.20863687f, 0.21223076f,\r
+       0.21586053f, 0.21952623f, 0.22322798f, 0.2269659f,\r
+       0.23074007f, 0.23455061f, 0.2383976f, 0.24228115f,\r
+       0.24620135f, 0.2501583f, 0.25415212f, 0.25818288f,\r
+       0.2622507f, 0.26635563f, 0.27049783f, 0.27467734f,\r
+       0.2788943f, 0.28314877f, 0.28744087f, 0.29177067f,\r
+       0.2961383f, 0.3005438f, 0.30498734f, 0.30946895f,\r
+       0.31398875f, 0.3185468f, 0.32314324f, 0.32777813f,\r
+       0.33245155f, 0.33716366f, 0.34191445f, 0.3467041f,\r
+       0.35153264f, 0.35640016f, 0.36130682f, 0.36625263f,\r
+       0.3712377f, 0.37626216f, 0.38132605f, 0.38642946f,\r
+       0.3915725f, 0.39675525f, 0.4019778f, 0.40724024f,\r
+       0.41254264f, 0.4178851f, 0.4232677f, 0.42869052f,\r
+       0.43415368f, 0.4396572f, 0.44520122f, 0.45078582f,\r
+       0.45641103f, 0.46207702f, 0.4677838f, 0.4735315f,\r
+       0.4793202f, 0.48514995f, 0.4910209f, 0.496933f,\r
+       0.5028865f, 0.50888133f, 0.5149177f, 0.5209956f,\r
+       0.52711517f, 0.53327644f, 0.5394795f, 0.5457245f,\r
+       0.55201143f, 0.55834043f, 0.5647115f, 0.57112485f,\r
+       0.57758045f, 0.58407843f, 0.59061885f, 0.5972018f,\r
+       0.60382736f, 0.61049557f, 0.6172066f, 0.62396044f,\r
+       0.63075715f, 0.6375969f, 0.6444797f, 0.65140563f,\r
+       0.65837485f, 0.66538733f, 0.67244315f, 0.6795425f,\r
+       0.6866853f, 0.6938718f, 0.7011019f, 0.7083758f,\r
+       0.71569353f, 0.7230551f, 0.73046076f, 0.73791045f,\r
+       0.74540424f, 0.7529422f, 0.7605245f, 0.76815116f,\r
+       0.7758222f, 0.7835378f, 0.791298f, 0.7991027f,\r
+       0.8069523f, 0.8148466f, 0.82278574f, 0.8307699f,\r
+       0.838799f, 0.8468732f, 0.8549926f, 0.8631572f,\r
+       0.8713671f, 0.8796224f, 0.8879231f, 0.8962694f,\r
+       0.9046612f, 0.91309863f, 0.92158186f, 0.9301109f,\r
+       0.9386857f, 0.9473065f, 0.9559733f, 0.9646863f,\r
+       0.9734453f, 0.9822506f, 0.9911021f, 1.0f,\r
+};\r
+/*\r
+int linear_to_srgb_8bit(const float x) {\r
+       if (x <= 0.f) return 0;\r
+       if (x >= 1.f) return 255;\r
+       const float *table = SRGB_8BIT_TO_LINEAR_FLOAT;\r
+       int y = 0;\r
+       for (int i = 128; i != 0; i >>= 1) {\r
+               if (table[y + i] <= x)\r
+                       y += i;\r
+       }\r
+       if (x - table[y] <= table[y + 1] - x)\r
+               return y;\r
+       else\r
+               return y + 1;\r
+}\r
+*/\r
+\r
+\r
+u32 linear_to_srgb_8bit(const float v)\r
+{\r
+       ieee754 c;\r
+       c.f = v;\r
+       const register size_t x = c.u;\r
+       const u32 *table = (u32*)srgb_8bit_to_linear_float;\r
+       register u32 y = 0;\r
+       y += table[y + 128] <= x ? 128 : 0;\r
+       y += table[y + 64] <= x ? 64 : 0;\r
+       y += table[y + 32] <= x ? 32 : 0;\r
+       y += table[y + 16] <= x ? 16 : 0;\r
+       y += table[y + 8] <= x ? 8 : 0;\r
+       y += table[y + 4] <= x ? 4 : 0;\r
+       y += table[y + 2] <= x ? 2 : 0;\r
+       y += table[y + 1] <= x ? 1 : 0;\r
+\r
+       return y;\r
+}\r
+\r
+// 2D Region half open [x0;x1[\r
+struct absrect2\r
+{\r
+       s32 x0;\r
+       s32 y0;\r
+       s32 x1;\r
+       s32 y1;\r
+};\r
+\r
+static inline int clipTest(absrect2 &o, const core::rect<s32>* a, const absrect2& b)\r
+{\r
+       if (a == 0)\r
+       {\r
+               o.x0 = b.x0;\r
+               o.y0 = b.y0;\r
+               o.x1 = b.x1;\r
+               o.y1 = b.y1;\r
+       }\r
+       else\r
+       {\r
+               o.x0 = core::s32_max(a->UpperLeftCorner.X, b.x0);\r
+               o.x1 = core::s32_min(a->LowerRightCorner.X, b.x1);\r
+               o.y0 = core::s32_max(a->UpperLeftCorner.Y, b.y0);\r
+               o.y1 = core::s32_min(a->LowerRightCorner.Y, b.y1);\r
+       }\r
+       int clipTest = 0;\r
+       clipTest |= o.x0 >= o.x1 ? 1 : 0;\r
+       clipTest |= o.y0 >= o.y1 ? 2 : 0;\r
+       return clipTest;\r
+}\r
+\r
+//! stretches srcRect src to dstRect dst, applying a sliding window box filter in linear color space (sRGB->linear->sRGB)\r
+// todo: texture jumps (mip selection problem)\r
+void Resample_subSampling(eBlitter op, video::IImage* dst, const core::rect<s32>* dstRect,\r
+       const video::IImage* src, const core::rect<s32>* srcRect,size_t flags)\r
+{\r
+       const absrect2 dst_clip = { 0,0,(s32)dst->getDimension().Width,(s32)dst->getDimension().Height };\r
+       absrect2 dc;\r
+       if (clipTest(dc, dstRect, dst_clip)) return;\r
+       const video::ECOLOR_FORMAT dstFormat = dst->getColorFormat();\r
+       u8* dstData = (u8*)dst->getData();\r
+\r
+       const absrect2 src_clip = { 0,0,(s32)src->getDimension().Width,(s32)src->getDimension().Height };\r
+       absrect2 sc;\r
+       if (clipTest(sc, srcRect, src_clip)) return;\r
+       const video::ECOLOR_FORMAT srcFormat = src->getColorFormat();\r
+       const u8* srcData = (u8*)src->getData();\r
+\r
+#if defined(IRRLICHT_sRGB)\r
+       const int dst_sRGB = dst->get_sRGB();\r
+       const int src_sRGB = src->get_sRGB();\r
+#else\r
+       const int dst_sRGB = (flags & CSoftwareTexture2::TEXTURE_IS_LINEAR) ? 0 : 1;\r
+       const int src_sRGB = (flags & CSoftwareTexture2::IMAGE_IS_LINEAR) ? 0 : 1;\r
+#endif\r
+\r
+\r
+\r
+       float scale[2];\r
+       scale[0] = (float)(sc.x1 - sc.x0) / (float)(dc.x1 - dc.x0);\r
+       scale[1] = (float)(sc.y1 - sc.y0) / (float)(dc.y1 - dc.y0);\r
+       const float rs = 1.f / (scale[0] * scale[1]);\r
+\r
+       float sum[4];\r
+       u32 sbgra = 0;\r
+\r
+       float f[4];\r
+       int fi[4];\r
+       f[3] = (float)sc.y0;\r
+       for (int dy = dc.y0; dy < dc.y1; ++dy)\r
+       {\r
+               f[1] = f[3];\r
+               f[3] = sc.y0 + (dy + 1 - dc.y0)*scale[1];\r
+               if (f[3] >= sc.y1) f[3] = sc.y1 - 0.001f; //todo:1.f/dim should be enough\r
+\r
+               f[2] = (float)sc.x0;\r
+               for (int dx = dc.x0; dx < dc.x1; ++dx)\r
+               {\r
+                       f[0] = f[2];\r
+                       f[2] = sc.x0 + (dx + 1 - dc.x0)*scale[0];\r
+                       if (f[2] >= sc.x1) f[2] = sc.x1 - 0.001f;\r
+\r
+                       //accumulate linear color\r
+                       sum[0] = 0.f;\r
+                       sum[1] = 0.f;\r
+                       sum[2] = 0.f;\r
+                       sum[3] = 0.f;\r
+\r
+                       //sample border\r
+                       fi[0] = (int)(f[0]);\r
+                       fi[1] = (int)(f[1]);\r
+                       fi[2] = (int)(f[2]);\r
+                       fi[3] = (int)(f[3]);\r
+\r
+                       float w[2];\r
+                       for (int fy = fi[1]; fy <= fi[3]; ++fy)\r
+                       {\r
+                               w[1] = 1.f;\r
+                               if (fy == fi[1]) w[1] -= f[1] - fy;\r
+                               if (fy == fi[3]) w[1] -= fy + 1 - f[3];\r
+\r
+                               for (int fx = fi[0]; fx <= fi[2]; ++fx)\r
+                               {\r
+                                       w[0] = 1.f;\r
+                                       if (fx == fi[0]) w[0] -= f[0] - fx;\r
+                                       if (fx == fi[2]) w[0] -= fx + 1 - f[2];\r
+\r
+                                       const float ws = w[1] * w[0] * rs;\r
+\r
+                                       switch (srcFormat)\r
+                                       {\r
+                                       case video::ECF_A1R5G5B5: sbgra = video::A1R5G5B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;\r
+                                       case video::ECF_R5G6B5: sbgra = video::R5G6B5toA8R8G8B8(*(u16*)(srcData + (fy*src_clip.x1) * 2 + (fx * 2))); break;\r
+                                       case video::ECF_A8R8G8B8: sbgra = *(u32*)(srcData + (fy*src_clip.x1) * 4 + (fx * 4)); break;\r
+                                       case video::ECF_R8G8B8:\r
+                                       {\r
+                                               const u8* p = srcData + (fy*src_clip.x1) * 3 + (fx * 3);\r
+                                               sbgra = 0xFF000000 | p[0] << 16 | p[1] << 8 | p[2];\r
+                                       } break;\r
+                                       default: break;\r
+                                       }\r
+                                       if (src_sRGB)\r
+                                       {\r
+                                               sum[0] += srgb_8bit_to_linear_float[(sbgra) & 0xFF] * ws;\r
+                                               sum[1] += srgb_8bit_to_linear_float[(sbgra >> 8) & 0xFF] * ws;\r
+                                               sum[2] += srgb_8bit_to_linear_float[(sbgra >> 16) & 0xFF] * ws;\r
+                                               sum[3] += ((sbgra >> 24) & 0xFF) * ws;\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               sum[0] += ((sbgra) & 0xFF) * ws;\r
+                                               sum[1] += ((sbgra >> 8) & 0xFF) * ws;\r
+                                               sum[2] += ((sbgra >> 16) & 0xFF) * ws;\r
+                                               sum[3] += ((sbgra >> 24) & 0xFF) * ws;\r
+                                       }\r
+\r
+                               }\r
+                       }\r
+                       switch (op)\r
+                       {\r
+                       case BLITTER_TEXTURE_ALPHA_BLEND:\r
+                       case BLITTER_TEXTURE_ALPHA_COLOR_BLEND:\r
+                               break;\r
+                       default:\r
+                               break;\r
+                       }\r
+                       if (dst_sRGB)\r
+                       {\r
+                               sbgra = linear_to_srgb_8bit(sum[0]) |\r
+                                       linear_to_srgb_8bit(sum[1]) << 8 |\r
+                                       linear_to_srgb_8bit(sum[2]) << 16 |\r
+                                       (u32)(sum[3]) << 24;\r
+                       }\r
+                       else\r
+                       {\r
+                               sbgra = (u32)(sum[0]) |\r
+                                       (u32)(sum[1]) << 8 |\r
+                                       (u32)(sum[2]) << 16 |\r
+                                       (u32)(sum[3]) << 24;\r
+                       }\r
+                       switch (dstFormat)\r
+                       {\r
+                       case video::ECF_A8R8G8B8: *(u32*)(dstData + (dy*dst_clip.x1) * 4 + (dx * 4)) = sbgra; break;\r
+                       case video::ECF_R8G8B8:\r
+                       {\r
+                               u8* p = dstData + (dy*dst_clip.x1) * 3 + (dx * 3);\r
+                               p[2] = (sbgra) & 0xFF;\r
+                               p[1] = (sbgra >> 8) & 0xFF;\r
+                               p[0] = (sbgra >> 16) & 0xFF;\r
+                       } break;\r
+                       case video::ECF_A1R5G5B5: *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toA1R5G5B5(sbgra); break;\r
+                       case video::ECF_R5G6B5:   *(u16*)(dstData + (dy*dst_clip.x1) * 2 + (dx * 2)) = video::A8R8G8B8toR5G6B5(sbgra); break;\r
+                       default:\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+}\r
+\r
 } // end namespace video\r
 } // end namespace irr\r
 \r
index ac3c1fc5c56ffd374943d11700cc523c7c724ad1..4f6be4867aaf4daf0323e59f06d14c7d18c3aa6f 100644 (file)
@@ -21,6 +21,14 @@ class CBurningVideoDriver;
 /*!\r
        interface for a Video Driver dependent Texture.\r
 */\r
+struct CSoftwareTexture2_Bound\r
+{\r
+       f32 w;  // width - 0.5f;\r
+       f32 h;  // height- 0.5f;\r
+       f32 cx; // texelcenter x 1.f/width*0.5f\r
+       f32 cy; // texelcenter y 1.f/height*0.5f\r
+};\r
+\r
 class CSoftwareTexture2 : public ITexture\r
 {\r
 public:\r
@@ -28,21 +36,34 @@ public:
        //! constructor\r
        enum eTex2Flags\r
        {\r
-               GEN_MIPMAP      = 1,\r
-               IS_RENDERTARGET = 2,\r
-               NP2_SIZE        = 4,\r
+               GEN_MIPMAP                      = 1,            // has mipmaps\r
+               GEN_MIPMAP_AUTO         = 2,            // automatic mipmap generation\r
+               IS_RENDERTARGET         = 4,\r
+               ALLOW_NPOT                      = 8,            //allow non power of two\r
+               IMAGE_IS_LINEAR         = 16,\r
+               TEXTURE_IS_LINEAR       = 32,\r
        };\r
-       CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags);\r
+       CSoftwareTexture2(IImage* surface, const io::path& name, u32 flags /*eTex2Flags*/, CBurningVideoDriver* driver);\r
 \r
        //! destructor\r
        virtual ~CSoftwareTexture2();\r
 \r
+       u32 getMipmapLevel(s32 newLevel) const\r
+       {\r
+               if ( newLevel < 0 ) newLevel = 0;\r
+               else if ( newLevel >= SOFTWARE_DRIVER_2_MIPMAPPING_MAX ) newLevel = SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1;\r
+\r
+               while ( newLevel > 0 && MipMap[newLevel] == 0 ) newLevel -= 1;\r
+               return newLevel;\r
+       }\r
+\r
        //! lock function\r
        virtual void* lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel, u32 layer, E_TEXTURE_LOCK_FLAGS lockFlags = ETLF_FLIP_Y_UP_RTT) _IRR_OVERRIDE_\r
        {\r
                if (Flags & GEN_MIPMAP)\r
                {\r
-                       MipMapLOD = mipmapLevel;\r
+                       //called from outside. must test\r
+                       MipMapLOD = getMipmapLevel(mipmapLevel);\r
                        Size = MipMap[MipMapLOD]->getDimension();\r
                        Pitch = MipMap[MipMapLOD]->getPitch();\r
                }\r
@@ -55,14 +76,19 @@ public:
        {\r
        }\r
 \r
-       //! Returns the size of the largest mipmap.\r
+       //! compare the area drawn with the area of the texture\r
        f32 getLODFactor( const f32 texArea ) const\r
        {\r
-               return OrigImageDataSizeInPixels * texArea;\r
+               return MipMap0_Area[0]* MipMap0_Area[1] * 0.5f * texArea;\r
                //return MipMap[0]->getImageDataSizeInPixels () * texArea;\r
        }\r
 \r
-       //! returns unoptimized surface\r
+       const u32* getMipMap0_Area() const\r
+       {\r
+               return MipMap0_Area;\r
+       }\r
+\r
+       //! returns unoptimized surface (misleading name. burning can scale down originalimage)\r
        virtual CImage* getImage() const\r
        {\r
                return MipMap[0];\r
@@ -74,16 +100,27 @@ public:
                return MipMap[MipMapLOD];\r
        }\r
 \r
+       //precalculated dimx-1/dimx*0.5f\r
+       const CSoftwareTexture2_Bound& getTexBound() const\r
+       {\r
+               return TexBound[MipMapLOD];\r
+       }\r
+\r
        virtual void regenerateMipMapLevels(void* data = 0, u32 layer = 0) _IRR_OVERRIDE_;\r
 \r
+       f32 get_lod_bias() const { return LodBIAS; }\r
 private:\r
-       f32 OrigImageDataSizeInPixels;\r
+       void calcDerivative();\r
 \r
-       CImage * MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];\r
+       //! controls MipmapSelection. relation between drawn area and image size\r
+       u32 MipMapLOD; // 0 .. original Texture pot -SOFTWARE_DRIVER_2_MIPMAPPING_MAX\r
+       u32 Flags; //eTex2Flags\r
+       CBurningVideoDriver* Driver;\r
 \r
-       u32 MipMapLOD;\r
-       u32 Flags;\r
-       ECOLOR_FORMAT OriginalFormat;\r
+       CImage* MipMap[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];\r
+       CSoftwareTexture2_Bound TexBound[SOFTWARE_DRIVER_2_MIPMAPPING_MAX];\r
+       u32 MipMap0_Area[2];\r
+       f32 LodBIAS;\r
 };\r
 \r
 /*!\r
@@ -103,9 +140,9 @@ protected:
        CBurningVideoDriver* Driver;\r
 };\r
 \r
-\r
 } // end namespace video\r
 } // end namespace irr\r
 \r
-#endif\r
+#endif // __C_SOFTWARE_2_TEXTURE_H_INCLUDED__\r
+\r
 \r
index 194cc68bd13380a0a937a9e0adf01bce72797545..d0488b575ec8b4e6512d4ff1ad3bc8ef8552dfbb 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -83,13 +83,11 @@ public:
        CTRGouraud2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       //virtual bool canWireFrame () { return true; }\r
 \r
-\r
-private:\r
-       void scanline_bilinear ();\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
+protected:\r
+       virtual void scanline_bilinear ();\r
 \r
 };\r
 \r
@@ -136,8 +134,8 @@ void CTRGouraud2::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -145,7 +143,7 @@ void CTRGouraud2::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -182,6 +180,7 @@ void CTRGouraud2::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -193,34 +192,31 @@ void CTRGouraud2::scanline_bilinear ()
 #ifdef IPOL_C0\r
        tFixPoint r0, g0, b0;\r
 \r
-#ifdef INVERSE_W\r
-       f32 inversew;\r
-#endif\r
+       f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;\r
 \r
 #endif\r
 \r
        for ( s32 i = 0; i <= dx; ++i )\r
        {\r
+               //if test active only first pixel\r
+               if ( (0 == EdgeTestPass) & i ) break;\r
 #ifdef CMP_Z\r
                if ( line.z[0] < z[i] )\r
 #endif\r
 #ifdef CMP_W\r
-               if ( line.w[0] >= z[i] )\r
+               if (line.w[0] >= z[i] )\r
 #endif\r
 \r
                {\r
 #ifdef IPOL_C0\r
-#ifdef INVERSE_W\r
-                       inversew = core::reciprocal ( line.w[0] );\r
 \r
-                       getSample_color ( r0, g0, b0, line.c[0][0] * inversew );\r
-#else\r
-                       getSample_color ( r0, g0, b0, line.c[0][0] );\r
+#ifdef INVERSE_W\r
+                       inversew = fix_inverse32_color(line.w[0]);\r
 #endif\r
-\r
-                       dst[i] = fix_to_color ( r0, g0, b0 );\r
+                       vec4_to_fix( r0, g0, b0, line.c[0][0],inversew );\r
+                       dst[i] = fix_to_sample( r0, g0, b0 );\r
 #else\r
-                       dst[i] = COLOR_BRIGHT_WHITE;\r
+                       dst[i] = PrimitiveColor;\r
 #endif\r
 \r
 #ifdef WRITE_Z\r
@@ -251,7 +247,7 @@ void CTRGouraud2::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);\r
@@ -262,10 +258,10 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
 \r
+       scan.invDeltaY[0] = reciprocal_edge( ca );\r
+       scan.invDeltaY[1] = reciprocal_edge( ba );\r
+       scan.invDeltaY[2] = reciprocal_edge( cb );\r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
 \r
@@ -351,8 +347,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -421,6 +417,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
 \r
                        // render a scanline\r
                        scanline_bilinear ();\r
+                       if ( EdgeTestPass & edge_test_first_line ) break;\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -454,7 +451,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
        }\r
 \r
        // rasterize lower sub-triangle\r
-       if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+       if (  (f32) 0.0 != scan.invDeltaY[2] )\r
        {\r
                // advance to middle point\r
                if( (f32) 0.0 != scan.invDeltaY[1] )\r
@@ -510,8 +507,8 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -581,6 +578,7 @@ void CTRGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4D
 \r
                        // render a scanline\r
                        scanline_bilinear ();\r
+                       if ( EdgeTestPass & edge_test_first_line ) break;\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -630,6 +628,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver)\r
 {\r
+       // ETR_GOURAUD . no texture\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRGouraud2(driver);\r
        #else\r
index 837ab3e436cc0f24bab26d7ac16e455ab3a86784..dd425f8bed9769c36fcb6812c85b0d130891afa8 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -84,15 +84,12 @@ public:
        CTRGouraudAlpha2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c ) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear ();\r
 \r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
-\r
 };\r
 \r
 //! constructor\r
@@ -142,8 +139,8 @@ void CTRGouraudAlpha2::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -151,7 +148,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -188,6 +185,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -198,9 +196,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
 \r
 #ifdef IPOL_C0\r
 \r
-#ifdef INVERSE_W\r
-       f32 inversew;\r
-#endif\r
+       f32 inversew = FIX_POINT_F32_MUL;\r
 \r
        tFixPoint a0;\r
        tFixPoint r0, g0, b0;\r
@@ -220,22 +216,20 @@ void CTRGouraudAlpha2::scanline_bilinear ()
                {\r
 #ifdef IPOL_C0\r
 #ifdef INVERSE_W\r
-                       inversew = core::reciprocal ( line.w[0] );\r
-\r
-                       getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );\r
-#else\r
-                       getSample_color ( a0, r0, g0, b0, line.c[0][0] );\r
+                       inversew = reciprocal_zero_no ( line.w[0] );\r
 #endif\r
+                       vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );\r
 \r
                        color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
+                       fix_color_norm(a0);\r
                        r2 = r1 + imulFix ( a0, r0 - r1 );\r
                        g2 = g1 + imulFix ( a0, g0 - g1 );\r
                        b2 = b1 + imulFix ( a0, b0 - b1 );\r
 \r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
+                       dst[i] = fix4_to_sample( a0,r2, g2, b2 );\r
 #else\r
-                       dst[i] = COLOR_BRIGHT_WHITE;\r
+                       dst[i] = PrimitiveColor;\r
 #endif\r
 #ifdef WRITE_Z\r
                        z[i] = line.z[0];\r
@@ -265,7 +259,7 @@ void CTRGouraudAlpha2::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -276,9 +270,9 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -365,8 +359,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -524,8 +518,8 @@ void CTRGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -642,6 +636,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver)\r
 {\r
+       // ETR_GOURAUD_ALPHA unused\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRGouraudAlpha2(driver);\r
        #else\r
index b5453df02af24bd0fcf5c798db1ba133eb564291..d921cb03bcddc6c154e6602112150876fcd391b3 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -84,14 +84,11 @@ public:
        CTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle (const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear ();\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
-\r
 };\r
 \r
 //! constructor\r
@@ -138,8 +135,8 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -147,7 +144,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -184,6 +181,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -192,11 +190,10 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
 \r
 \r
 \r
+       f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;\r
+\r
 #ifdef IPOL_C0\r
 \r
-#ifdef INVERSE_W\r
-       f32 inversew;\r
-#endif\r
 \r
        tFixPoint a0;\r
        tFixPoint r0, g0, b0;\r
@@ -224,22 +221,21 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
 \r
 #ifdef IPOL_C0\r
 #ifdef IPOL_W\r
-                       inversew = core::reciprocal ( line.w[0] );\r
-\r
-                       getSample_color ( a0, r0, g0, b0, line.c[0][0] * inversew );\r
-#else\r
-                       getSample_color ( a0, r0, g0, b0, line.c[0][0] );\r
+                       inversew = fix_inverse32_color(line.w[0]);\r
 #endif\r
 \r
+                       vec4_to_fix( a0, r0, g0, b0, line.c[0][0],inversew );\r
+\r
                        color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
+                       fix_color_norm(a0);\r
                        r2 = r1 + imulFix ( a0, r0 - r1 );\r
                        g2 = g1 + imulFix ( a0, g0 - g1 );\r
                        b2 = b1 + imulFix ( a0, b0 - b1 );\r
 \r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
+                       dst[i] = fix_to_sample( r2, g2, b2 );\r
 #else\r
-                       dst[i] = COLOR_BRIGHT_WHITE;\r
+                       dst[i] = PrimitiveColor;\r
 #endif\r
 \r
 \r
@@ -264,7 +260,7 @@ void CTRGouraudAlphaNoZ2::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGouraudAlphaNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -275,9 +271,9 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -363,8 +359,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -522,8 +518,8 @@ void CTRGouraudAlphaNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,c
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -640,6 +636,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver)\r
 {\r
+       //ETR_GOURAUD_ALPHA_NOZ  - draw2DRectangle Gradient\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRGouraudAlphaNoZ2(driver);\r
        #else\r
diff --git a/source/Irrlicht/CTRGouraudNoZ2.cpp b/source/Irrlicht/CTRGouraudNoZ2.cpp
new file mode 100644 (file)
index 0000000..2e0bc39
--- /dev/null
@@ -0,0 +1,641 @@
+// 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 "IBurningShader.h"\r
+\r
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+// compile flag for this file\r
+#undef USE_ZBUFFER\r
+#undef IPOL_Z\r
+#undef CMP_Z\r
+#undef WRITE_Z\r
+\r
+#undef IPOL_W\r
+#undef CMP_W\r
+#undef WRITE_W\r
+\r
+#undef SUBTEXEL\r
+#undef INVERSE_W\r
+\r
+#undef IPOL_C0\r
+#undef IPOL_T0\r
+#undef IPOL_T1\r
+\r
+// define render case\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+\r
+#define USE_ZBUFFER\r
+#define IPOL_W\r
+//#define CMP_W\r
+//#define WRITE_W\r
+\r
+#define IPOL_C0\r
+//#define IPOL_T0\r
+//#define IPOL_T1\r
+\r
+// apply global override\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+       #undef INVERSE_W\r
+#endif\r
+\r
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
+       #undef SUBTEXEL\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+       #undef IPOL_C0\r
+#endif\r
+\r
+#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
+       #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+               #undef IPOL_W\r
+       #endif\r
+       #define IPOL_Z\r
+\r
+       #ifdef CMP_W\r
+               #undef CMP_W\r
+               #define CMP_Z\r
+       #endif\r
+\r
+       #ifdef WRITE_W\r
+               #undef WRITE_W\r
+               #define WRITE_Z\r
+       #endif\r
+\r
+#endif\r
+\r
+\r
+namespace irr\r
+{\r
+\r
+namespace video\r
+{\r
+\r
+class CTRGouraudNoZ2 : public IBurningShader\r
+{\r
+public:\r
+\r
+       //! constructor\r
+       CTRGouraudNoZ2(CBurningVideoDriver* driver);\r
+\r
+       //! draws an indexed triangle list\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual bool canWireFrame () { return true; }\r
+\r
+protected:\r
+       virtual void scanline_bilinear ();\r
+};\r
+\r
+//! constructor\r
+CTRGouraudNoZ2::CTRGouraudNoZ2(CBurningVideoDriver* driver)\r
+: IBurningShader(driver)\r
+{\r
+       #ifdef _DEBUG\r
+       setDebugName("CTRGouraudNoZ2");\r
+       #endif\r
+}\r
+\r
+\r
+\r
+/*!\r
+*/\r
+void CTRGouraudNoZ2::scanline_bilinear ()\r
+{\r
+       tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+       //fp24 *z;\r
+#endif\r
+\r
+       s32 xStart;\r
+       s32 xEnd;\r
+       s32 dx;\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+       f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+       fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+       sVec4 slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+       // apply top-left fill-convention, left\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
+\r
+       dx = xEnd - xStart;\r
+\r
+       if ( dx < 0 )\r
+               return;\r
+\r
+       // slopes\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
+\r
+#ifdef IPOL_Z\r
+       slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+       slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+       slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+       subPixel = ( (f32) xStart ) - line.x[0];\r
+#ifdef IPOL_Z\r
+       line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+       line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+       line.c[0][0] += slopeC * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+       line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+       line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+       dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+       //z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+#endif\r
+\r
+\r
+\r
+#ifdef IPOL_C0\r
+       tFixPoint r0, g0, b0;\r
+\r
+       f32 inversew = FIX_POINT_F32_MUL * COLOR_MAX;\r
+\r
+#endif\r
+\r
+       for ( s32 i = 0; i <= dx; ++i )\r
+       {\r
+               if ( (0 == EdgeTestPass) & i ) break;\r
+\r
+#ifdef CMP_Z\r
+               if ( line.z[0] < z[i] )\r
+#endif\r
+#ifdef CMP_W\r
+               if (line.w[0] >= z[i] )\r
+#endif\r
+\r
+               {\r
+#ifdef IPOL_C0\r
+#ifdef INVERSE_W\r
+                       inversew = fix_inverse32_color(line.w[0]);\r
+#endif\r
+                       vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);\r
+                       dst[i] = fix_to_sample(r0, g0, b0);\r
+#else\r
+                       dst[i] = PrimitiveColor;\r
+#endif\r
+\r
+#ifdef WRITE_Z\r
+                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                       z[i] = line.w[0];\r
+#endif\r
+\r
+               }\r
+\r
+#ifdef IPOL_Z\r
+               line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+               line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+               line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+               line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+               line.t[1][0] += slopeT[1];\r
+#endif\r
+       }\r
+\r
+}\r
+\r
+void CTRGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
+{\r
+       // sort on height, y\r
+       if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);\r
+       if ( a->Pos.y > c->Pos.y ) swapVertexPointer(&a, &c);\r
+       if ( b->Pos.y > c->Pos.y ) swapVertexPointer(&b, &c);\r
+\r
+       const f32 ca = c->Pos.y - a->Pos.y;\r
+       const f32 ba = b->Pos.y - a->Pos.y;\r
+       const f32 cb = c->Pos.y - b->Pos.y;\r
+\r
+       // calculate delta y of the edges\r
+       scan.invDeltaY[0] = reciprocal_edge( ca );\r
+       scan.invDeltaY[1] = reciprocal_edge( ba );\r
+       scan.invDeltaY[2] = reciprocal_edge( cb );\r
+\r
+       if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
+               return;\r
+\r
+       // find if the major edge is left or right aligned\r
+       f32 temp[4];\r
+\r
+       temp[0] = a->Pos.x - c->Pos.x;\r
+       temp[1] = -ca;\r
+       temp[2] = b->Pos.x - a->Pos.x;\r
+       temp[3] = ba;\r
+\r
+       scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;\r
+       scan.right = 1 - scan.left;\r
+\r
+       // calculate slopes for the major edge\r
+       scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];\r
+       scan.x[0] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+       scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];\r
+       scan.z[0] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+       scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
+       scan.w[0] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+       scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+       scan.c[0][0] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+       scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
+       scan.t[0][0] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+       scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];\r
+       scan.t[1][0] = a->Tex[1];\r
+#endif\r
+\r
+       // top left fill convention y run\r
+       s32 yStart;\r
+       s32 yEnd;\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+\r
+       // rasterize upper sub-triangle\r
+       if ( (f32) 0.0 != scan.invDeltaY[1]  )\r
+       {\r
+               // calculate slopes for top edge\r
+               scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
+               scan.x[1] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+               scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];\r
+               scan.z[1] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
+               scan.w[1] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+               scan.c[0][1] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
+               scan.t[0][1] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];\r
+               scan.t[1][1] = a->Tex[1];\r
+#endif\r
+\r
+               // apply top-left fill convention, top part\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+               subPixel = ( (f32) yStart ) - a->Pos.y;\r
+\r
+               // correct to pixel center\r
+               scan.x[0] += scan.slopeX[0] * subPixel;\r
+               scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+               scan.z[0] += scan.slopeZ[0] * subPixel;\r
+               scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.w[0] += scan.slopeW[0] * subPixel;\r
+               scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+               scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+               scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+               // rasterize the edge scanlines\r
+               for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+               {\r
+                       line.x[scan.left] = scan.x[0];\r
+                       line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+                       line.z[scan.left] = scan.z[0];\r
+                       line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       line.w[scan.left] = scan.w[0];\r
+                       line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       line.t[0][scan.left] = scan.t[0][0];\r
+                       line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       line.t[1][scan.left] = scan.t[1][0];\r
+                       line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+                       // render a scanline\r
+                       scanline_bilinear ();\r
+                       if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
+                       scan.x[0] += scan.slopeX[0];\r
+                       scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+                       scan.z[0] += scan.slopeZ[0];\r
+                       scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       scan.w[0] += scan.slopeW[0];\r
+                       scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] += scan.slopeT[0][0];\r
+                       scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] += scan.slopeT[1][0];\r
+                       scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+               }\r
+       }\r
+\r
+       // rasterize lower sub-triangle\r
+       if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+       {\r
+               // advance to middle point\r
+               if( (f32) 0.0 != scan.invDeltaY[1] )\r
+               {\r
+                       temp[0] = b->Pos.y - a->Pos.y;  // dy\r
+\r
+                       scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
+#ifdef IPOL_Z\r
+                       scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_W\r
+                       scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
+#endif\r
+\r
+               }\r
+\r
+               // calculate slopes for bottom edge\r
+               scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];\r
+               scan.x[1] = b->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+               scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];\r
+               scan.z[1] = b->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
+               scan.w[1] = b->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+               scan.c[0][1] = b->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
+               scan.t[0][1] = b->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];\r
+               scan.t[1][1] = b->Tex[1];\r
+#endif\r
+\r
+               // apply top-left fill convention, top part\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+\r
+               subPixel = ( (f32) yStart ) - b->Pos.y;\r
+\r
+               // correct to pixel center\r
+               scan.x[0] += scan.slopeX[0] * subPixel;\r
+               scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+               scan.z[0] += scan.slopeZ[0] * subPixel;\r
+               scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.w[0] += scan.slopeW[0] * subPixel;\r
+               scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+               scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+               scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+               // rasterize the edge scanlines\r
+               for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+               {\r
+                       line.x[scan.left] = scan.x[0];\r
+                       line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+                       line.z[scan.left] = scan.z[0];\r
+                       line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       line.w[scan.left] = scan.w[0];\r
+                       line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       line.t[0][scan.left] = scan.t[0][0];\r
+                       line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       line.t[1][scan.left] = scan.t[1][0];\r
+                       line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+                       // render a scanline\r
+                       scanline_bilinear ();\r
+                       if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
+                       scan.x[0] += scan.slopeX[0];\r
+                       scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+                       scan.z[0] += scan.slopeZ[0];\r
+                       scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       scan.w[0] += scan.slopeW[0];\r
+                       scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] += scan.slopeT[0][0];\r
+                       scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] += scan.slopeT[1][0];\r
+                       scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+               }\r
+       }\r
+\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+namespace irr\r
+{\r
+namespace video\r
+{\r
+\r
+//! creates a flat triangle renderer\r
+IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver)\r
+{\r
+       //ETR_GOURAUD_NOZ - no texture no depth test no depth write\r
+       #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+       return new CTRGouraudNoZ2(driver);\r
+       #else\r
+       return 0;\r
+       #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+\r
+\r
index bc72b75c6cca004811005b799a0ef4fd89c4e3ed..5df81c7a077106105b584aeedc24f80363c171b2 100644 (file)
@@ -21,6 +21,7 @@
 #undef INVERSE_W\r
 \r
 #undef IPOL_C0\r
+#undef IPOL_C1\r
 #undef IPOL_T0\r
 #undef IPOL_T1\r
 #undef IPOL_T2\r
@@ -36,6 +37,7 @@
 #define WRITE_W\r
 \r
 #define IPOL_C0\r
+#define IPOL_C1\r
 #define IPOL_T0\r
 #define IPOL_T1\r
 #define IPOL_L0\r
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+       #undef IPOL_C1\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+       #undef IPOL_L0\r
+#endif\r
+\r
 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
        #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
                #undef IPOL_W\r
@@ -87,14 +97,11 @@ public:
        CTRNormalMap(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
-\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
 \r
 private:\r
-       void scanline_bilinear ();\r
-\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
+       void fragmentShader();\r
 \r
 };\r
 \r
@@ -108,10 +115,13 @@ CTRNormalMap::CTRNormalMap(CBurningVideoDriver* driver)
 }\r
 \r
 \r
+void CTRNormalMap::OnSetMaterial(const SBurningShaderMaterial& material)\r
+{\r
+}\r
 \r
 /*!\r
 */\r
-void CTRNormalMap::scanline_bilinear ()\r
+void CTRNormalMap::fragmentShader()\r
 {\r
        tVideoSample *dst;\r
 \r
@@ -135,18 +145,18 @@ void CTRNormalMap::scanline_bilinear ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 #ifdef IPOL_L0\r
-       sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];\r
+       sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -154,7 +164,7 @@ void CTRNormalMap::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -165,6 +175,9 @@ void CTRNormalMap::scanline_bilinear ()
 #ifdef IPOL_C0\r
        slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
 #endif\r
+#ifdef IPOL_C1\r
+       slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
 #ifdef IPOL_T0\r
        slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
 #endif\r
@@ -189,6 +202,9 @@ void CTRNormalMap::scanline_bilinear ()
 #ifdef IPOL_C0\r
        line.c[0][0] += slopeC[0] * subPixel;\r
 #endif\r
+#ifdef IPOL_C1\r
+       line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
 #ifdef IPOL_T0\r
        line.t[0][0] += slopeT[0] * subPixel;\r
 #endif\r
@@ -203,6 +219,7 @@ void CTRNormalMap::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -210,25 +227,33 @@ void CTRNormalMap::scanline_bilinear ()
 #endif\r
 \r
 \r
-       f32 inversew;\r
+       f32 inversew = FIX_POINT_F32_MUL;\r
 \r
-       tFixPoint tx0, tx1;\r
-       tFixPoint ty0, ty1;\r
+       tFixPoint tx0, ty0;\r
+\r
+#ifdef IPOL_T1\r
+       tFixPoint tx1, ty1;\r
+#endif\r
 \r
        tFixPoint r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
        tFixPoint r2, g2, b2;\r
 \r
+#ifdef IPOL_L0\r
        tFixPoint lx, ly, lz;\r
-       tFixPoint ndotl;\r
-\r
-       sVec3 light;\r
+#endif\r
+       tFixPoint ndotl = FIX_POINT_ONE;\r
 \r
 \r
 #ifdef IPOL_C0\r
-       tFixPoint r3, g3, b3;\r
+       tFixPoint a3,r3, g3, b3;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+       tFixPoint aFog = FIX_POINT_ONE;\r
 #endif\r
 \r
+\r
        for ( s32 i = 0; i <= dx; i++ )\r
        {\r
 #ifdef CMP_Z\r
@@ -240,94 +265,100 @@ void CTRNormalMap::scanline_bilinear ()
                {\r
 #ifdef INVERSE_W\r
                        inversew = fix_inverse32 ( line.w[0] );\r
-\r
-                       tx0 = tofix ( line.t[0][0].x,inversew);\r
-                       ty0 = tofix ( line.t[0][0].y,inversew);\r
-                       tx1 = tofix ( line.t[1][0].x,inversew);\r
-                       ty1 = tofix ( line.t[1][0].y,inversew);\r
-\r
-\r
-#ifdef IPOL_C0\r
-                       r3 = tofix ( line.c[0][0].y ,inversew );\r
-                       g3 = tofix ( line.c[0][0].z ,inversew );\r
-                       b3 = tofix ( line.c[0][0].w ,inversew );\r
 #endif\r
 \r
-#else\r
-                       inversew = FIX_POINT_F32_MUL;\r
-                       tx0 = tofix(line.t[0][0].x, inversew);\r
-                       ty0 = tofix(line.t[0][0].y, inversew);\r
-                       tx1 = tofix(line.t[1][0].x, inversew);\r
-                       ty1 = tofix(line.t[1][0].y, inversew);\r
-\r
 #ifdef IPOL_C0\r
-                       r3 = tofix ( line.c[0][0].y );\r
-                       g3 = tofix ( line.c[0][0].z );\r
-                       b3 = tofix ( line.c[0][0].w );\r
+               //vertex alpha blend ( and omit depthwrite ,hacky..)\r
+               a3 = tofix(line.c[0][0].x, inversew);\r
+               if (a3 + 2 >= FIX_POINT_ONE)\r
+               {\r
+#ifdef WRITE_Z\r
+                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                       z[i] = line.w[0];\r
+#endif\r
+               }\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       //complete inside fog\r
+                       if (TL_Flag & TL_FOG)\r
+                       {\r
+                               aFog = tofix(line.c[1][0].a, inversew);\r
+                               if (aFog <= 0)\r
+                               {\r
+                                       dst[i] = fog_color_sample;\r
+                                       continue;\r
+                               }\r
+                       }\r
 #endif\r
+\r
+                       tx0 = tofix ( line.t[0][0].x,inversew);\r
+                       ty0 = tofix ( line.t[0][0].y,inversew);\r
+                       tx1 = tofix ( line.t[1][0].x,inversew);\r
+                       ty1 = tofix ( line.t[1][0].y,inversew);\r
+\r
+                       // diffuse map\r
                        getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
 \r
-                       // normal map\r
+                       // normal map ( same texcoord0 but different mipmapping)\r
                        getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );\r
 \r
                        r1 = ( r1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);\r
                        g1 = ( g1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);\r
                        b1 = ( b1 - FIX_POINT_HALF_COLOR) >> (COLOR_MAX_LOG2-1);\r
 \r
-/*\r
-                       sVec3 l = line.l[0][0] * inversew;\r
-                       l.setLength( 2.f );\r
-\r
-                       lx = tofix ( l.x - 0.5f );\r
-                       ly = tofix ( l.y - 0.5f );\r
-                       lz = tofix ( l.z - 0.5f );\r
-*/\r
-\r
+#ifdef IPOL_L0\r
                        lx = tofix ( line.l[0][0].x, inversew );\r
                        ly = tofix ( line.l[0][0].y, inversew );\r
                        lz = tofix ( line.l[0][0].z, inversew );\r
 \r
                        // DOT 3 Normal Map light in tangent space\r
-                       ndotl = saturateFix ( FIX_POINT_HALF_COLOR +  (( imulFix ( r1, lx ) + imulFix ( g1, ly ) + imulFix ( b1, lz ) ) << (COLOR_MAX_LOG2-1)) );\r
+                       //max(dot(LightVector, Normal), 0.0);\r
+                       ndotl = clampfix_mincolor( (imulFix_simple(r1,lx) + imulFix_simple(g1,ly) + imulFix_simple(b1,lz) )  );\r
+#endif\r
 \r
 #ifdef IPOL_C0\r
 \r
-                       // N . L\r
-                       r2 = imulFix ( imulFix_tex1 ( r0, ndotl ), r3 );\r
-                       g2 = imulFix ( imulFix_tex1 ( g0, ndotl ), g3 );\r
-                       b2 = imulFix ( imulFix_tex1 ( b0, ndotl ), b3 );\r
-\r
-/*\r
-                       // heightmap: (1 - neu ) + alt - 0.5, on_minus_srcalpha + add signed\r
-                       // emboss bump map\r
-                       a4 -= a1;\r
-                       r2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( r0 + a4, r3 ) ) );\r
-                       g2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( g0 + a4, g3 ) ) );\r
-                       b2 = clampfix_maxcolor ( clampfix_mincolor ( imulFix ( b0 + a4, b3 ) ) );\r
-*/\r
+                       //LightColor[0]\r
+                       r3 = tofix(line.c[0][0].y, inversew);\r
+                       g3 = tofix(line.c[0][0].z, inversew);\r
+                       b3 = tofix(line.c[0][0].w, inversew);\r
+\r
+                       // Lambert * LightColor[0] * Diffuse Texture;\r
+                       r2 = imulFix (imulFix_simple( r3, ndotl ), r0 );\r
+                       g2 = imulFix (imulFix_simple( g3, ndotl ), g0 );\r
+                       b2 = imulFix (imulFix_simple( b3, ndotl ), b0 );\r
+\r
+                       //vertex alpha blend ( and omit depthwrite ,hacky..)\r
+                       if (a3 + 2 < FIX_POINT_ONE)\r
+                       {\r
+                               color_to_fix(r1, g1, b1, dst[i]);\r
+                               r2 = r1 + imulFix(a3, r2 - r1);\r
+                               g2 = g1 + imulFix(a3, g2 - g1);\r
+                               b2 = b1 + imulFix(a3, b2 - b1);\r
+                       }\r
+\r
+#ifdef IPOL_C1\r
+                       //mix with distance\r
+                       if (aFog < FIX_POINT_ONE)\r
+                       {\r
+                               r2 = fog_color[1] + imulFix(aFog, r2 - fog_color[1]);\r
+                               g2 = fog_color[2] + imulFix(aFog, g2 - fog_color[2]);\r
+                               b2 = fog_color[3] + imulFix(aFog, b2 - fog_color[3]);\r
+                       }\r
+#endif\r
+                       dst[i] = fix_to_sample(r2, g2, b2);\r
+\r
 \r
-/*\r
-                       r2 = clampfix_maxcolor ( imulFix_tex1 ( r2, r1 ) );\r
-                       g2 = clampfix_maxcolor ( imulFix_tex1 ( g2, g1 ) );\r
-                       b2 = clampfix_maxcolor ( imulFix_tex1 ( b2, b1 ) );\r
-*/\r
 #else\r
-                       r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );\r
-                       g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );\r
-                       b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );\r
+                       r2 = imulFix_tex4 ( r0, r1 );\r
+                       g2 = imulFix_tex4 ( g0, g1 );\r
+                       b2 = imulFix_tex4 ( b0, b1 );\r
+                       dst[i] = fix_to_sample(r2, g2, b2);\r
 #endif\r
 \r
-\r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
-\r
-#ifdef WRITE_Z\r
-                       z[i] = line.z[0];\r
-#endif\r
-#ifdef WRITE_W\r
-                       z[i] = line.w[0];\r
-#endif\r
                }\r
 \r
 #ifdef IPOL_Z\r
@@ -339,6 +370,9 @@ void CTRNormalMap::scanline_bilinear ()
 #ifdef IPOL_C0\r
                line.c[0][0] += slopeC[0];\r
 #endif\r
+#ifdef IPOL_C1\r
+               line.c[1][0] += slopeC[1];\r
+#endif\r
 #ifdef IPOL_T0\r
                line.t[0][0] += slopeT[0];\r
 #endif\r
@@ -355,7 +389,7 @@ void CTRNormalMap::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRNormalMap::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -366,9 +400,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
                return;\r
@@ -403,6 +437,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
        scan.c[0][0] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+       scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+       scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
        scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
        scan.t[0][0] = a->Tex[0];\r
@@ -433,7 +472,6 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
 \r
 \r
        // rasterize upper sub-triangle\r
-       //if ( (f32) 0.0 != scan.invDeltaY[1]  )\r
        if ( F32_GREATER_0 ( scan.invDeltaY[1] )  )\r
        {\r
                // calculate slopes for top edge\r
@@ -455,6 +493,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                scan.c[0][1] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+               scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
                scan.t[0][1] = a->Tex[0];\r
@@ -476,8 +519,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -501,6 +544,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -544,6 +592,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -565,7 +618,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
 #endif\r
 \r
                        // render a scanline\r
-                       scanline_bilinear ();\r
+                       fragmentShader ();\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -585,6 +638,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
@@ -609,11 +667,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
        }\r
 \r
        // rasterize lower sub-triangle\r
-       //if ( (f32) 0.0 != scan.invDeltaY[2] )\r
        if ( F32_GREATER_0 ( scan.invDeltaY[2] )  )\r
        {\r
                // advance to middle point\r
-               //if( (f32) 0.0 != scan.invDeltaY[1] )\r
                if ( F32_GREATER_0 ( scan.invDeltaY[1] )  )\r
                {\r
                        temp[0] = b->Pos.y - a->Pos.y;  // dy\r
@@ -628,6 +684,9 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
 #ifdef IPOL_C0\r
                        scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
 #endif\r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
 #endif\r
@@ -638,7 +697,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                        scan.t[2][0] = a->Tex[2] + scan.slopeT[2][0] * temp[0];\r
 #endif\r
 #ifdef IPOL_L0\r
-                       scan.l[0][0] = a->LightTangent[0] + scan.slopeL[0][0] * temp[0];\r
+                       scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];\r
 #endif\r
 \r
                }\r
@@ -662,6 +721,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                scan.c[0][1] = b->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+               scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
                scan.t[0][1] = b->Tex[0];\r
@@ -683,8 +747,8 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -709,6 +773,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -752,6 +821,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -773,7 +847,7 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
 #endif\r
 \r
                        // render a scanline\r
-                       scanline_bilinear ();\r
+                       fragmentShader();\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -793,6 +867,11 @@ void CTRNormalMap::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
index 02ed525da67d7f6c389b04cf60239ae6f564fba0..82b5ed3d1ca10d1abcab84f30b9d29a64ad3da43 100644 (file)
@@ -47,7 +47,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -84,19 +84,10 @@ public:
        CTRStencilShadow(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
-       virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 private:\r
-       // fragment shader\r
-       typedef void (CTRStencilShadow::*tFragmentShader) ();\r
-       void fragment_zfail_decr ();\r
-       void fragment_zfail_incr ();\r
-\r
-       tFragmentShader fragmentShader;\r
-\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
+       void fragmentShader();\r
 \r
 };\r
 \r
@@ -112,36 +103,14 @@ CTRStencilShadow::CTRStencilShadow(CBurningVideoDriver* driver)
 \r
 /*!\r
 */\r
-void CTRStencilShadow::setParam ( u32 index, f32 value)\r
-{\r
-       u32 val = (u32) value;\r
-\r
-       // glStencilOp (fail,zfail,zpass\r
-       if ( index == 1 && val == 1 )\r
-       {\r
-               fragmentShader = &CTRStencilShadow::fragment_zfail_incr;\r
-       }\r
-       else\r
-       if ( index == 1 && val == 2 )\r
-       {\r
-               fragmentShader = &CTRStencilShadow::fragment_zfail_decr;\r
-       }\r
-}\r
-\r
-/*!\r
-*/\r
-void CTRStencilShadow::fragment_zfail_decr ()\r
+void CTRStencilShadow::fragmentShader()\r
 {\r
-       if (!Stencil)\r
-               return;\r
-       //tVideoSample *dst;\r
-\r
 #ifdef USE_ZBUFFER\r
        fp24 *z;\r
 #endif\r
 \r
 #ifdef USE_SBUFFER\r
-       u32 *stencil;\r
+       tStencilSample *stencil;\r
 #endif\r
 \r
        s32 xStart;\r
@@ -158,27 +127,19 @@ void CTRStencilShadow::fragment_zfail_decr ()
 #ifdef IPOL_W\r
        fp24 slopeW;\r
 #endif\r
-#ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
-#endif\r
-#ifdef IPOL_T0\r
-       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
-#endif\r
-#ifdef IPOL_L0\r
-       sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];\r
-#endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
-\r
        if ( dx < 0 )\r
                return;\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+\r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -186,21 +147,6 @@ void CTRStencilShadow::fragment_zfail_decr ()
 #ifdef IPOL_W\r
        slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
 #endif\r
-#ifdef IPOL_C0\r
-       slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T0\r
-       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T1\r
-       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T2\r
-       slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_L0\r
-       slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;\r
-#endif\r
 \r
 #ifdef SUBTEXEL\r
        subPixel = ( (f32) xStart ) - line.x[0];\r
@@ -210,23 +156,8 @@ void CTRStencilShadow::fragment_zfail_decr ()
 #ifdef IPOL_W\r
        line.w[0] += slopeW * subPixel;\r
 #endif\r
-#ifdef IPOL_C0\r
-       line.c[0][0] += slopeC[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T0\r
-       line.t[0][0] += slopeT[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T1\r
-       line.t[1][0] += slopeT[1] * subPixel;\r
 #endif\r
-#ifdef IPOL_T2\r
-       line.t[2][0] += slopeT[2] * subPixel;\r
-#endif\r
-#ifdef IPOL_L0\r
-       line.l[0][0] += slopeL[0] * subPixel;\r
-#endif\r
-#endif\r
-\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        //dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -234,185 +165,43 @@ void CTRStencilShadow::fragment_zfail_decr ()
 #endif\r
 \r
 #ifdef USE_SBUFFER\r
-       stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+       stencil = (tStencilSample*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 #endif\r
 \r
 \r
 #ifdef INVERSE_W\r
-       f32 inversew;\r
-#endif\r
-\r
-\r
-#ifdef IPOL_C0\r
-       tFixPoint r3, g3, b3;\r
+       f32 inversew = FIX_POINT_F32_MUL;\r
 #endif\r
 \r
-       for ( s32 i = 0; i <= dx; i++ )\r
+       s32 i;\r
+       for (i = 0; i <= dx; i++)\r
        {\r
 #ifdef CMP_Z\r
-               if ( line.z[0] < z[i] )\r
+               if (line.z[0] < z[i])\r
 #endif\r
 #ifdef CMP_W\r
-               if ( line.w[0] < z[i] )\r
+               if (line.w[0] > z[i])\r
 #endif\r
                {\r
-                       // zfail\r
-                       stencil[i] -= 1;\r
+                       // zpass\r
+                       switch (stencilOp[2])\r
+                       {\r
+                       case StencilOp_INCR: stencil[i] += 1; break;\r
+                       case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;\r
+                       default:\r
+                       case StencilOp_KEEP: break;\r
+                       }\r
                }\r
-\r
-#ifdef IPOL_Z\r
-               line.z[0] += slopeZ;\r
-#endif\r
-#ifdef IPOL_W\r
-               line.w[0] += slopeW;\r
-#endif\r
-#ifdef IPOL_C0\r
-               line.c[0][0] += slopeC[0];\r
-#endif\r
-#ifdef IPOL_T0\r
-               line.t[0][0] += slopeT[0];\r
-#endif\r
-#ifdef IPOL_T1\r
-               line.t[1][0] += slopeT[1];\r
-#endif\r
-#ifdef IPOL_T2\r
-               line.t[2][0] += slopeT[2];\r
-#endif\r
-#ifdef IPOL_L0\r
-               line.l[0][0] += slopeL[0];\r
-#endif\r
-       }\r
-}\r
-\r
-/*!\r
-*/\r
-void CTRStencilShadow::fragment_zfail_incr()\r
-{\r
-       if (!Stencil)\r
-               return;\r
-       //tVideoSample *dst;\r
-\r
-#ifdef USE_ZBUFFER\r
-       fp24 *z;\r
-#endif\r
-\r
-#ifdef USE_SBUFFER\r
-       u32 *stencil;\r
-#endif\r
-\r
-       s32 xStart;\r
-       s32 xEnd;\r
-       s32 dx;\r
-\r
-\r
-#ifdef SUBTEXEL\r
-       f32 subPixel;\r
-#endif\r
-\r
-#ifdef IPOL_Z\r
-       f32 slopeZ;\r
-#endif\r
-#ifdef IPOL_W\r
-       fp24 slopeW;\r
-#endif\r
-#ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
-#endif\r
-#ifdef IPOL_T0\r
-       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
-#endif\r
-#ifdef IPOL_L0\r
-       sVec3 slopeL[BURNING_MATERIAL_MAX_TANGENT];\r
-#endif\r
-\r
-       // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
-\r
-       dx = xEnd - xStart;\r
-\r
-       if ( dx < 0 )\r
-               return;\r
-\r
-       // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
-\r
-#ifdef IPOL_Z\r
-       slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_W\r
-       slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_C0\r
-       slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T0\r
-       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T1\r
-       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_T2\r
-       slopeT[2] = (line.t[2][1] - line.t[2][0]) * invDeltaX;\r
-#endif\r
-#ifdef IPOL_L0\r
-       slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;\r
-#endif\r
-\r
-#ifdef SUBTEXEL\r
-       subPixel = ( (f32) xStart ) - line.x[0];\r
-#ifdef IPOL_Z\r
-       line.z[0] += slopeZ * subPixel;\r
-#endif\r
-#ifdef IPOL_W\r
-       line.w[0] += slopeW * subPixel;\r
-#endif\r
-#ifdef IPOL_C0\r
-       line.c[0][0] += slopeC[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T0\r
-       line.t[0][0] += slopeT[0] * subPixel;\r
-#endif\r
-#ifdef IPOL_T1\r
-       line.t[1][0] += slopeT[1] * subPixel;\r
-#endif\r
-#ifdef IPOL_T2\r
-       line.t[2][0] += slopeT[2] * subPixel;\r
-#endif\r
-#ifdef IPOL_L0\r
-       line.l[0][0] += slopeL[0] * subPixel;\r
-#endif\r
-#endif\r
-\r
-       //dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
-\r
-#ifdef USE_ZBUFFER\r
-       z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
-#endif\r
-\r
-#ifdef USE_SBUFFER\r
-       stencil = (u32*) Stencil->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
-#endif\r
-\r
-#ifdef INVERSE_W\r
-       f32 inversew;\r
-#endif\r
-\r
-#ifdef IPOL_C0\r
-       tFixPoint r3, g3, b3;\r
-#endif\r
-\r
-       for ( s32 i = 0; i <= dx; i++ )\r
-       {\r
-#ifdef CMP_Z\r
-               if ( line.z[0] < z[i] )\r
-#endif\r
-#ifdef CMP_W\r
-               if ( line.w[0] < z[i] )\r
-#endif\r
+               else\r
                {\r
                        // zfail\r
-                       stencil[i] += 1;\r
+                       switch (stencilOp[1])\r
+                       {\r
+                       case StencilOp_INCR: stencil[i] += 1; break;\r
+                       case StencilOp_DECR: stencil[i] -= 1; break;// core::s32_max(0, stencil[i] - 1); break;\r
+                       default:\r
+                       case StencilOp_KEEP: break;\r
+                       }\r
                }\r
 \r
 #ifdef IPOL_Z\r
@@ -420,26 +209,13 @@ void CTRStencilShadow::fragment_zfail_incr()
 #endif\r
 #ifdef IPOL_W\r
                line.w[0] += slopeW;\r
-#endif\r
-#ifdef IPOL_C0\r
-               line.c[0][0] += slopeC[0];\r
-#endif\r
-#ifdef IPOL_T0\r
-               line.t[0][0] += slopeT[0];\r
-#endif\r
-#ifdef IPOL_T1\r
-               line.t[1][0] += slopeT[1];\r
-#endif\r
-#ifdef IPOL_T2\r
-               line.t[2][0] += slopeT[2];\r
-#endif\r
-#ifdef IPOL_L0\r
-               line.l[0][0] += slopeL[0];\r
 #endif\r
        }\r
+\r
 }\r
 \r
-void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+\r
+void CTRStencilShadow::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -450,9 +226,9 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
                return;\r
@@ -516,7 +292,6 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
 #endif\r
 \r
        // rasterize upper sub-triangle\r
-       //if ( (f32) 0.0 != scan.invDeltaY[1]  )\r
        if ( F32_GREATER_0 ( scan.invDeltaY[1] )  )\r
        {\r
                // calculate slopes for top edge\r
@@ -559,8 +334,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -648,7 +423,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
 #endif\r
 \r
                        // render a scanline\r
-                       (this->*fragmentShader) ();\r
+                       fragmentShader ();\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -766,8 +541,8 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -856,7 +631,7 @@ void CTRStencilShadow::drawTriangle ( const s4DVertex *a,const s4DVertex *b,cons
 #endif\r
 \r
                        // render a scanline\r
-                       (this->*fragmentShader) ();\r
+                       fragmentShader ();\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -915,6 +690,7 @@ namespace video
 //! creates a triangle renderer\r
 IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver)\r
 {\r
+       //ETR_STENCIL_SHADOW\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRStencilShadow(driver);\r
        #else\r
index e3ba07913dffcb81571cb3469006916a4a74b91a..da178eb19ee98be9127412e231647285ab77f2be 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -76,19 +76,32 @@ namespace irr
 namespace video\r
 {\r
 \r
-class CTRTextureBlend : public IBurningShader\r
-{\r
-public:\r
+       class CTRTextureBlend : public IBurningShader\r
+       {\r
+       public:\r
 \r
-       //! constructor\r
-       CTRTextureBlend(CBurningVideoDriver* driver);\r
+               //! constructor\r
+               CTRTextureBlend(CBurningVideoDriver* driver);\r
 \r
-       //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+               //! draws an indexed triangle list\r
+               virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+               virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
 \r
-       virtual void setZCompareFunc ( u32 func) _IRR_OVERRIDE_;\r
-       virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
 \r
+               virtual void setZCompareFunc(u32 func)\r
+               {\r
+                       depth_func = (E_COMPARISON_FUNC)func;\r
+               }\r
+               virtual void setParam(u32 index, f32 value)\r
+               {\r
+                       SBurningShaderMaterial material;\r
+                       material.org.ZBuffer = depth_func;\r
+                       material.org.MaterialTypeParam = value;\r
+                       OnSetMaterial(material);\r
+       }\r
+\r
+#endif\r
 \r
 private:\r
        // fragment shader\r
@@ -102,12 +115,11 @@ private:
        void fragment_one_one_minus_src_alpha ();\r
        void fragment_one_minus_dst_alpha_one();\r
        void fragment_src_alpha_one();\r
+       void fragment_src_alpha_one_minus_src_alpha();\r
 \r
        tFragmentShader fragmentShader;\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
 \r
-       u32 ZCompare;\r
+       E_COMPARISON_FUNC depth_func;\r
 };\r
 \r
 //! constructor\r
@@ -118,26 +130,23 @@ CTRTextureBlend::CTRTextureBlend(CBurningVideoDriver* driver)
        setDebugName("CTRTextureBlend");\r
        #endif\r
 \r
-       ZCompare = 1;\r
+       depth_func = ECFN_LESSEQUAL;\r
+       fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;\r
 }\r
 \r
 /*!\r
 */\r
-void CTRTextureBlend::setZCompareFunc ( u32 func)\r
+void CTRTextureBlend::OnSetMaterial(const SBurningShaderMaterial& material)\r
 {\r
-       ZCompare = func;\r
-}\r
+       int showname = 0;\r
 \r
-/*!\r
-*/\r
-void CTRTextureBlend::setParam ( u32 index, f32 value)\r
-{\r
-       u8 showname = 0;\r
+       depth_func = (E_COMPARISON_FUNC)material.org.ZBuffer;\r
+       AlphaRef = 0; // tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
 \r
        E_BLEND_FACTOR srcFact,dstFact;\r
        E_MODULATE_FUNC modulate;\r
        u32 alphaSrc;\r
-       unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, value );\r
+       unpack_textureBlendFunc ( srcFact, dstFact, modulate, alphaSrc, material.org.MaterialTypeParam);\r
 \r
        fragmentShader = 0;\r
 \r
@@ -145,43 +154,39 @@ void CTRTextureBlend::setParam ( u32 index, f32 value)
        {\r
                fragmentShader = &CTRTextureBlend::fragment_dst_color_zero;\r
        }\r
-       else\r
-       if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE )\r
+       else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE )\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_dst_color_one;\r
        }\r
-       else\r
-       if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA)\r
+       else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_SRC_ALPHA)\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_dst_color_src_alpha;\r
        }\r
-       else\r
-       if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA)\r
+       else if ( srcFact == EBF_DST_COLOR && dstFact == EBF_ONE_MINUS_DST_ALPHA)\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha;\r
        }\r
-       else\r
-       if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR )\r
+       else if ( srcFact == EBF_ZERO && dstFact == EBF_ONE_MINUS_SRC_COLOR )\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_zero_one_minus_scr_color;\r
        }\r
-       else\r
-       if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA)\r
+       else if ( srcFact == EBF_ONE && dstFact == EBF_ONE_MINUS_SRC_ALPHA)\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_one_one_minus_src_alpha;\r
        }\r
-       else\r
-       if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE )\r
+       else if ( srcFact == EBF_ONE_MINUS_DST_ALPHA && dstFact == EBF_ONE )\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_one_minus_dst_alpha_one;\r
        }\r
-       else\r
-       if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE )\r
+       else if ( srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE )\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_src_alpha_one;\r
        }\r
-       else\r
-       if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA )\r
+       else if (srcFact == EBF_SRC_ALPHA && dstFact == EBF_ONE_MINUS_SRC_ALPHA)\r
+       {\r
+               fragmentShader = &CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha;\r
+       }\r
+       else if ( srcFact == EBF_SRC_COLOR && dstFact == EBF_SRC_ALPHA )\r
        {\r
                fragmentShader = &CTRTextureBlend::fragment_src_color_src_alpha;\r
        }\r
@@ -213,7 +218,7 @@ void CTRTextureBlend::setParam ( u32 index, f32 value)
        {\r
                char buf[128];\r
                snprintf_irr ( buf, 128, "missing shader: %s %s",n[srcFact], n[dstFact] );\r
-               os::Printer::log( buf, ELL_INFORMATION );\r
+               os::Printer::log( buf, ELL_WARNING);\r
 \r
                lsrcFact = srcFact;\r
                ldstFact = dstFact;\r
@@ -248,15 +253,15 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -264,7 +269,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -301,6 +306,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -315,9 +321,10 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
 \r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -342,7 +349,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
 \r
                color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
                                                                clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
                                                                clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
                                                        );\r
@@ -385,7 +392,7 @@ void CTRTextureBlend::fragment_dst_color_src_alpha ()
 \r
                color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
                                                                clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
                                                                clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
                                                        );\r
@@ -432,23 +439,22 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
-\r
        if ( dx < 0 )\r
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -485,6 +491,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -497,11 +504,16 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
        tFixPoint a0, r0, g0, b0;\r
        tFixPoint     r1, g1, b1;\r
 \r
+#ifdef IPOL_C0\r
+       tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -509,9 +521,9 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
 #endif\r
 \r
                {\r
-\r
+                       //solves example 08. todo: depth_write. \r
 #ifdef WRITE_W\r
-                       z[i] = line.w[0];\r
+               //z[i] = line.w[0];\r
 #endif\r
 \r
 #ifdef INVERSE_W\r
@@ -519,13 +531,21 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
 #endif\r
 \r
                getSample_texture ( a0, r0, g0, b0, &IT[0],     tofix ( line.t[0][0].x,iw),     tofix ( line.t[0][0].y,iw) );\r
-               color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
-//             u32 check = imulFix_tex1( r0, r1 );\r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1( r0, r1 ) + imulFix_tex1( r1, a0 ) ),\r
-                                                               clampfix_maxcolor ( imulFix_tex1( g0, g1 ) + imulFix_tex1( g1, a0 ) ),\r
-                                                               clampfix_maxcolor ( imulFix_tex1( b0, b1 ) + imulFix_tex1( b1, a0 ) )\r
+#ifdef IPOL_C0\r
+               vec4_to_fix(a2,r2, g2, b2, line.c[0][0], iw);\r
+               //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?\r
+               r0 = imulFix_simple(r0, r2);\r
+               g0 = imulFix_simple(g0, g2);\r
+               b0 = imulFix_simple(b0, b2);\r
+#endif\r
+\r
+               color_to_fix ( r1, g1, b1, dst[i] );\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1( r0, r0 ) + imulFix_tex1( r1, a0 ) ),\r
+                                                               clampfix_maxcolor ( imulFix_tex1( g0, g0 ) + imulFix_tex1( g1, a0 ) ),\r
+                                                               clampfix_maxcolor ( imulFix_tex1( b0, b0 ) + imulFix_tex1( b1, a0 ) )\r
                                                        );\r
+\r
                }\r
 \r
 #ifdef IPOL_W\r
@@ -565,7 +585,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
 \r
                color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
                                                                clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
                                                                clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
                                                        );\r
@@ -582,6 +602,7 @@ void CTRTextureBlend::fragment_src_color_src_alpha ()
                line.c[0][0] += slopeC[0];\r
 #endif\r
        }break;\r
+       \r
        } // zcompare\r
 \r
 }\r
@@ -612,15 +633,15 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -628,7 +649,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2 ( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -665,6 +686,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -676,13 +698,15 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
 \r
        tFixPoint a0,r0, g0, b0;\r
        tFixPoint        r1, g1, b1;\r
+#ifdef IPOL_C0\r
        tFixPoint        r2, g2, b2;\r
-\r
+#endif\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -704,16 +728,16 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
 \r
                color_to_fix1 ( r1, g1, b1, dst[i] );\r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ),\r
-                                                               imulFix ( g0 + imulFix ( g1, a0 ), g2 ),\r
-                                                               imulFix ( b0 + imulFix ( b1, a0 ), b2 )\r
+               dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),\r
+                                                               imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),\r
+                                                               imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )\r
                                                        );\r
 #else\r
-               dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ),\r
-                                                               g0 + imulFix ( g1, a0 ),\r
-                                                               b0 + imulFix ( b1, a0 )\r
+               dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),\r
+                                                               g0 + imulFix_simple( g1, a0 ),\r
+                                                               b0 + imulFix_simple( b1, a0 )\r
                                                        );\r
 \r
 #endif\r
@@ -753,16 +777,16 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
 \r
                color_to_fix1 ( r1, g1, b1, dst[i] );\r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( imulFix ( r0 + imulFix ( r1, a0 ), r2 ),\r
-                                                               imulFix ( g0 + imulFix ( g1, a0 ), g2 ),\r
-                                                               imulFix ( b0 + imulFix ( b1, a0 ), b2 )\r
+               dst[i] = fix_to_sample( imulFix ( r0 + imulFix_simple( r1, a0 ), r2 ),\r
+                                                               imulFix ( g0 + imulFix_simple( g1, a0 ), g2 ),\r
+                                                               imulFix ( b0 + imulFix_simple( b1, a0 ), b2 )\r
                                                        );\r
 #else\r
-               dst[i] = fix_to_color ( r0 + imulFix ( r1, a0 ),\r
-                                                               g0 + imulFix ( g1, a0 ),\r
-                                                               b0 + imulFix ( b1, a0 )\r
+               dst[i] = fix_to_sample( r0 + imulFix_simple( r1, a0 ),\r
+                                                               g0 + imulFix_simple( g1, a0 ),\r
+                                                               b0 + imulFix_simple( b1, a0 )\r
                                                        );\r
 \r
 #endif\r
@@ -779,6 +803,7 @@ void CTRTextureBlend::fragment_one_one_minus_src_alpha()
                line.c[0][0] += slopeC[0];\r
 #endif\r
        }break;\r
+\r
        } // zcompare\r
 \r
 }\r
@@ -809,15 +834,15 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -825,7 +850,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -862,6 +887,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -873,13 +899,15 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
 \r
        tFixPoint r0, g0, b0;\r
        tFixPoint a1, r1, g1, b1;\r
+#ifdef IPOL_C0\r
        tFixPoint r2, g2, b2;\r
-\r
+#endif\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -899,17 +927,17 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
                getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
                color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
                a1 = FIX_POINT_ONE - a1;\r
-               dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ),\r
-                                                               imulFix ( imulFix ( g0, a1 ) + g1, g2 ),\r
-                                                               imulFix ( imulFix ( b0, a1 ) + b1, b2 )\r
+               dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),\r
+                                                               imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),\r
+                                                               imulFix (imulFix_simple( b0, a1 ) + b1, b2 )\r
                                                        );\r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( r0, a1) + r0,\r
-                                                               imulFix ( g0, a1) + g0,\r
-                                                               imulFix ( b0, a1) + b0\r
+               dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,\r
+                       imulFix_simple( g0, a1) + g0,\r
+                       imulFix_simple( b0, a1) + b0\r
                                                        );\r
 \r
 #endif\r
@@ -948,17 +976,17 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
                color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
                a1 = FIX_POINT_ONE - a1;\r
-               dst[i] = fix_to_color ( imulFix ( imulFix ( r0, a1 ) + r1, r2 ),\r
-                                                               imulFix ( imulFix ( g0, a1 ) + g1, g2 ),\r
-                                                               imulFix ( imulFix ( b0, a1 ) + b1, b2 )\r
+               dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, a1 ) + r1, r2 ),\r
+                                                               imulFix (imulFix_simple( g0, a1 ) + g1, g2 ),\r
+                                                               imulFix (imulFix_simple( b0, a1 ) + b1, b2 )\r
                                                        );\r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( r0, a1) + r0,\r
-                                                               imulFix ( g0, a1) + g0,\r
-                                                               imulFix ( b0, a1) + b0\r
+               dst[i] = fix_to_sample(imulFix_simple( r0, a1) + r0,\r
+                       imulFix_simple( g0, a1) + g0,\r
+                       imulFix_simple( b0, a1) + b0\r
                                                        );\r
 \r
 #endif\r
@@ -975,6 +1003,7 @@ void CTRTextureBlend::fragment_one_minus_dst_alpha_one ()
                line.c[0][0] += slopeC[0];\r
 #endif\r
        }break;\r
+\r
        } // zcompare\r
 \r
 }\r
@@ -1005,15 +1034,15 @@ void CTRTextureBlend::fragment_src_alpha_one ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -1021,7 +1050,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -1058,6 +1087,7 @@ void CTRTextureBlend::fragment_src_alpha_one ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -1069,13 +1099,15 @@ void CTRTextureBlend::fragment_src_alpha_one ()
 \r
        tFixPoint a0, r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
        tFixPoint r2, g2, b2;\r
-\r
+#endif\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -1092,32 +1124,32 @@ void CTRTextureBlend::fragment_src_alpha_one ()
                getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
                if ( a0 > 0 )\r
                {\r
-               a0 >>= 8;\r
+                       fix_color_norm(a0);\r
 \r
                color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix4_to_color ( a0,\r
-                                                                clampfix_maxcolor ( imulFix (r0,a0 ) + r1),\r
-                                                                clampfix_maxcolor ( imulFix (g0,a0 ) + g1),\r
-                                                                clampfix_maxcolor ( imulFix (b0,a0 ) + b1)\r
+               dst[i] = fix4_to_sample( a0,\r
+                                                                clampfix_maxcolor (imulFix_simple(r0,a0) + r1),\r
+                                                                clampfix_maxcolor (imulFix_simple(g0,a0) + g1),\r
+                                                                clampfix_maxcolor (imulFix_simple(b0,a0) + b1)\r
                                                                );\r
 \r
 /*\r
-               a0 >>= 8;\r
-               dst[i] = fix4_to_color ( a0,\r
-                                                               imulFix ( imulFix ( r0, a0 ) + r1, r2 ),\r
-                                                               imulFix ( imulFix ( g0, a0 ) + g1, g2 ),\r
-                                                               imulFix ( imulFix ( b0, a0 ) + b1, b2 )\r
+               fix_color_norm(a0);\r
+               dst[i] = fix4_to_sample ( a0,\r
+                                                               imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),\r
+                                                               imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),\r
+                                                               imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )\r
                                                        );\r
 */\r
 #else\r
-               dst[i] = fix4_to_color ( a0,\r
-                                                                clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ),\r
-                                                                clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ),\r
-                                                                clampfix_maxcolor ( imulFix (b0,a0 ) + b1 )\r
+               dst[i] = fix4_to_sample( a0,\r
+                                                                clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),\r
+                                                                clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),\r
+                                                                clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )\r
                                                                );\r
 \r
 #endif\r
@@ -1156,32 +1188,32 @@ void CTRTextureBlend::fragment_src_alpha_one ()
                getSample_texture ( a0, r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
                if ( a0 > 0 )\r
                {\r
-               a0 >>= 8;\r
+                       fix_color_norm(a0);\r
 \r
                color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix4_to_color ( a0,\r
-                                                                clampfix_maxcolor ( imulFix ( imulFix (r0,a0 ) + r1, r2 ) ),\r
-                                                                clampfix_maxcolor ( imulFix ( imulFix (g0,a0 ) + g1, g2 ) ),\r
-                                                                clampfix_maxcolor ( imulFix ( imulFix (b0,a0 ) + b1, b2 ) )\r
+               dst[i] = fix4_to_sample( a0,\r
+                                                                clampfix_maxcolor ( imulFix (imulFix_simple(r0,a0 ) + r1, r2 ) ),\r
+                                                                clampfix_maxcolor ( imulFix (imulFix_simple(g0,a0 ) + g1, g2 ) ),\r
+                                                                clampfix_maxcolor ( imulFix (imulFix_simple(b0,a0 ) + b1, b2 ) )\r
                                                                );\r
 \r
 /*\r
-               a0 >>= 8;\r
-               dst[i] = fix4_to_color ( a0,\r
-                                                               imulFix ( imulFix ( r0, a0 ) + r1, r2 ),\r
-                                                               imulFix ( imulFix ( g0, a0 ) + g1, g2 ),\r
-                                                               imulFix ( imulFix ( b0, a0 ) + b1, b2 )\r
+               fix_color_norm(a0);\r
+               dst[i] = fix4_to_sample ( a0,\r
+                                                               imulFix ( imulFix_simple ( r0, a0 ) + r1, r2 ),\r
+                                                               imulFix ( imulFix_simple ( g0, a0 ) + g1, g2 ),\r
+                                                               imulFix ( imulFix_simple ( b0, a0 ) + b1, b2 )\r
                                                        );\r
 */\r
 #else\r
-               dst[i] = fix4_to_color ( a0,\r
-                                                                clampfix_maxcolor ( imulFix (r0,a0 ) + r1 ),\r
-                                                                clampfix_maxcolor ( imulFix (g0,a0 ) + g1 ),\r
-                                                                clampfix_maxcolor ( imulFix (b0,a0 ) + b1 )\r
+               dst[i] = fix4_to_sample( a0,\r
+                                                                clampfix_maxcolor (imulFix_simple(r0,a0 ) + r1 ),\r
+                                                                clampfix_maxcolor (imulFix_simple(g0,a0 ) + g1 ),\r
+                                                                clampfix_maxcolor (imulFix_simple(b0,a0 ) + b1 )\r
                                                                );\r
 \r
 #endif\r
@@ -1201,6 +1233,160 @@ void CTRTextureBlend::fragment_src_alpha_one ()
                line.c[0][0] += slopeC[0];\r
 #endif\r
        }break;\r
+\r
+       } // zcompare\r
+\r
+}\r
+\r
+\r
+/*!\r
+*/\r
+void CTRTextureBlend::fragment_src_alpha_one_minus_src_alpha()\r
+{\r
+       tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+       fp24 *z;\r
+#endif\r
+\r
+       s32 xStart;\r
+       s32 xEnd;\r
+       s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+       f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+       fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#ifdef IPOL_T0\r
+       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+       // apply top-left fill-convention, left\r
+       xStart = fill_convention_left(line.x[0]);\r
+       xEnd = fill_convention_right(line.x[1]);\r
+\r
+       dx = xEnd - xStart;\r
+       if (dx < 0)\r
+               return;\r
+\r
+       // slopes\r
+       const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+       slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+       slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+       slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+       subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+       line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+       line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+       line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+       line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+       line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+       dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+       z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+       f32 iw = FIX_POINT_F32_MUL;\r
+\r
+       tFixPoint a0, r0, g0, b0;\r
+       tFixPoint     r1, g1, b1;\r
+       tFixPoint a2, r2, g2, b2;\r
+\r
+       s32 i;\r
+\r
+       switch (depth_func)\r
+       {\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
+               for (i = 0; i <= dx; ++i)\r
+               {\r
+#ifdef CMP_W\r
+                       if (line.w[0] >= z[i])\r
+#endif\r
+\r
+                       {\r
+#ifdef WRITE_W\r
+               //z[i] = line.w[0];\r
+#endif\r
+\r
+#ifdef INVERSE_W\r
+                               iw = fix_inverse32(line.w[0]);\r
+#endif\r
+\r
+                               getSample_texture(a0, r0, g0, b0, &IT[0], tofix(line.t[0][0].x, iw), tofix(line.t[0][0].y, iw));\r
+                               if (a0 > AlphaRef)\r
+                               {\r
+#ifdef IPOL_C0\r
+                                       vec4_to_fix(a2, r2, g2, b2, line.c[0][0], iw);\r
+                                       //a0 = imulFix(a0, a2); why is vertex color enabled and not vertex_alpha?\r
+                                       r0 = imulFix_simple(r0, r2);\r
+                                       g0 = imulFix_simple(g0, g2);\r
+                                       b0 = imulFix_simple(b0, b2);\r
+#endif\r
+\r
+                                       color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+                                       fix_color_norm(a0);\r
+\r
+                                       r2 = r1 + imulFix(a0, r0 - r1);\r
+                                       g2 = g1 + imulFix(a0, g0 - g1);\r
+                                       b2 = b1 + imulFix(a0, b0 - b1);\r
+                                       dst[i] = fix4_to_sample(a0, r2, g2, b2);\r
+                               }\r
+\r
+                       }\r
+\r
+#ifdef IPOL_W\r
+                       line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_T0\r
+                       line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+                       line.c[0][0] += slopeC[0];\r
+#endif\r
+               }\r
+               break;\r
+\r
        } // zcompare\r
 \r
 }\r
@@ -1232,15 +1418,15 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -1248,7 +1434,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -1285,6 +1471,7 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -1296,13 +1483,15 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
 \r
        tFixPoint r0, g0, b0;\r
        tFixPoint a1, r1, g1, b1;\r
+#ifdef IPOL_C0\r
        tFixPoint r2, g2, b2;\r
-\r
+#endif\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -1322,15 +1511,15 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
                getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
                color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
                a1 = FIX_POINT_ONE - a1;\r
-               dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
+               dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
                                                                imulFix ( imulFix ( g1, g0 + a1 ), g2 ),\r
                                                                imulFix ( imulFix ( b1, b0 + a1 ), b2 )\r
                                                        );\r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ),\r
+               dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),\r
                                                                imulFix ( g1, g0 + a1 ),\r
                                                                imulFix ( b1, b0 + a1 )\r
                                                        );\r
@@ -1371,15 +1560,15 @@ void CTRTextureBlend::fragment_dst_color_one_minus_dst_alpha ()
                color_to_fix1 ( a1, r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
                a1 = FIX_POINT_ONE - a1;\r
-               dst[i] = fix_to_color ( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
+               dst[i] = fix_to_sample( imulFix ( imulFix ( r1, r0 + a1 ), r2 ),\r
                                                                imulFix ( imulFix ( g1, g0 + a1 ), g2 ),\r
                                                                imulFix ( imulFix ( b1, b0 + a1 ), b2 )\r
                                                        );\r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( r1, r0 + a1 ),\r
+               dst[i] = fix_to_sample( imulFix ( r1, r0 + a1 ),\r
                                                                imulFix ( g1, g0 + a1 ),\r
                                                                imulFix ( b1, b0 + a1 )\r
                                                        );\r
@@ -1428,15 +1617,15 @@ void CTRTextureBlend::fragment_dst_color_zero ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -1444,7 +1633,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -1481,6 +1670,7 @@ void CTRTextureBlend::fragment_dst_color_zero ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -1492,13 +1682,15 @@ void CTRTextureBlend::fragment_dst_color_zero ()
 \r
        tFixPoint r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
        tFixPoint r2, g2, b2;\r
-\r
+#endif\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -1519,15 +1711,15 @@ void CTRTextureBlend::fragment_dst_color_zero ()
                color_to_fix1 ( r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ),\r
-                                                               imulFix ( imulFix ( g0, g1 ), g2 ),\r
-                                                               imulFix ( imulFix ( b0, b1 ), b2 ) );\r
+               dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),\r
+                                                               imulFix (imulFix_simple( g0, g1 ), g2 ),\r
+                                                               imulFix (imulFix_simple( b0, b1 ), b2 ) );\r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( r0, r1 ),\r
-                                                               imulFix ( g0, g1 ),\r
-                                                               imulFix ( b0, b1 )\r
+               dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),\r
+                       imulFix_simple( g0, g1 ),\r
+                       imulFix_simple( b0, b1 )\r
                                                        );\r
 \r
 #endif\r
@@ -1566,16 +1758,16 @@ void CTRTextureBlend::fragment_dst_color_zero ()
                color_to_fix1 ( r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( imulFix ( imulFix ( r0, r1 ), r2 ),\r
-                                                               imulFix ( imulFix ( g0, g1 ), g2 ),\r
-                                                               imulFix ( imulFix ( b0, b1 ), b2 )\r
+               dst[i] = fix_to_sample( imulFix (imulFix_simple( r0, r1 ), r2 ),\r
+                                                               imulFix (imulFix_simple( g0, g1 ), g2 ),\r
+                                                               imulFix (imulFix_simple( b0, b1 ), b2 )\r
                                                        );\r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( r0, r1 ),\r
-                                                               imulFix ( g0, g1 ),\r
-                                                               imulFix ( b0, b1 )\r
+               dst[i] = fix_to_sample(imulFix_simple( r0, r1 ),\r
+                       imulFix_simple( g0, g1 ),\r
+                       imulFix_simple( b0, b1 )\r
                                                        );\r
 \r
 #endif\r
@@ -1622,15 +1814,15 @@ void CTRTextureBlend::fragment_dst_color_one ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -1638,7 +1830,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -1675,6 +1867,7 @@ void CTRTextureBlend::fragment_dst_color_one ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -1686,13 +1879,15 @@ void CTRTextureBlend::fragment_dst_color_one ()
 \r
        tFixPoint r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
        tFixPoint r2, g2, b2;\r
-\r
+#endif\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -1712,15 +1907,15 @@ void CTRTextureBlend::fragment_dst_color_one ()
                getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
                color_to_fix ( r1, g1, b1, dst[i] );\r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
                                                        );\r
 \r
 #else\r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
                                                        );\r
@@ -1761,15 +1956,15 @@ void CTRTextureBlend::fragment_dst_color_one ()
                color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
                                                        );\r
 \r
 #else\r
-               dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
+               dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex1 ( r0, r1 ) + r1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( g0, g1 ) + g1 ),\r
                                                                clampfix_maxcolor ( imulFix_tex1 ( b0, b1 ) + b1 )\r
                                                        );\r
@@ -1819,15 +2014,15 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -1835,7 +2030,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -1872,6 +2067,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -1883,13 +2079,15 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
 \r
        tFixPoint r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
+#ifdef IPOL_C0\r
        tFixPoint r2, g2, b2;\r
-\r
+#endif\r
        s32 i;\r
 \r
-       switch ( ZCompare )\r
+       switch (depth_func)\r
        {\r
-       case 1:\r
+       default:\r
+       case ECFN_LESSEQUAL:\r
        for ( i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_W\r
@@ -1909,17 +2107,17 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
                getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
                color_to_fix1 ( r1, g1, b1, dst[i] );\r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - g0, g1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - b0, b1 )\r
+               dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+                       imulFix( FIX_POINT_ONE - g0, g1 ),\r
+                       imulFix( FIX_POINT_ONE - b0, b1 )\r
                                                        );\r
 \r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - g0, g1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - b0, b1 )\r
+               dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+                       imulFix( FIX_POINT_ONE - g0, g1 ),\r
+                       imulFix( FIX_POINT_ONE - b0, b1 )\r
                                                        );\r
 \r
 #endif\r
@@ -1957,17 +2155,17 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
                getSample_texture ( r0, g0, b0, IT + 0, tofix ( line.t[0][0].x,iw),tofix ( line.t[0][0].y,iw) );\r
                color_to_fix1 ( r1, g1, b1, dst[i] );\r
 #ifdef IPOL_C0\r
-               getSample_color ( r2, g2, b2, line.c[0][0],iw );\r
+               vec4_to_fix( r2, g2, b2, line.c[0][0],iw );\r
 \r
-               dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - g0, g1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - b0, b1 )\r
+               dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+                       imulFix( FIX_POINT_ONE - g0, g1 ),\r
+                       imulFix( FIX_POINT_ONE - b0, b1 )\r
                                                        );\r
 \r
 #else\r
-               dst[i] = fix_to_color ( imulFix ( FIX_POINT_ONE - r0, r1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - g0, g1 ),\r
-                                                               imulFix ( FIX_POINT_ONE - b0, b1 )\r
+               dst[i] = fix_to_sample(imulFix( FIX_POINT_ONE - r0, r1 ),\r
+                       imulFix( FIX_POINT_ONE - g0, g1 ),\r
+                       imulFix( FIX_POINT_ONE - b0, b1 )\r
                                                        );\r
 \r
 #endif\r
@@ -1990,7 +2188,7 @@ void CTRTextureBlend::fragment_zero_one_minus_scr_color ()
 \r
 \r
 \r
-void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureBlend::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        if ( 0 == fragmentShader )\r
                return;\r
@@ -2004,9 +2202,9 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -2092,8 +2290,8 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -2251,8 +2449,8 @@ void CTRTextureBlend::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -2371,6 +2569,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTRTextureBlend(CBurningVideoDriver* driver)\r
 {\r
+       // EMT_ONETEXTURE_BLEND\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureBlend(driver);\r
        #else\r
index f5653ab56a84a825aa82ab5948002af752e0eb63..3e75c2d9b48d93beb81ede220674dca2612b03a3 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -84,13 +84,11 @@ public:
        CTRTextureDetailMap2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual bool canWireFrame () { return true; }\r
 \r
-\r
-private:\r
-       void scanline_bilinear ();\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
+protected:\r
+       virtual void scanline_bilinear ();\r
 \r
 };\r
 \r
@@ -138,8 +136,8 @@ void CTRTextureDetailMap2::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -147,7 +145,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -184,6 +182,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -203,6 +202,8 @@ void CTRTextureDetailMap2::scanline_bilinear ()
 \r
        for ( s32 i = 0; i <= dx; ++i )\r
        {\r
+               if ( (0 == EdgeTestPass) & i ) break;\r
+\r
 #ifdef CMP_Z\r
                if ( line.z[0] < z[i] )\r
 #endif\r
@@ -222,16 +223,13 @@ void CTRTextureDetailMap2::scanline_bilinear ()
                        getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
                        getSample_texture ( r1, g1, b1, &IT[1], tx1,ty1 );\r
 \r
-                       // bias half color\r
-                       r1 += -FIX_POINT_HALF_COLOR;\r
-                       g1 += -FIX_POINT_HALF_COLOR;\r
-                       b1 += -FIX_POINT_HALF_COLOR;\r
+                       // add signed\r
 \r
-                       r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 ) );\r
-                       g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 ) );\r
-                       b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 ) );\r
+                       r2 = clampfix_mincolor ( clampfix_maxcolor ( r0 + r1 - FIX_POINT_HALF_COLOR ) );\r
+                       g2 = clampfix_mincolor ( clampfix_maxcolor ( g0 + g1 - FIX_POINT_HALF_COLOR ) );\r
+                       b2 = clampfix_mincolor ( clampfix_maxcolor ( b0 + b1 - FIX_POINT_HALF_COLOR ) );\r
 \r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
+                       dst[i] = fix_to_sample( r2, g2, b2 );\r
 \r
 #ifdef WRITE_Z\r
                        z[i] = line.z[0];\r
@@ -261,7 +259,7 @@ void CTRTextureDetailMap2::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureDetailMap2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -272,9 +270,9 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_edge( ca );\r
+       scan.invDeltaY[1] = reciprocal_edge( ba );\r
+       scan.invDeltaY[2] = reciprocal_edge( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -360,8 +358,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -519,8 +517,8 @@ void CTRTextureDetailMap2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
index 7bcc512b3106ad91f1220810ca4c85db0fa1cfa6..ef864606746dc7c5ac014008a002b561ccdea804 100644 (file)
 #undef INVERSE_W\r
 \r
 #undef IPOL_C0\r
+#undef IPOL_C1\r
+#undef IPOL_C2\r
 #undef IPOL_T0\r
 #undef IPOL_T1\r
+#undef IPOL_L0\r
 \r
 // define render case\r
 #define SUBTEXEL\r
 #define WRITE_W\r
 \r
 #define IPOL_C0\r
+#define IPOL_C1\r
+//#define IPOL_C2\r
 #define IPOL_T0\r
 //#define IPOL_T1\r
+//#define IPOL_L0\r
 \r
 // apply global override\r
 #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+       #undef IPOL_C1\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 3\r
+#undef IPOL_C2\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+       #undef IPOL_L0\r
+#endif\r
+\r
+\r
 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
        #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
                #undef IPOL_W\r
@@ -83,14 +102,12 @@ public:
        CTRTextureGouraud2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual bool canWireFrame () { return true; }\r
 \r
 \r
 private:\r
-       void scanline_bilinear ();\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
-\r
+       void fragmentShader ();\r
 };\r
 \r
 //! constructor\r
@@ -106,7 +123,7 @@ CTRTextureGouraud2::CTRTextureGouraud2(CBurningVideoDriver* driver)
 \r
 /*!\r
 */\r
-void CTRTextureGouraud2::scanline_bilinear ()\r
+void CTRTextureGouraud2::fragmentShader ()\r
 {\r
        tVideoSample *dst;\r
 \r
@@ -130,15 +147,19 @@ void CTRTextureGouraud2::scanline_bilinear ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC;\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+       sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
+#endif\r
+\r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -146,7 +167,7 @@ void CTRTextureGouraud2::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -155,7 +176,13 @@ void CTRTextureGouraud2::scanline_bilinear ()
        slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
 #endif\r
 #ifdef IPOL_C0\r
-       slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+       slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+       slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C2\r
+       slopeC[2] = (line.c[2][1] - line.c[2][0]) * invDeltaX;\r
 #endif\r
 #ifdef IPOL_T0\r
        slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
@@ -163,6 +190,10 @@ void CTRTextureGouraud2::scanline_bilinear ()
 #ifdef IPOL_T1\r
        slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
 #endif\r
+#ifdef IPOL_L0\r
+       slopeL[0] = (line.l[0][1] - line.l[0][0]) * invDeltaX;\r
+#endif\r
+\r
 \r
 #ifdef SUBTEXEL\r
        subPixel = ( (f32) xStart ) - line.x[0];\r
@@ -173,7 +204,13 @@ void CTRTextureGouraud2::scanline_bilinear ()
        line.w[0] += slopeW * subPixel;\r
 #endif\r
 #ifdef IPOL_C0\r
-       line.c[0][0] += slopeC * subPixel;\r
+       line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_C1\r
+       line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+#ifdef IPOL_C2\r
+       line.c[2][0] += slopeC[2] * subPixel;\r
 #endif\r
 #ifdef IPOL_T0\r
        line.t[0][0] += slopeT[0] * subPixel;\r
@@ -181,8 +218,12 @@ void CTRTextureGouraud2::scanline_bilinear ()
 #ifdef IPOL_T1\r
        line.t[1][0] += slopeT[1] * subPixel;\r
 #endif\r
+#ifdef IPOL_L0\r
+       line.l[0][0] += slopeL[0] * subPixel;\r
+#endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -195,18 +236,29 @@ void CTRTextureGouraud2::scanline_bilinear ()
        tFixPoint tx0;\r
        tFixPoint ty0;\r
 \r
-       tFixPoint r0, g0, b0;\r
-\r
 #ifdef IPOL_C0\r
+       tFixPoint r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
 #endif\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#ifdef IPOL_C1\r
+       tFixPoint aFog = FIX_POINT_ONE;\r
+#endif\r
+\r
+\r
+#ifdef IPOL_C2\r
+       tFixPoint r3, g3, b3;\r
+#endif\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
        u32 dIndex = ( line.y & 3 ) << 2;\r
 #endif\r
 \r
        for ( s32 i = 0; i <= dx; ++i )\r
        {\r
+               //if test active only first pixel\r
+               if ( (0 == EdgeTestPass) & i ) break;\r
+\r
 #ifdef CMP_Z\r
                if ( line.z[0] < z[i] )\r
 #endif\r
@@ -221,41 +273,70 @@ void CTRTextureGouraud2::scanline_bilinear ()
                        z[i] = line.w[0];\r
 #endif\r
 \r
-\r
 #ifdef INVERSE_W\r
                        inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+                       //complete inside fog\r
+                       if (TL_Flag & TL_FOG)\r
+                       {\r
+                               aFog = tofix(line.c[1][0].a, inversew);\r
+                               if (aFog <= 0)\r
+                               {\r
+                                       dst[i] = fog_color_sample;\r
+                                       continue;\r
+                               }\r
+                       }\r
+#endif\r
                        tx0 = tofix ( line.t[0][0].x, inversew);\r
                        ty0 = tofix ( line.t[0][0].y, inversew);\r
 \r
+\r
 #ifdef IPOL_C0\r
-                       r1 = tofix ( line.c[0][0].y ,inversew );\r
-                       g1 = tofix ( line.c[0][0].z ,inversew );\r
-                       b1 = tofix ( line.c[0][0].w ,inversew );\r
-#endif\r
+\r
+                       getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);\r
+                       vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);\r
+\r
+                       r0 = imulFix_simple(r0, r1);\r
+                       g0 = imulFix_simple(g0, g1);\r
+                       b0 = imulFix_simple(b0, b1);\r
+\r
+#ifdef IPOL_C1\r
+\r
+                       //specular highlight\r
+                       if (TL_Flag & TL_SPECULAR)\r
+                       {\r
+                               vec4_to_fix(r1, g1, b1, line.c[1][0], inversew*COLOR_MAX);\r
+                               r0 = clampfix_maxcolor(r1 + r0);\r
+                               g0 = clampfix_maxcolor(g1 + g0);\r
+                               b0 = clampfix_maxcolor(b1 + b0);\r
+                       }\r
+                       //mix with distance\r
+                       if (aFog < FIX_POINT_ONE)\r
+                       {\r
+                               r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);\r
+                               g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);\r
+                               b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);\r
+                       }\r
+                       dst[i] = fix_to_sample(r0, g0, b0);\r
 \r
 #else\r
-                       tx0 = tofix(line.t[0][0].x, inversew);\r
-                       ty0 = tofix(line.t[0][0].y, inversew);\r
-#ifdef IPOL_C0\r
-                       getTexel_plain2 ( r1, g1, b1, line.c[0][0] );\r
-#endif\r
+                       dst[i] = fix_to_sample(\r
+                               imulFix_simple(r0, r1),\r
+                               imulFix_simple(g0, g1),\r
+                               imulFix_simple(b0, b1)\r
+                       );\r
 #endif\r
 \r
-#ifdef IPOL_C0\r
-                       getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
-\r
-                       dst[i] = fix_to_color ( imulFix ( r0, r1 ),\r
-                                                                       imulFix ( g0, g1 ),\r
-                                                                       imulFix ( b0, b1 )\r
-                                                               );\r
 #else\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
                        const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
                        dst[i] = getTexel_plain ( &IT[0], d + tx0, d + ty0 );\r
 #else\r
                        getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
-                       dst[i] = fix_to_color ( r0, g0, b0 );\r
+                       dst[i] = fix_to_sample( r0, g0, b0 );\r
 #endif\r
 \r
 #endif\r
@@ -269,19 +350,28 @@ void CTRTextureGouraud2::scanline_bilinear ()
                line.w[0] += slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-               line.c[0][0] += slopeC;\r
+               line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+               line.c[1][0] += slopeC[1];\r
+#endif\r
+#ifdef IPOL_C2\r
+               line.c[2][0] += slopeC[2];\r
 #endif\r
 #ifdef IPOL_T0\r
                line.t[0][0] += slopeT[0];\r
 #endif\r
 #ifdef IPOL_T1\r
                line.t[1][0] += slopeT[1];\r
+#endif\r
+#ifdef IPOL_L0\r
+               line.l[0][0] += slopeL[0];\r
 #endif\r
        }\r
 \r
 }\r
 \r
-void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraud2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -292,9 +382,9 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -329,6 +419,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
        scan.c[0][0] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+       scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+       scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+       scan.slopeC[2][0] = (c->Color[2] - a->Color[2]) * scan.invDeltaY[0];\r
+       scan.c[2][0] = a->Color[2];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
        scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
        scan.t[0][0] = a->Tex[0];\r
@@ -339,6 +439,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
        scan.t[1][0] = a->Tex[1];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+       scan.slopeL[0][0] = (c->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[0];\r
+       scan.l[0][0] = a->LightTangent[0];\r
+#endif\r
+\r
        // top left fill convention y run\r
        s32 yStart;\r
        s32 yEnd;\r
@@ -348,7 +453,7 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
 #endif\r
 \r
        // rasterize upper sub-triangle\r
-       if ( (f32) 0.0 != scan.invDeltaY[1]  )\r
+       if ( F32_GREATER_0(scan.invDeltaY[1])  )\r
        {\r
                // calculate slopes for top edge\r
                scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
@@ -369,6 +474,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.c[0][1] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+               scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+               scan.slopeC[2][1] = (b->Color[2] - a->Color[2]) * scan.invDeltaY[1];\r
+               scan.c[2][1] = a->Color[2];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
                scan.t[0][1] = a->Tex[0];\r
@@ -379,9 +494,14 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.t[1][1] = a->Tex[1];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+               scan.slopeL[0][1] = (b->LightTangent[0] - a->LightTangent[0]) * scan.invDeltaY[1];\r
+               scan.l[0][1] = a->LightTangent[0];\r
+#endif\r
+\r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -405,6 +525,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+               scan.c[2][0] += scan.slopeC[2][0] * subPixel;\r
+               scan.c[2][1] += scan.slopeC[2][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -415,6 +545,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+               scan.l[0][0] += scan.slopeL[0][0] * subPixel;\r
+               scan.l[0][1] += scan.slopeL[0][1] * subPixel;\r
+#endif\r
+\r
 #endif\r
 \r
                // rasterize the edge scanlines\r
@@ -438,6 +573,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+                       line.c[2][scan.left] = scan.c[2][0];\r
+                       line.c[2][scan.right] = scan.c[2][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -448,8 +593,15 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        line.t[1][scan.right] = scan.t[1][1];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+                       line.l[0][scan.left] = scan.l[0][0];\r
+                       line.l[0][scan.right] = scan.l[0][1];\r
+#endif\r
+\r
                        // render a scanline\r
-                       scanline_bilinear ();\r
+                       fragmentShader ();\r
+                       if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -469,6 +621,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+                       scan.c[2][0] += scan.slopeC[2][0];\r
+                       scan.c[2][1] += scan.slopeC[2][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
@@ -479,14 +641,19 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        scan.t[1][1] += scan.slopeT[1][1];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+                       scan.l[0][0] += scan.slopeL[0][0];\r
+                       scan.l[0][1] += scan.slopeL[0][1];\r
+#endif\r
+\r
                }\r
        }\r
 \r
        // rasterize lower sub-triangle\r
-       if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+       if (F32_GREATER_0(scan.invDeltaY[2]) )\r
        {\r
                // advance to middle point\r
-               if( (f32) 0.0 != scan.invDeltaY[1] )\r
+               if(F32_GREATER_0(scan.invDeltaY[1]) )\r
                {\r
                        temp[0] = b->Pos.y - a->Pos.y;  // dy\r
 \r
@@ -500,6 +667,12 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
 #ifdef IPOL_C0\r
                        scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
 #endif\r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C2\r
+                       scan.c[2][0] = a->Color[2] + scan.slopeC[2][0] * temp[0];\r
+#endif\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
 #endif\r
@@ -507,6 +680,9 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+                       scan.l[0][0] = sVec3Pack_unpack(a->LightTangent[0]) + scan.slopeL[0][0] * temp[0];\r
+#endif\r
                }\r
 \r
                // calculate slopes for bottom edge\r
@@ -528,6 +704,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.c[0][1] = b->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+               scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+               scan.slopeC[2][1] = (c->Color[2] - b->Color[2]) * scan.invDeltaY[2];\r
+               scan.c[2][1] = b->Color[2];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
                scan.t[0][1] = b->Tex[0];\r
@@ -538,9 +724,14 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.t[1][1] = b->Tex[1];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+               scan.slopeL[0][1] = (c->LightTangent[0] - b->LightTangent[0]) * scan.invDeltaY[2];\r
+               scan.l[0][1] = b->LightTangent[0];\r
+#endif\r
+\r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -565,6 +756,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+               scan.c[2][0] += scan.slopeC[2][0] * subPixel;\r
+               scan.c[2][1] += scan.slopeC[2][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -575,6 +776,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+               scan.l[0][0] += scan.slopeL[0][0] * subPixel;\r
+               scan.l[0][1] += scan.slopeL[0][1] * subPixel;\r
+#endif\r
+\r
 #endif\r
 \r
                // rasterize the edge scanlines\r
@@ -598,6 +804,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+                       line.c[2][scan.left] = scan.c[2][0];\r
+                       line.c[2][scan.right] = scan.c[2][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -608,8 +824,15 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        line.t[1][scan.right] = scan.t[1][1];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+                       line.l[0][scan.left] = scan.l[0][0];\r
+                       line.l[0][scan.right] = scan.l[0][1];\r
+#endif\r
+\r
                        // render a scanline\r
-                       scanline_bilinear ( );\r
+                       fragmentShader ();\r
+                       if ( EdgeTestPass & edge_test_first_line ) break;\r
+\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -629,6 +852,16 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
+#ifdef IPOL_C2\r
+                       scan.c[2][0] += scan.slopeC[2][0];\r
+                       scan.c[2][1] += scan.slopeC[2][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
@@ -639,6 +872,11 @@ void CTRTextureGouraud2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,co
                        scan.t[1][1] += scan.slopeT[1][1];\r
 #endif\r
 \r
+#ifdef IPOL_L0\r
+                       scan.l[0][0] += scan.slopeL[0][0];\r
+                       scan.l[0][1] += scan.slopeL[0][1];\r
+#endif\r
+\r
                }\r
        }\r
 \r
@@ -657,6 +895,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTriangleRendererTextureGouraud2(CBurningVideoDriver* driver)\r
 {\r
+       // ETR_TEXTURE_GOURAUD\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureGouraud2(driver);\r
        #else\r
index 0f54928f568ba17e6f652dd94054a41b445786b0..040c83def8c652a25fab14ecf4300ce98da775a1 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -84,13 +84,11 @@ public:
        CTRTextureGouraudAdd2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear ();\r
-       sScanLineData line;\r
-\r
 };\r
 \r
 //! constructor\r
@@ -137,8 +135,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -146,7 +144,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -183,6 +181,7 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -193,9 +192,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
        f32 inversew = FIX_POINT_F32_MUL;\r
 \r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
        u32 dIndex = ( line.y & 3 ) << 2;\r
-\r
 #else\r
        tFixPoint tx0;\r
        tFixPoint ty0;\r
@@ -216,32 +214,28 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
 \r
                {\r
 \r
+#ifdef INVERSE_W\r
+                       inversew = fix_inverse32(line.w[0]);\r
+#endif\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
 \r
                const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
 \r
-\r
-#ifdef INVERSE_W\r
-                       inversew = fix_inverse32 ( line.w[0] );\r
-#endif\r
-                       dst[i] = PixelAdd32 (\r
-                                               dst[i],\r
-                                       getTexel_plain ( &IT[0],        d + tofix ( line.t[0][0].x,inversew),\r
-                                                                                               d + tofix ( line.t[0][0].y,inversew) )\r
-                                                                                                 );\r
+               dst[i] = PixelAdd32 (\r
+                                       dst[i],\r
+                               getTexel_plain ( &IT[0],        d + tofix ( line.t[0][0].x,inversew),\r
+                                                                                       d + tofix ( line.t[0][0].y,inversew) )\r
+                                                                                               );\r
 #else\r
 \r
-#ifdef INVERSE_W\r
-                       inversew = fix_inverse32 ( line.w[0] );\r
-#endif\r
                        tx0 = tofix ( line.t[0][0].x,inversew);\r
                        ty0 = tofix ( line.t[0][0].y,inversew);\r
                        getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
 \r
                        color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
-                       dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + r0 ),\r
+                       dst[i] = fix_to_sample( clampfix_maxcolor ( r1 + r0 ),\r
                                                                        clampfix_maxcolor ( g1 + g0 ),\r
                                                                        clampfix_maxcolor ( b1 + b0 )\r
                                                                );\r
@@ -275,10 +269,8 @@ void CTRTextureGouraudAdd2::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudAdd2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
-       sScanConvertData scan;\r
-\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
        if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
@@ -288,9 +280,9 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        // find if the major edge is left or right aligned\r
        f32 temp[4];\r
@@ -373,8 +365,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -532,8 +524,8 @@ void CTRTextureGouraudAdd2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -651,6 +643,8 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTRTextureGouraudAdd2(CBurningVideoDriver* driver)\r
 {\r
+       //ETR_TEXTURE_GOURAUD_ADD\r
+\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureGouraudAdd2(driver);\r
        #else\r
index 1c7f586ba70c63401154fb7986fef3753b30de23..4a619530a5b705ece8d8d27e9a90cad402c58c54 100644 (file)
 #define CMP_W\r
 //#define WRITE_W\r
 \r
-//#define IPOL_C0\r
+#define IPOL_C0\r
 #define IPOL_T0\r
 //#define IPOL_T1\r
 \r
 // apply global override\r
 #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-       #undef INVERSE_W\r
-       #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-               #undef IPOL_W\r
-       #endif\r
+#undef INVERSE_W\r
 #endif\r
 \r
 #ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
-       #undef SUBTEXEL\r
+#undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-       #undef IPOL_C0\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+#undef IPOL_C0\r
 #endif\r
 \r
 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
-       #define IPOL_Z\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+#undef IPOL_W\r
+#endif\r
+#define IPOL_Z\r
 \r
-       #ifdef CMP_W\r
-               #undef CMP_W\r
-               #define CMP_Z\r
-       #endif\r
+#ifdef CMP_W\r
+#undef CMP_W\r
+#define CMP_Z\r
+#endif\r
 \r
-       #ifdef WRITE_W\r
-               #undef WRITE_W\r
-               #define WRITE_Z\r
-       #endif\r
+#ifdef WRITE_W\r
+#undef WRITE_W\r
+#define WRITE_Z\r
+#endif\r
 \r
 #endif\r
 \r
@@ -83,13 +83,11 @@ public:
        CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
-       void scanline_bilinear ();\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
+       void fragmentShader();\r
 \r
 };\r
 \r
@@ -106,7 +104,7 @@ CTRTextureGouraudAddNoZ2::CTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)
 \r
 /*!\r
 */\r
-void CTRTextureGouraudAddNoZ2::scanline_bilinear ()\r
+void CTRTextureGouraudAddNoZ2::fragmentShader()\r
 {\r
        tVideoSample *dst;\r
 \r
@@ -137,16 +135,15 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
-\r
        if ( dx < 0 )\r
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -155,7 +152,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
        slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
 #endif\r
 #ifdef IPOL_C0\r
-       slopeC = (line.c[1] - line.c[0]) * invDeltaX;\r
+       slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
 #endif\r
 #ifdef IPOL_T0\r
        slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
@@ -173,7 +170,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
        line.w[0] += slopeW * subPixel;\r
 #endif\r
 #ifdef IPOL_C0\r
-       line.c[0] += slopeC * subPixel;\r
+       line.c[0][0] += slopeC * subPixel;\r
 #endif\r
 #ifdef IPOL_T0\r
        line.t[0][0] += slopeT[0] * subPixel;\r
@@ -183,6 +180,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -198,6 +196,10 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
        tFixPoint r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
 \r
+#ifdef IPOL_C0\r
+       tFixPoint r2, g2, b2;\r
+#endif\r
+\r
        for ( s32 i = 0; i <= dx; ++i )\r
        {\r
 #ifdef CMP_Z\r
@@ -207,20 +209,30 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
                if ( line.w[0] >= z[i] )\r
 #endif\r
                {\r
-#ifdef IPOL_W\r
+#ifdef INVERSE_W\r
                        inversew = fix_inverse32 ( line.w[0] );\r
 #endif\r
                        tx0 = tofix ( line.t[0][0].x,inversew);\r
                        ty0 = tofix ( line.t[0][0].y,inversew);\r
 \r
-                       getSample_texture ( r0, g0, b0, &IT[0], tx0,ty0 );\r
-\r
-                       color_to_fix ( r1, g1, b1, dst[i] );\r
+                       getSample_texture(r0, g0, b0, &IT[0], tx0, ty0);\r
 \r
-                       dst[i] = fix_to_color ( clampfix_maxcolor ( r1 + (r0 >> 1 ) ),\r
-                                                                       clampfix_maxcolor ( g1 + (g0 >> 1 ) ),\r
-                                                                       clampfix_maxcolor ( b1 + (b0 >> 1) )\r
-                                                               );\r
+#ifdef IPOL_C0\r
+                       vec4_to_fix(r2, g2, b2, line.c[0][0], inversew);\r
+                       r0 = imulFix(r2, r0);\r
+                       g0 = imulFix(g2, g0);\r
+                       b0 = imulFix(b2, b0);\r
+#endif\r
+                       \r
+                       //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
+                       if (r0 | g0 | b0)\r
+                       {\r
+                               color_to_fix(r1, g1, b1, dst[i]);\r
+                               r1 = imulFix_tex1(r1, FIXPOINT_COLOR_MAX - r0);\r
+                               g1 = imulFix_tex1(g1, FIXPOINT_COLOR_MAX - g0);\r
+                               b1 = imulFix_tex1(b1, FIXPOINT_COLOR_MAX - b0);\r
+                               dst[i] = fix_to_sample(r0+r1, g0+g1, b0+b1);\r
+                       }\r
 \r
 #ifdef WRITE_Z\r
                        z[i] = line.z[0];\r
@@ -237,7 +249,7 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
                line.w[0] += slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-               line.c[0] += slopeC;\r
+               line.c[0][0] += slopeC;\r
 #endif\r
 #ifdef IPOL_T0\r
                line.t[0][0] += slopeT[0];\r
@@ -249,8 +261,11 @@ void CTRTextureGouraudAddNoZ2::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudAddNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
+       //billboard discard\r
+       //if (a->Color[0].r <= 0.f) return;\r
+\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
        if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
@@ -260,9 +275,9 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -293,8 +308,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-       scan.slopeC[0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
-       scan.c[0] = a->Color[0];\r
+       scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+       scan.c[0][0] = a->Color[0];\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -316,7 +331,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
        // rasterize upper sub-triangle\r
-       if ( (f32) 0.0 != scan.invDeltaY[1]  )\r
+       if (F32_GREATER_0(scan.invDeltaY[1])  )\r
        {\r
                // calculate slopes for top edge\r
                scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
@@ -333,8 +348,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-               scan.slopeC[1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
-               scan.c[1] = a->Color[0];\r
+               scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+               scan.c[0][1] = a->Color[0];\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -348,8 +363,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -369,8 +384,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-               scan.c[0] += scan.slopeC[0] * subPixel;\r
-               scan.c[1] += scan.slopeC[1] * subPixel;\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -402,8 +417,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-                       line.c[scan.left] = scan.c[0];\r
-                       line.c[scan.right] = scan.c[1];\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -417,7 +432,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                        // render a scanline\r
-                       scanline_bilinear ();\r
+                       fragmentShader();\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -433,8 +448,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-                       scan.c[0] += scan.slopeC[0];\r
-                       scan.c[1] += scan.slopeC[1];\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -451,10 +466,10 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
        }\r
 \r
        // rasterize lower sub-triangle\r
-       if ( (f32) 0.0 != scan.invDeltaY[2] )\r
+       if (F32_GREATER_0(scan.invDeltaY[2]) )\r
        {\r
                // advance to middle point\r
-               if( (f32) 0.0 != scan.invDeltaY[1] )\r
+               if(F32_GREATER_0(scan.invDeltaY[1]) )\r
                {\r
                        temp[0] = b->Pos.y - a->Pos.y;  // dy\r
 \r
@@ -466,7 +481,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
                        scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
 #endif\r
 #ifdef IPOL_C0\r
-                       scan.c[0] = a->Color[0] + scan.slopeC[0] * temp[0];\r
+                       scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
 #endif\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
@@ -492,8 +507,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-               scan.slopeC[1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
-               scan.c[1] = b->Color[0];\r
+               scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+               scan.c[0][1] = b->Color[0];\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -507,8 +522,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -529,8 +544,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-               scan.c[0] += scan.slopeC[0] * subPixel;\r
-               scan.c[1] += scan.slopeC[1] * subPixel;\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -562,8 +577,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-                       line.c[scan.left] = scan.c[0];\r
-                       line.c[scan.right] = scan.c[1];\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -577,7 +592,7 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                        // render a scanline\r
-                       scanline_bilinear ( );\r
+                       fragmentShader( );\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -593,8 +608,8 @@ void CTRTextureGouraudAddNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
 #ifdef IPOL_C0\r
-                       scan.c[0] += scan.slopeC[0];\r
-                       scan.c[1] += scan.slopeC[1];\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
 #ifdef IPOL_T0\r
@@ -625,6 +640,20 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTRTextureGouraudAddNoZ2(CBurningVideoDriver* driver)\r
 {\r
+       /*\r
+       ETR_TEXTURE_GOURAUD_ADD_NO_Z\r
+       \r
+       Irrlicht:\r
+               Material.MaterialType = EMT_TRANSPARENT_ADD_COLOR;\r
+               Material.ZBuffer = ECFN_DISABLED;\r
+               -> need Material.ZWriteEnable off\r
+\r
+       OpenGL\r
+       glDisable(GL_DEPTH_TEST);\r
+       glDepthMask(GL_FALSE);\r
+       glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
+       */\r
+\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureGouraudAddNoZ2(driver);\r
        #else\r
index 37bb477c5e0a7a59676d277fa370aac5cec5984d..6e92235937bcd902449bbcacbb4960e979f36e2e 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -84,18 +84,12 @@ public:
        CTRTextureGouraudAlpha2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
-\r
-       virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
-\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
 \r
 private:\r
        void scanline_bilinear ();\r
 \r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
-\r
-       u32 AlphaRef;\r
 };\r
 \r
 //! constructor\r
@@ -105,19 +99,17 @@ CTRTextureGouraudAlpha2::CTRTextureGouraudAlpha2(CBurningVideoDriver* driver)
        #ifdef _DEBUG\r
        setDebugName("CTRTextureGouraudAlpha2");\r
        #endif\r
-\r
-       AlphaRef = 0;\r
 }\r
 \r
 \r
 /*!\r
 */\r
-void CTRTextureGouraudAlpha2::setParam ( u32 index, f32 value)\r
+void CTRTextureGouraudAlpha2::OnSetMaterial(const SBurningShaderMaterial& material)\r
 {\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
-       AlphaRef = core::floor32_fast( value * 256.f );\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+       AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);\r
 #else\r
-       AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );\r
+       AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
 #endif\r
 }\r
 \r
@@ -147,15 +139,15 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -163,7 +155,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -200,6 +192,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -209,17 +202,15 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
 \r
        f32 inversew = FIX_POINT_F32_MUL;\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
-       u32 dIndex = ( line.y & 3 ) << 2;\r
-\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+       u32 dIndex = (line.y & 3) << 2;\r
 #else\r
-       tFixPoint a0;\r
-       tFixPoint r0, g0, b0;\r
-#endif\r
+       tFixPoint a0, r0, g0, b0;\r
 \r
 #ifdef IPOL_C0\r
        tFixPoint r1, g1, b1;\r
        tFixPoint r2, g2, b2;\r
+#endif\r
 #endif\r
 \r
        for ( s32 i = 0; i <= dx; ++i )\r
@@ -233,7 +224,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
 \r
                {\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
 \r
                const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
 \r
@@ -245,7 +236,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
                                                                                        d + tofix ( line.t[0][0].y,inversew)\r
                                                                                        );\r
 \r
-               const u32 alpha = ( argb >> 24 );\r
+               const tFixPoint alpha = ( argb >> 24 );\r
                if ( alpha > AlphaRef )\r
                {\r
 #ifdef WRITE_Z\r
@@ -263,19 +254,14 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
 \r
 #ifdef INVERSE_W\r
                inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
                getSample_texture ( a0,r0,g0,b0,\r
                                                        &IT[0],\r
                                                        tofix ( line.t[0][0].x,inversew),\r
                                                        tofix ( line.t[0][0].y,inversew)\r
                                                );\r
-#else\r
-               getSample_texture ( a0,r0,g0,b0,\r
-                                                       &IT[0],\r
-                                                       tofix ( line.t[0][0].x),\r
-                                                       tofix ( line.t[0][0].y)\r
-                                               );\r
-#endif\r
-               if ( (tFixPointu) a0 > AlphaRef )\r
+\r
+               if ( a0 > AlphaRef )\r
                {\r
 #ifdef WRITE_Z\r
                        z[i] = line.z[0];\r
@@ -284,30 +270,23 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
                        z[i] = line.w[0];\r
 #endif\r
 \r
-#ifdef INVERSE_W\r
-                       getSample_color ( r2, g2, b2, line.c[0][0], inversew );\r
-#else\r
-                       getSample_color ( r2, g2, b2, line.c[0][0] );\r
-#endif\r
-                       r0 = imulFix ( r0, r2 );\r
-                       g0 = imulFix ( g0, g2 );\r
-                       b0 = imulFix ( b0, b2 );\r
+#ifdef IPOL_C0\r
+\r
+                       vec4_to_fix( r2, g2, b2, line.c[0][0], inversew );\r
+\r
+                       r0 = imulFix_simple( r0, r2 );\r
+                       g0 = imulFix_simple( g0, g2 );\r
+                       b0 = imulFix_simple( b0, b2 );\r
 \r
                        color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
-                       a0 >>= 8;\r
+                       fix_color_norm(a0);\r
 \r
                        r2 = r1 + imulFix ( a0, r0 - r1 );\r
                        g2 = g1 + imulFix ( a0, g0 - g1 );\r
                        b2 = b1 + imulFix ( a0, b0 - b1 );\r
-                       dst[i] = fix4_to_color ( a0, r2, g2, b2 );\r
+                       dst[i] = fix4_to_sample( a0, r2, g2, b2 );\r
 \r
-/*\r
-                       dst[i] = PixelBlend32 ( dst[i],\r
-                                                                       fix_to_color ( r0,g0, b0 ),\r
-                                                                       fixPointu_to_u32 ( a0 )\r
-                                                               );\r
-*/\r
 /*\r
                        getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );\r
                        color_to_fix ( r1, g1, b1, dst[i] );\r
@@ -315,9 +294,14 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
                        r2 = r0 + imulFix ( a0, r1 - r0 );\r
                        g2 = g0 + imulFix ( a0, g1 - g0 );\r
                        b2 = b0 + imulFix ( a0, b1 - b0 );\r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
+                       dst[i] = fix_to_sample ( r2, g2, b2 );\r
 */\r
-\r
+#else\r
+                       dst[i] = PixelBlend32 ( dst[i],\r
+                               fix_to_sample( r0,g0, b0 ),\r
+                                                                       fixPointu_to_u32 ( a0 )\r
+                                                               );\r
+#endif\r
                }\r
 #endif\r
 \r
@@ -342,7 +326,7 @@ void CTRTextureGouraudAlpha2::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -353,9 +337,9 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -441,8 +425,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -600,8 +584,8 @@ void CTRTextureGouraudAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -720,6 +704,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTRTextureGouraudAlpha(CBurningVideoDriver* driver)\r
 {\r
+       //ETR_TEXTURE_GOURAUD_ALPHA\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureGouraudAlpha2(driver);\r
        #else\r
index 2830247e93d97bd7ab220f2e86709ab04837d218..6a550334d906b3462d508f22ce17ce02e505639a 100644 (file)
@@ -21,6 +21,7 @@
 #undef INVERSE_W\r
 \r
 #undef IPOL_C0\r
+#undef IPOL_C1\r
 #undef IPOL_T0\r
 #undef IPOL_T1\r
 \r
@@ -34,6 +35,7 @@
 //#define WRITE_W\r
 \r
 #define IPOL_C0\r
+//#define IPOL_C1\r
 #define IPOL_T0\r
 //#define IPOL_T1\r
 \r
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+       #undef IPOL_C1\r
+#endif\r
+\r
 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
        #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
                #undef IPOL_W\r
@@ -84,18 +90,34 @@ public:
        CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
+\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
+       SBurningShaderMaterial Material;\r
 \r
-       virtual void setParam ( u32 index, f32 value) _IRR_OVERRIDE_;\r
+       virtual void setMaterial(const SBurningShaderMaterial &material)\r
+       {\r
+               Material = material;\r
+       }\r
 \r
+       virtual void setParam(u32 index, f32 value)\r
+       {\r
+               OnSetMaterial(Material);\r
+}\r
+#endif\r
 \r
 private:\r
-       void scanline_bilinear ();\r
 \r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
+       // fragment shader\r
+       typedef void (CTRTextureGouraudAlphaNoZ::*tFragmentShader) ();\r
+       void fragment_linear();\r
+       void fragment_linear_test();\r
+       void fragment_point_noz();\r
+\r
+       tFragmentShader fragmentShader;\r
+\r
 \r
-       u32 AlphaRef;\r
 };\r
 \r
 //! constructor\r
@@ -106,24 +128,37 @@ CTRTextureGouraudAlphaNoZ::CTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver
        setDebugName("CTRTextureGouraudAlphaNoZ");\r
        #endif\r
 \r
-       AlphaRef = 0;\r
+       fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;\r
 }\r
 \r
 \r
 /*!\r
 */\r
-void CTRTextureGouraudAlphaNoZ::setParam ( u32 index, f32 value)\r
+void CTRTextureGouraudAlphaNoZ::OnSetMaterial(const SBurningShaderMaterial& material)\r
 {\r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
-       AlphaRef = core::floor32_fast( value * 256.f );\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+       AlphaRef = core::floor32(material.org.MaterialTypeParam * 256.f);\r
 #else\r
-       AlphaRef = u32_to_fixPoint ( core::floor32_fast( value * 256.f ) );\r
+       AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
 #endif\r
+\r
+       //check triangle on w = 1.f instead..\r
+#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
+       if (material.Fallback_MaterialType == EMT_TRANSPARENT_ALPHA_CHANNEL_REF)\r
+               fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear_test;\r
+       else\r
+       if ( material.org.TextureLayer[0].BilinearFilter )\r
+               fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_linear;\r
+       else\r
+\r
+#endif\r
+               fragmentShader = &CTRTextureGouraudAlphaNoZ::fragment_point_noz;\r
+\r
 }\r
 \r
 /*!\r
 */\r
-void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()\r
+void CTRTextureGouraudAlphaNoZ::fragment_linear()\r
 {\r
        tVideoSample *dst;\r
 \r
@@ -147,15 +182,15 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS];\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -163,7 +198,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -174,6 +209,9 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 #ifdef IPOL_C0\r
        slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
 #endif\r
+#ifdef IPOL_C1\r
+       slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
 #ifdef IPOL_T0\r
        slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
 #endif\r
@@ -192,6 +230,9 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 #ifdef IPOL_C0\r
        line.c[0][0] += slopeC[0] * subPixel;\r
 #endif\r
+#ifdef IPOL_C1\r
+       line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
 #ifdef IPOL_T0\r
        line.t[0][0] += slopeT[0] * subPixel;\r
 #endif\r
@@ -200,6 +241,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -209,7 +251,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 \r
        f32 inversew = FIX_POINT_F32_MUL;\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
        u32 dIndex = ( line.y & 3 ) << 2;\r
 \r
 #else\r
@@ -219,7 +261,11 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 \r
 #ifdef IPOL_C0\r
        tFixPoint r1, g1, b1;\r
-       tFixPoint r2, g2, b2;\r
+       tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+       tFixPoint a3,r3, g3, b3;\r
 #endif\r
 \r
        for ( s32 i = 0; i <= dx; ++i )\r
@@ -233,7 +279,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 \r
                {\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
 \r
                const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
 \r
@@ -244,7 +290,7 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
                                                                                        d + tofix ( line.t[0][0].y,inversew)\r
                                                                                        );\r
 \r
-               const u32 alpha = ( argb >> 24 );\r
+               const tFixPoint alpha = ( argb >> 24 );\r
                if ( alpha > AlphaRef )\r
                {\r
 #ifdef WRITE_Z\r
@@ -262,19 +308,14 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 \r
 #ifdef INVERSE_W\r
                inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
                getSample_texture ( a0, r0, g0, b0,\r
                                                        &IT[0],\r
                                                        tofix ( line.t[0][0].x,inversew),\r
                                                        tofix ( line.t[0][0].y,inversew)\r
                                                );\r
-#else\r
-               getSample_texture ( a0, r0, g0,b0,\r
-                                                       &IT[0],\r
-                                                       tofix ( line.t[0][0].x),\r
-                                                       tofix ( line.t[0][0].y)\r
-                                               );\r
-#endif\r
-               if ( (tFixPointu) a0 > AlphaRef )\r
+\r
+               if ( a0 > AlphaRef )\r
                {\r
 #ifdef WRITE_Z\r
                        z[i] = line.z[0];\r
@@ -283,39 +324,30 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
                        z[i] = line.w[0];\r
 #endif\r
 \r
-#ifdef INVERSE_W\r
-                       getSample_color ( r2, g2, b2, line.c[0][0], inversew );\r
-#else\r
-                       getSample_color ( r2, g2, b2, line.c[0][0] );\r
-#endif\r
-                       r0 = imulFix ( r0, r2 );\r
-                       g0 = imulFix ( g0, g2 );\r
-                       b0 = imulFix ( b0, b2 );\r
+#ifdef IPOL_C0\r
+\r
+                       vec4_to_fix( a2,r2, g2, b2, line.c[0][0], inversew );\r
+\r
+                       //a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha\r
+                       r0 = imulFix_simple( r0, r2 );\r
+                       g0 = imulFix_simple( g0, g2 );\r
+                       b0 = imulFix_simple( b0, b2 );\r
 \r
                        color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
-                       a0 >>= 8;\r
+                       fix_color_norm(a0);\r
 \r
                        r2 = r1 + imulFix ( a0, r0 - r1 );\r
                        g2 = g1 + imulFix ( a0, g0 - g1 );\r
                        b2 = b1 + imulFix ( a0, b0 - b1 );\r
-                       dst[i] = fix4_to_color ( a0, r2, g2, b2 );\r
+                       dst[i] = fix4_to_sample( a0, r2, g2, b2 );\r
 \r
-/*\r
+#else\r
                        dst[i] = PixelBlend32 ( dst[i],\r
-                                                                       fix_to_color ( r0,g0, b0 ),\r
+                               fix_to_sample( r0,g0, b0 ),\r
                                                                        fixPointu_to_u32 ( a0 )\r
                                                                );\r
-*/\r
-/*\r
-                       getSample_color ( r2, g2, b2, line.c[0][0], inversew * COLOR_MAX );\r
-                       color_to_fix ( r1, g1, b1, dst[i] );\r
-\r
-                       r2 = r0 + imulFix ( a0, r1 - r0 );\r
-                       g2 = g0 + imulFix ( a0, g1 - g0 );\r
-                       b2 = b0 + imulFix ( a0, b1 - b0 );\r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
-*/\r
+#endif\r
 \r
                }\r
 #endif\r
@@ -331,6 +363,229 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 #ifdef IPOL_C0\r
                line.c[0][0] += slopeC[0];\r
 #endif\r
+#ifdef IPOL_C1\r
+               line.c[1][0] += slopeC[1];\r
+#endif\r
+#ifdef IPOL_T0\r
+               line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+               line.t[1][0] += slopeT[1];\r
+#endif\r
+       }\r
+\r
+}\r
+\r
+/*!\r
+*/\r
+void CTRTextureGouraudAlphaNoZ::fragment_linear_test()\r
+{\r
+       tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+       fp24 *z;\r
+#endif\r
+\r
+       s32 xStart;\r
+       s32 xEnd;\r
+       s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+       f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+       fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#ifdef IPOL_T0\r
+       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+       // apply top-left fill-convention, left\r
+       xStart = fill_convention_left(line.x[0]);\r
+       xEnd = fill_convention_right(line.x[1]);\r
+\r
+       dx = xEnd - xStart;\r
+\r
+       if (dx < 0)\r
+               return;\r
+\r
+       // slopes\r
+       const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+       slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+       slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+       slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+       slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+       subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+       line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+       line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+       line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_C1\r
+       line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+       line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+       line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+       dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+       z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+       f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+       u32 dIndex = (line.y & 3) << 2;\r
+\r
+#else\r
+       tFixPoint a0;\r
+       tFixPoint r0, g0, b0;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+       tFixPoint r1, g1, b1;\r
+       tFixPoint a2, r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+       tFixPoint a3, r3, g3, b3;\r
+#endif\r
+\r
+       for (s32 i = 0; i <= dx; ++i)\r
+       {\r
+#ifdef CMP_Z\r
+               if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+                       if (line.w[0] >= z[i])\r
+#endif\r
+\r
+                       {\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+\r
+                               const tFixPointu d = dithermask[dIndex | (i) & 3];\r
+\r
+#ifdef INVERSE_W\r
+                               inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+                               u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),\r
+                                       d + tofix(line.t[0][0].y, inversew)\r
+                               );\r
+\r
+                               const tFixPoint alpha = (argb >> 24);\r
+                               if (alpha > AlphaRef)\r
+                               {\r
+#ifdef WRITE_Z\r
+                                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                                       z[i] = line.w[0];\r
+#endif\r
+\r
+                                       dst[i] = PixelBlend32(dst[i], argb, alpha);\r
+                               }\r
+\r
+\r
+#else\r
+\r
+#ifdef INVERSE_W\r
+                               inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+                               getSample_texture(a0, r0, g0, b0,\r
+                                       &IT[0],\r
+                                       tofix(line.t[0][0].x, inversew),\r
+                                       tofix(line.t[0][0].y, inversew)\r
+                               );\r
+\r
+                               if (a0 > AlphaRef)\r
+                               {\r
+#ifdef WRITE_Z\r
+                                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                                       z[i] = line.w[0];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+\r
+                                       vec4_to_fix(a2, r2, g2, b2, line.c[0][0], inversew);\r
+\r
+                                       a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha\r
+                                       r0 = imulFix(r0, r2);\r
+                                       g0 = imulFix(g0, g2);\r
+                                       b0 = imulFix(b0, b2);\r
+\r
+                                       color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+                                       fix_color_norm(a0);\r
+\r
+                                       r2 = r1 + imulFix(a0, r0 - r1);\r
+                                       g2 = g1 + imulFix(a0, g0 - g1);\r
+                                       b2 = b1 + imulFix(a0, b0 - b1);\r
+                                       dst[i] = fix4_to_sample(a0, r2, g2, b2);\r
+\r
+#else\r
+                                       dst[i] = PixelBlend32(dst[i],\r
+                                               fix_to_sample(r0, g0, b0),\r
+                                               fixPointu_to_u32(a0)\r
+                                       );\r
+#endif\r
+\r
+                               }\r
+#endif\r
+\r
+                       }\r
+\r
+#ifdef IPOL_Z\r
+               line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+               line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+               line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+               line.c[1][0] += slopeC[1];\r
+#endif\r
 #ifdef IPOL_T0\r
                line.t[0][0] += slopeT[0];\r
 #endif\r
@@ -341,7 +596,227 @@ void CTRTextureGouraudAlphaNoZ::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+\r
+/*!\r
+*/\r
+void CTRTextureGouraudAlphaNoZ::fragment_point_noz()\r
+{\r
+       tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+       //fp24 *z;\r
+#endif\r
+\r
+       s32 xStart;\r
+       s32 xEnd;\r
+       s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+       f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+       fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#ifdef IPOL_T0\r
+       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+       // apply top-left fill-convention, left\r
+       xStart = fill_convention_left(line.x[0]);\r
+       xEnd = fill_convention_right(line.x[1]);\r
+\r
+       dx = xEnd - xStart;\r
+\r
+       if (dx < 0)\r
+               return;\r
+\r
+       // slopes\r
+       const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+       slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+       slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+       slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+       slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+       subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+       line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+       line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+       line.c[0][0] += slopeC[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_C1\r
+       line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+       line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+       line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+       dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+       //z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+       f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+       u32 dIndex = (line.y & 3) << 2;\r
+\r
+#else\r
+       tFixPoint a0;\r
+       tFixPoint r0, g0, b0;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+       tFixPoint r1, g1, b1;\r
+       tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+       tFixPoint a3, r3, g3, b3;\r
+#endif\r
+       for (s32 i = 0; i <= dx; ++i)\r
+       {\r
+#ifdef CMP_Z\r
+               if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+//                     if (line.w[0] >= z[i])\r
+#endif\r
+\r
+                       {\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+\r
+                               const tFixPointu d = dithermask[dIndex | (i) & 3];\r
+\r
+#ifdef INVERSE_W\r
+                               inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+                               u32 argb = getTexel_plain(&IT[0], d + tofix(line.t[0][0].x, inversew),\r
+                                       d + tofix(line.t[0][0].y, inversew)\r
+                               );\r
+\r
+                               const tFixPoint alpha = (argb >> 24);\r
+                               if (alpha > AlphaRef)\r
+                               {\r
+#ifdef WRITE_Z\r
+                                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                                       z[i] = line.w[0];\r
+#endif\r
+\r
+                                       dst[i] = PixelBlend32(dst[i], argb, alpha);\r
+                               }\r
+\r
+\r
+#else\r
+\r
+#ifdef INVERSE_W\r
+                               //inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+                       getTexel_fix(a0, r0, g0, b0,\r
+                                       &IT[0],\r
+                                       tofix(line.t[0][0].x, inversew),\r
+                                       tofix(line.t[0][0].y, inversew)\r
+                               );\r
+\r
+                               if (a0 > AlphaRef)\r
+                               {\r
+#ifdef WRITE_Z\r
+                                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                                       //z[i] = line.w[0];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+\r
+                                       vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);\r
+\r
+                                       a0 = imulFix(a0, a2); //2D uses vertexalpha*texelalpha\r
+                                       r0 = imulFix(r0, r2);\r
+                                       g0 = imulFix(g0, g2);\r
+                                       b0 = imulFix(b0, b2);\r
+\r
+                                       color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+                                       fix_color_norm(a0);\r
+\r
+                                       r2 = r1 + imulFix(a0, r0 - r1);\r
+                                       g2 = g1 + imulFix(a0, g0 - g1);\r
+                                       b2 = b1 + imulFix(a0, b0 - b1);\r
+                                       dst[i] = fix4_to_sample(a0, r2, g2, b2);\r
+\r
+#else\r
+                                       dst[i] = PixelBlend32(dst[i],\r
+                                               fix_to_sample(r0, g0, b0),\r
+                                               fixPointu_to_u32(a0)\r
+                                       );\r
+#endif\r
+\r
+                               }\r
+#endif\r
+\r
+                       }\r
+\r
+#ifdef IPOL_Z\r
+               line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+               //line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+               line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+               line.c[1][0] += slopeC[1];\r
+#endif\r
+#ifdef IPOL_T0\r
+               line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+               line.t[1][0] += slopeT[1];\r
+#endif\r
+       }\r
+\r
+}\r
+\r
+void CTRTextureGouraudAlphaNoZ::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -352,9 +827,9 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -389,6 +864,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
        scan.c[0][0] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+       scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+       scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
        scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
        scan.t[0][0] = a->Tex[0];\r
@@ -429,6 +909,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                scan.c[0][1] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+               scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
                scan.t[0][1] = a->Tex[0];\r
@@ -440,8 +925,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -465,6 +950,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -498,6 +988,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -509,7 +1004,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
 #endif\r
 \r
                        // render a scanline\r
-                       scanline_bilinear ( );\r
+                       (this->*fragmentShader) ();\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -529,6 +1024,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
@@ -560,6 +1060,10 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
 #ifdef IPOL_C0\r
                        scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
 #endif\r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
 #endif\r
@@ -588,6 +1092,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                scan.c[0][1] = b->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+               scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
                scan.t[0][1] = b->Tex[0];\r
@@ -599,8 +1108,8 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -625,6 +1134,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -658,6 +1172,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -669,7 +1188,7 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
 #endif\r
 \r
                        // render a scanline\r
-                       scanline_bilinear ( );\r
+                       (this->*fragmentShader) ();\r
 \r
                        scan.x[0] += scan.slopeX[0];\r
                        scan.x[1] += scan.slopeX[1];\r
@@ -689,6 +1208,11 @@ void CTRTextureGouraudAlphaNoZ::drawTriangle ( const s4DVertex *a,const s4DVerte
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
@@ -720,6 +1244,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)\r
 {\r
+       // ETR_TEXTURE_GOURAUD_ALPHA_NOZ\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureGouraudAlphaNoZ(driver);\r
        #else\r
@@ -728,6 +1253,7 @@ IBurningShader* createTRTextureGouraudAlphaNoZ(CBurningVideoDriver* driver)
 }\r
 \r
 \r
+\r
 } // end namespace video\r
 } // end namespace irr\r
 \r
index 6abc6e116765c71fe743c5e864e69433557f58a6..c2b4625d788a73c5bd191731aa08249b968aba0b 100644 (file)
@@ -42,7 +42,7 @@
 #define IPOL_T0\r
 //#define IPOL_T1\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -88,13 +88,11 @@ public:
        CTRTextureGouraudNoZ2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear ();\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
 \r
 };\r
 \r
@@ -142,8 +140,8 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -151,7 +149,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -188,6 +186,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -199,7 +198,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
 \r
        tFixPoint tx0;\r
        tFixPoint ty0;\r
-\r
+       tFixPoint r0, g0, b0;\r
 \r
        for ( s32 i = 0; i <= dx; ++i )\r
        {\r
@@ -216,12 +215,12 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
 #endif\r
                        tx0 = tofix ( line.t[0][0].x,inversew);\r
                        ty0 = tofix ( line.t[0][0].y,inversew);\r
-                       dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );\r
+                       //skybox\r
+                       //dst[i] = getTexel_plain ( &IT[0], tx0, ty0 );\r
+\r
+                       getSample_texture ( r0, g0, b0, IT+0, tx0, ty0 );\r
+                       dst[i] = fix_to_sample( r0, g0, b0 );\r
 \r
-/*\r
-                       getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
-                       dst[i] = fix_to_color ( r0, g0, b0 );\r
-*/\r
 #ifdef WRITE_Z\r
                        z[i] = line.z[0];\r
 #endif\r
@@ -249,7 +248,7 @@ void CTRTextureGouraudNoZ2::scanline_bilinear ( )
 \r
 }\r
 \r
-void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureGouraudNoZ2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -260,9 +259,9 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -348,8 +347,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -507,8 +506,8 @@ void CTRTextureGouraudNoZ2::drawTriangle ( const s4DVertex *a,const s4DVertex *b
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -626,6 +625,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTRTextureGouraudNoZ2(CBurningVideoDriver* driver)\r
 {\r
+       // ETR_TEXTURE_GOURAUD_NOZ\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureGouraudNoZ2( driver );\r
        #else\r
index 8da8e872435b959d9ceb1eb3e90fd238137849ab..4b9c4c20c15935b3286cafe8c47d9cd8d5940aeb 100644 (file)
@@ -21,6 +21,7 @@
 #undef INVERSE_W\r
 \r
 #undef IPOL_C0\r
+#undef IPOL_C1\r
 #undef IPOL_T0\r
 #undef IPOL_T1\r
 \r
@@ -34,6 +35,7 @@
 //#define WRITE_W\r
 \r
 #define IPOL_C0\r
+#define IPOL_C1\r
 #define IPOL_T0\r
 //#define IPOL_T1\r
 \r
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS < 2\r
+       #undef IPOL_C1\r
+#endif\r
+\r
+\r
 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
        #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
                #undef IPOL_W\r
@@ -82,13 +89,11 @@ public:
        CTRTextureVertexAlpha2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear ();\r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
 \r
 };\r
 \r
@@ -129,15 +134,15 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
        fp24 slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-       sVec4 slopeC;\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS];\r
 #endif\r
 #ifdef IPOL_T0\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -145,7 +150,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -154,7 +159,10 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
        slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
 #endif\r
 #ifdef IPOL_C0\r
-       slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+       slopeC[0] = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C1\r
+       slopeC[1] = (line.c[1][1] - line.c[1][0]) * invDeltaX;\r
 #endif\r
 #ifdef IPOL_T0\r
        slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
@@ -172,8 +180,12 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
        line.w[0] += slopeW * subPixel;\r
 #endif\r
 #ifdef IPOL_C0\r
-       line.c[0][0] += slopeC * subPixel;\r
+       line.c[0][0] += slopeC[0] * subPixel;\r
 #endif\r
+#ifdef IPOL_C1\r
+       line.c[1][0] += slopeC[1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
        line.t[0][0] += slopeT[0] * subPixel;\r
 #endif\r
@@ -182,6 +194,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -191,22 +204,18 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
 \r
        f32 inversew = FIX_POINT_F32_MUL;\r
 \r
-//#define __TEST_THIS\r
-\r
-#ifdef __TEST_THIS\r
-\r
-#else\r
        tFixPoint tx0;\r
        tFixPoint ty0;\r
 \r
        tFixPoint r0, g0, b0;\r
        tFixPoint r1, g1, b1;\r
-       tFixPoint r2, g2, b2;\r
-#endif\r
-\r
 \r
 #ifdef IPOL_C0\r
-       tFixPoint a3;\r
+       tFixPoint a2,r2, g2, b2;\r
+#endif\r
+\r
+#ifdef IPOL_C1\r
+       tFixPoint aFog = FIX_POINT_ONE;\r
 #endif\r
 \r
 \r
@@ -220,50 +229,74 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
 #endif\r
 \r
                {\r
-#ifdef __TEST_THIS\r
-\r
-                       inversew = fix_inverse32 ( line.w[0] );\r
-\r
-                       dst[i] = PixelAdd32 (\r
-                                               dst[i],\r
-                                       getTexel_plain ( &IT[0],        tofix ( line.t[0][0].x,inversew),\r
-                                                                                               tofix ( line.t[0][0].y,inversew) )\r
-                                                                                                 );\r
-\r
-#else\r
+#ifdef WRITE_Z\r
+                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                       z[i] = line.w[0];\r
+#endif\r
 \r
 #ifdef INVERSE_W\r
                        inversew = fix_inverse32 ( line.w[0] );\r
+#endif\r
+#ifdef IPOL_C1\r
+                       //complete inside fog\r
+                       if (TL_Flag & TL_FOG)\r
+                       {\r
+                               aFog = tofix(line.c[1][0].a, inversew);\r
+                               if (aFog <= 0)\r
+                               {\r
+                                       dst[i] = fog_color_sample;\r
+                                       continue;\r
+                               }\r
+                       }\r
 #endif\r
                        tx0 = tofix ( line.t[0][0].x,inversew);\r
                        ty0 = tofix ( line.t[0][0].y,inversew);\r
 \r
-#ifdef IPOL_C0\r
-                       a3 = tofix ( line.c[0][0].y,inversew );\r
-#endif\r
-\r
                        getSample_texture ( r0, g0, b0, &IT[0], tx0, ty0 );\r
                        color_to_fix ( r1, g1, b1, dst[i] );\r
 \r
 #ifdef IPOL_C0\r
-                       r2 = clampfix_maxcolor ( r1 + imulFix ( r0, a3 ) );\r
-                       g2 = clampfix_maxcolor ( g1 + imulFix ( g0, a3 ) );\r
-                       b2 = clampfix_maxcolor ( b1 + imulFix ( b0, a3 ) );\r
+                       vec4_to_fix(a2,r2, g2, b2, line.c[0][0], inversew);\r
+\r
+                       r0 = imulFix_simple(r0, r2);\r
+                       g0 = imulFix_simple(g0, g2);\r
+                       b0 = imulFix_simple(b0, b2);\r
+\r
+#ifdef IPOL_C1\r
+                       //specular highlight\r
+                       if (TL_Flag & TL_SPECULAR)\r
+                       {\r
+                               vec4_to_fix(r2, g2, b2, line.c[1][0], inversew*COLOR_MAX);\r
+                               r0 = clampfix_maxcolor(r2 + r0);\r
+                               g0 = clampfix_maxcolor(g2 + g0);\r
+                               b0 = clampfix_maxcolor(b2 + b0);\r
+                       }\r
+#endif\r
+                       //blend background\r
+                       r0 = r1 + imulFix(a2, r0 - r1);\r
+                       g0 = g1 + imulFix(a2, g0 - g1);\r
+                       b0 = b1 + imulFix(a2, b0 - b1);\r
+\r
+#ifdef IPOL_C1\r
+                       //mix with distance\r
+                       if (aFog < FIX_POINT_ONE) //TL_Flag & TL_FOG)\r
+                       {\r
+                               r0 = fog_color[1] + imulFix(aFog, r0 - fog_color[1]);\r
+                               g0 = fog_color[2] + imulFix(aFog, g0 - fog_color[2]);\r
+                               b0 = fog_color[3] + imulFix(aFog, b0 - fog_color[3]);\r
+                       }\r
+#endif\r
+\r
 #else\r
-                       r2 = clampfix_maxcolor ( r1 + r0 );\r
-                       g2 = clampfix_maxcolor ( g1 + g0 );\r
-                       b2 = clampfix_maxcolor ( b1 + b0 );\r
+                       r0 = clampfix_maxcolor ( r1 + r0 );\r
+                       g0 = clampfix_maxcolor ( g1 + g0 );\r
+                       b0 = clampfix_maxcolor ( b1 + b0 );\r
 #endif\r
 \r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
+                       dst[i] = fix_to_sample( r0, g0, b0 );\r
 \r
-#ifdef WRITE_Z\r
-                       z[i] = line.z[0];\r
-#endif\r
-#ifdef WRITE_W\r
-                       z[i] = line.w[0];\r
-#endif\r
-#endif\r
                }\r
 \r
 #ifdef IPOL_Z\r
@@ -273,7 +306,10 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
                line.w[0] += slopeW;\r
 #endif\r
 #ifdef IPOL_C0\r
-               line.c[0][0] += slopeC;\r
+               line.c[0][0] += slopeC[0];\r
+#endif\r
+#ifdef IPOL_C1\r
+               line.c[1][0] += slopeC[1];\r
 #endif\r
 #ifdef IPOL_T0\r
                line.t[0][0] += slopeT[0];\r
@@ -285,7 +321,7 @@ void CTRTextureVertexAlpha2::scanline_bilinear (  )
 \r
 }\r
 \r
-void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureVertexAlpha2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -296,9 +332,9 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -333,6 +369,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
        scan.c[0][0] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+       scan.slopeC[1][0] = (c->Color[1] - a->Color[1]) * scan.invDeltaY[0];\r
+       scan.c[1][0] = a->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
        scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
        scan.t[0][0] = a->Tex[0];\r
@@ -373,6 +414,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                scan.c[0][1] = a->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (b->Color[1] - a->Color[1]) * scan.invDeltaY[1];\r
+               scan.c[1][1] = a->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
                scan.t[0][1] = a->Tex[0];\r
@@ -384,8 +430,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -409,6 +455,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -442,6 +493,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -473,6 +529,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
@@ -504,6 +565,9 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #ifdef IPOL_C0\r
                        scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
 #endif\r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] = a->Color[1] + scan.slopeC[1][0] * temp[0];\r
+#endif\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
 #endif\r
@@ -532,6 +596,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                scan.c[0][1] = b->Color[0];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.slopeC[1][1] = (c->Color[1] - b->Color[1]) * scan.invDeltaY[2];\r
+               scan.c[1][1] = b->Color[1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
                scan.t[0][1] = b->Tex[0];\r
@@ -543,8 +612,8 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -569,6 +638,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+               scan.c[1][0] += scan.slopeC[1][0] * subPixel;\r
+               scan.c[1][1] += scan.slopeC[1][1] * subPixel;\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
                scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
@@ -602,6 +676,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                        line.c[0][scan.right] = scan.c[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       line.c[1][scan.left] = scan.c[1][0];\r
+                       line.c[1][scan.right] = scan.c[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        line.t[0][scan.left] = scan.t[0][0];\r
                        line.t[0][scan.right] = scan.t[0][1];\r
@@ -633,6 +712,11 @@ void CTRTextureVertexAlpha2::drawTriangle ( const s4DVertex *a,const s4DVertex *
                        scan.c[0][1] += scan.slopeC[0][1];\r
 #endif\r
 \r
+#ifdef IPOL_C1\r
+                       scan.c[1][0] += scan.slopeC[1][0];\r
+                       scan.c[1][1] += scan.slopeC[1][1];\r
+#endif\r
+\r
 #ifdef IPOL_T0\r
                        scan.t[0][0] += scan.slopeT[0][0];\r
                        scan.t[0][1] += scan.slopeT[0][1];\r
@@ -662,6 +746,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTriangleRendererTextureVertexAlpha2(CBurningVideoDriver* driver)\r
 {\r
+       /* ETR_TEXTURE_GOURAUD_VERTEX_ALPHA */\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureVertexAlpha2(driver);\r
        #else\r
index db49d53087a55c4647944bd3df8a9fc756e16f1f..d5cc7e320913601b7b33d3f2bcfd6eb95e9130ab 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -82,15 +82,12 @@ public:
        CTRTextureLightMap2_Add(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear ();\r
 \r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
-\r
 };\r
 \r
 //! constructor\r
@@ -137,8 +134,8 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -146,7 +143,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -183,6 +180,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -190,11 +188,10 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
 #endif\r
 \r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
        f32 inversew = FIX_POINT_F32_MUL;\r
-       u32 dIndex = ( line.y & 3 ) << 2;\r
-\r
 \r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+       u32 dIndex = ( line.y & 3 ) << 2;\r
 #else\r
        //\r
        tFixPoint r0, g0, b0;\r
@@ -219,11 +216,12 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
                        z[i] = line.w[0];\r
 #endif\r
 \r
-#ifdef BURNINGVIDEO_RENDERER_FAST\r
-\r
 #ifdef INVERSE_W\r
-                       inversew = fix_inverse32 ( line.w[0] );\r
+                       inversew = fix_inverse32(line.w[0]);\r
 #endif\r
+\r
+#if defined(BURNINGVIDEO_RENDERER_FAST) && COLOR_MAX==0xff\r
+\r
                        const tFixPointu d = dithermask [ dIndex | ( i ) & 3 ];\r
 \r
                        dst[i] = PixelAdd32 (\r
@@ -234,12 +232,11 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
                                                        );\r
 \r
 #else\r
-                       const f32 inversew = fix_inverse32 ( line.w[0] );\r
 \r
                        getSample_texture ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );\r
                        getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[0][1].x,inversew), tofix ( line.t[0][1].y,inversew) );\r
 \r
-                       dst[i] = fix_to_color ( clampfix_maxcolor ( r0 + r1 ),\r
+                       dst[i] = fix_to_sample( clampfix_maxcolor ( r0 + r1 ),\r
                                                                        clampfix_maxcolor ( g0 + g1 ),\r
                                                                        clampfix_maxcolor ( b0 + b1 )\r
                                                                );\r
@@ -266,7 +263,7 @@ REALINLINE void CTRTextureLightMap2_Add::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_Add::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -277,9 +274,9 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
                return;\r
@@ -365,8 +362,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -524,8 +521,8 @@ void CTRTextureLightMap2_Add::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
index 719527491316a724fab2ed70a6e71db06a9cf40c..1295d3c7ad20485784de8f8c6b67d89d5abee624 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -82,14 +82,12 @@ public:
        CTRTextureLightMap2_M1(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear2 ();\r
 \r
-       sScanLineData line;\r
-\r
 };\r
 \r
 //! constructor\r
@@ -115,15 +113,15 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
 \r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
        if ( dx < 0 )\r
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
        // search z-buffer for first not occulled pixel\r
        z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
@@ -170,6 +168,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
        line.z[0] = a;\r
        line.z[1] = b;\r
 #endif\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
        a = (f32) i + subPixel;\r
@@ -226,7 +225,7 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
 \r
 #endif\r
 \r
-                       dst[i] = fix_to_color ( imulFix_tex1 ( r0, r1 ),\r
+                       dst[i] = fix_to_sample( imulFix_tex1 ( r0, r1 ),\r
                                                                        imulFix_tex1 ( g0, g1 ),\r
                                                                        imulFix_tex1 ( b0, b1 )\r
                                                                );\r
@@ -244,9 +243,8 @@ REALINLINE void CTRTextureLightMap2_M1::scanline_bilinear2 ()
 }\r
 \r
 \r
-void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M1::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
-       sScanConvertData scan;\r
 \r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -257,9 +255,9 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
                return;\r
@@ -345,8 +343,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -505,8 +503,8 @@ void CTRTextureLightMap2_M1::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -626,6 +624,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTriangleRendererTextureLightMap2_M1(CBurningVideoDriver* driver)\r
 {\r
+       //ETR_TEXTURE_GOURAUD_LIGHTMAP_M1\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureLightMap2_M1(driver);\r
        #else\r
index f748990b3105e3c5c39763b05e378f9f84115aae..5976cfb8b97e38d400b223411cb6d492120d6870 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -82,14 +82,12 @@ public:
        CTRTextureLightMap2_M2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear2 ();\r
 \r
-       sScanLineData line;\r
-\r
 };\r
 \r
 //! constructor\r
@@ -115,15 +113,15 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
 \r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
        if ( dx < 0 )\r
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
        // search z-buffer for first not occulled pixel\r
        z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
@@ -170,6 +168,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
        line.z[0] = a;\r
        line.z[1] = b;\r
 #endif\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
        a = (f32) i + subPixel;\r
@@ -226,7 +225,7 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
 \r
 #endif\r
 \r
-                       dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
+                       dst[i] = fix_to_sample( clampfix_maxcolor ( imulFix_tex2 ( r0, r1 ) ),\r
                                                                        clampfix_maxcolor ( imulFix_tex2 ( g0, g1 ) ),\r
                                                                        clampfix_maxcolor ( imulFix_tex2 ( b0, b1 ) )\r
                                                                );\r
@@ -244,10 +243,8 @@ REALINLINE void CTRTextureLightMap2_M2::scanline_bilinear2 ()
 }\r
 \r
 \r
-void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
-       sScanConvertData scan;\r
-\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
        if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
@@ -257,9 +254,9 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
                return;\r
@@ -345,8 +342,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -505,8 +502,8 @@ void CTRTextureLightMap2_M2::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
index 3fd726cffce5281bef2ed947147b849299855f9e..b33a0e0cc84f00d178473f0071b77106ac286fc1 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -82,19 +82,21 @@ public:
        CTRTextureLightMap2_M4(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
 \r
-       void drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );\r
-       void drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );\r
-\r
-       void scanline_bilinear ();\r
+#if defined(SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)\r
+       void drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );\r
+       void drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c );\r
        void scanline_bilinear2_mag ();\r
        void scanline_bilinear2_min ();\r
+#else\r
+       #define scanline_bilinear2_mag scanline_bilinear\r
+#endif\r
 \r
-       sScanLineData line;\r
+       void scanline_bilinear ();\r
 \r
 };\r
 \r
@@ -109,14 +111,14 @@ CTRTextureLightMap2_M4::CTRTextureLightMap2_M4(CBurningVideoDriver* driver)
 \r
 /*!\r
 */\r
-REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()\r
+void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()\r
 {\r
        tVideoSample *dst;\r
        fp24 *z;\r
 \r
        // apply top-left fill-convention, left\r
-       const s32 xStart = irr::core::ceil32_fast( line.x[0] );\r
-       const s32 xEnd = irr::core::ceil32_fast( line.x[1] ) - 1;\r
+       const s32 xStart = fill_convention_left(line.x[0]);\r
+       const s32 xEnd = fill_convention_right(line.x[1]);\r
        s32 dx;\r
        s32 i;\r
 \r
@@ -125,8 +127,10 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
        if ( dx < 0 )\r
                return;\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+\r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
        // search z-buffer for first not occulled pixel\r
        i = ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
@@ -229,11 +233,7 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
                        getSample_texture ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );\r
 \r
 #endif\r
-\r
-                       dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),\r
-                                                                       clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),\r
-                                                                       clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )\r
-                                                               );\r
+                       dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));\r
                }\r
 \r
 #ifdef IPOL_W\r
@@ -248,7 +248,8 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_mag ()
 }\r
 \r
 \r
-REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()\r
+#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)\r
+void CTRTextureLightMap2_M4::scanline_bilinear2_min ()\r
 {\r
        tVideoSample *dst;\r
        fp24 *z;\r
@@ -260,15 +261,17 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
 \r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left(line.x[0]);\r
+       xEnd = fill_convention_right(line.x[1]);\r
 \r
        dx = xEnd - xStart;\r
        if ( dx < 0 )\r
                return;\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+\r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
        // search z-buffer for first not occulled pixel\r
        z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
@@ -315,6 +318,7 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
        line.z[0] = a;\r
        line.z[1] = b;\r
 #endif\r
+\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
        a = (f32) i + subPixel;\r
@@ -352,10 +356,7 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
                        getTexel_fix ( r0, g0, b0, &IT[0], tofix ( line.t[0][0].x,inversew), tofix ( line.t[0][0].y,inversew) );\r
                        getTexel_fix ( r1, g1, b1, &IT[1], tofix ( line.t[1][0].x,inversew), tofix ( line.t[1][0].y,inversew) );\r
 \r
-                       dst[i] = fix_to_color ( clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) ),\r
-                                                                       clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) ),\r
-                                                                       clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) )\r
-                                                               );\r
+                       dst[i] = fix_to_sample(imulFix_tex4(r0, r1), imulFix_tex4(g0, g1), imulFix_tex4(b0, b1));\r
                }\r
 \r
 #ifdef IPOL_W\r
@@ -369,21 +370,20 @@ REALINLINE void CTRTextureLightMap2_M4::scanline_bilinear2_min ()
 \r
 }\r
 \r
-//#ifdef BURNINGVIDEO_RENDERER_FAST\r
-#if 1\r
-\r
-void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
-       if ( IT[0].lodLevel <= 2 )\r
-               drawTriangle_Mag ( a, b, c );\r
+       if (IT[0].lodFactor < 4)\r
+       {\r
+               drawTriangle_Mag(a, b, c);\r
+       }\r
        else\r
-               drawTriangle_Min ( a, b, c );\r
+       {\r
+               drawTriangle_Min(a, b, c);\r
+       }\r
 }\r
 \r
-void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )\r
 {\r
-       sScanConvertData scan;\r
-\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
        if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
@@ -393,9 +393,9 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
                return;\r
@@ -481,8 +481,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -641,8 +641,8 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -746,16 +746,15 @@ void CTRTextureLightMap2_M4::drawTriangle_Min ( const s4DVertex *a,const s4DVert
 \r
 }\r
 \r
-void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle_Mag ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )\r
 \r
-#else\r
+#else //#if defined (SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN)\r
 \r
-void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 \r
 #endif\r
 \r
 {\r
-       sScanConvertData scan;\r
 \r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -765,14 +764,18 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
        const f32 ca = c->Pos.y - a->Pos.y;\r
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
-       // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
 \r
-       if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
+       if ( F32_LOWER_EQUAL_0 ( ca )  )\r
                return;\r
 \r
+       // calculate delta y of the edges\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
+\r
+       //if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] )  )\r
+       //      return;\r
+\r
        // find if the major edge is left or right aligned\r
        f32 temp[4];\r
 \r
@@ -855,8 +858,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -1015,8 +1018,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
@@ -1120,6 +1123,8 @@ void CTRTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *
 \r
 }\r
 \r
+#undef scanline_bilinear2_mag\r
+\r
 } // end namespace video\r
 } // end namespace irr\r
 \r
index 64a14ab4611fe558a49e98b1a9b1f10d2b44c729..55e7ffc0addc0f5b6fd535e072015ca83672db3e 100644 (file)
@@ -46,7 +46,7 @@
        #undef SUBTEXEL\r
 #endif\r
 \r
-#ifndef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
        #undef IPOL_C0\r
 #endif\r
 \r
@@ -82,15 +82,12 @@ public:
        CTRGTextureLightMap2_M4(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
 \r
 \r
 private:\r
        void scanline_bilinear ();\r
 \r
-       sScanConvertData scan;\r
-       sScanLineData line;\r
-\r
 };\r
 \r
 //! constructor\r
@@ -137,8 +134,8 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
 #endif\r
 \r
        // apply top-left fill-convention, left\r
-       xStart = core::ceil32_fast( line.x[0] );\r
-       xEnd = core::ceil32_fast( line.x[1] ) - 1;\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
 \r
        dx = xEnd - xStart;\r
 \r
@@ -146,7 +143,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
                return;\r
 \r
        // slopes\r
-       const f32 invDeltaX = core::reciprocal_approxim ( line.x[1] - line.x[0] );\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
 \r
 #ifdef IPOL_Z\r
        slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
@@ -183,6 +180,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
 #endif\r
 #endif\r
 \r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
        dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
 \r
 #ifdef USE_ZBUFFER\r
@@ -230,26 +228,22 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
                        getSample_texture ( r1, g1, b1, &IT[1], tx1, ty1 );\r
 \r
 #ifdef IPOL_C0\r
-                       r2 = imulFix ( r0, r3 );\r
-                       g2 = imulFix ( g0, g3 );\r
-                       b2 = imulFix ( b0, b3 );\r
-\r
-                       r2 = clampfix_maxcolor ( imulFix_tex4 ( r2, r1 ) );\r
-                       g2 = clampfix_maxcolor ( imulFix_tex4 ( g2, g1 ) );\r
-                       b2 = clampfix_maxcolor ( imulFix_tex4 ( b2, b1 ) );\r
-/*\r
-                       r2 = r3 << 8;\r
-                       g2 = g3 << 8;\r
-                       b2 = b3 << 8;\r
-*/\r
+                       r2 = imulFix_simple( r0, r3 );\r
+                       g2 = imulFix_simple( g0, g3 );\r
+                       b2 = imulFix_simple( b0, b3 );\r
+\r
+                       r2 = imulFix_tex4 ( r2, r1 );\r
+                       g2 = imulFix_tex4 ( g2, g1 );\r
+                       b2 = imulFix_tex4 ( b2, b1 );\r
+\r
 #else\r
-                       r2 = clampfix_maxcolor ( imulFix_tex4 ( r0, r1 ) );\r
-                       g2 = clampfix_maxcolor ( imulFix_tex4 ( g0, g1 ) );\r
-                       b2 = clampfix_maxcolor ( imulFix_tex4 ( b0, b1 ) );\r
+                       r2 = imulFix_tex4 ( r0, r1 );\r
+                       g2 = imulFix_tex4 ( g0, g1 );\r
+                       b2 = imulFix_tex4 ( b0, b1 );\r
 #endif\r
 \r
 \r
-                       dst[i] = fix_to_color ( r2, g2, b2 );\r
+                       dst[i] = fix_to_sample( r2, g2, b2 );\r
 \r
 #ifdef WRITE_Z\r
                        z[i] = line.z[0];\r
@@ -278,7 +272,7 @@ void CTRGTextureLightMap2_M4::scanline_bilinear ()
 \r
 }\r
 \r
-void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRGTextureLightMap2_M4::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
 {\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
@@ -289,9 +283,9 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
        const f32 ba = b->Pos.y - a->Pos.y;\r
        const f32 cb = c->Pos.y - b->Pos.y;\r
        // calculate delta y of the edges\r
-       scan.invDeltaY[0] = core::reciprocal( ca );\r
-       scan.invDeltaY[1] = core::reciprocal( ba );\r
-       scan.invDeltaY[2] = core::reciprocal( cb );\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
 \r
        if ( F32_LOWER_0 ( scan.invDeltaY[0] )  )\r
                return;\r
@@ -379,8 +373,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( a->Pos.y );\r
-               yEnd = core::ceil32_fast( b->Pos.y ) - 1;\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
                subPixel = ( (f32) yStart ) - a->Pos.y;\r
@@ -540,8 +534,8 @@ void CTRGTextureLightMap2_M4::drawTriangle ( const s4DVertex *a,const s4DVertex
 #endif\r
 \r
                // apply top-left fill convention, top part\r
-               yStart = core::ceil32_fast( b->Pos.y );\r
-               yEnd = core::ceil32_fast( c->Pos.y ) - 1;\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
 \r
 #ifdef SUBTEXEL\r
 \r
index e1bb8ba68d4c7af8aab7b6843084d021a8716c14..b77b788f41cbc8d08b90e21e560c70cc7c488789 100644 (file)
 #define SUBTEXEL\r
 #define INVERSE_W\r
 \r
-#define USE_ZBUFFER\r
+//#define USE_ZBUFFER\r
 #define IPOL_W\r
-#define CMP_W\r
-#define WRITE_W\r
+//#define CMP_W\r
+//#define WRITE_W\r
 \r
 \r
-//#define IPOL_C0\r
-#define IPOL_T0\r
+#define IPOL_C0\r
+//#define IPOL_T0\r
 //#define IPOL_T1\r
 \r
 // apply global override\r
        #undef SUBTEXEL\r
 #endif\r
 \r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+       #undef IPOL_C0\r
+#endif\r
+\r
 #if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
        #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
                #undef IPOL_W\r
@@ -80,14 +84,17 @@ public:
        CTRTextureWire2(CBurningVideoDriver* driver);\r
 \r
        //! draws an indexed triangle list\r
-       virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) _IRR_OVERRIDE_;\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
        virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) _IRR_OVERRIDE_;\r
+       virtual void drawPoint( const s4DVertex *a) _IRR_OVERRIDE_;\r
+       virtual bool canWireFrame () _IRR_OVERRIDE_  { return true; }\r
+       virtual bool canPointCloud() _IRR_OVERRIDE_  { return true; }\r
 \r
+protected:\r
+       virtual void scanline_bilinear ();\r
 \r
-\r
-private:\r
        void renderAlphaLine ( const s4DVertex *a,const s4DVertex *b ) const;\r
-       void renderLine ( const s4DVertex *a,const s4DVertex *b ) const;\r
+       void renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero = 0 ) const;\r
 \r
 };\r
 \r
@@ -101,26 +108,22 @@ CTRTextureWire2::CTRTextureWire2(CBurningVideoDriver* driver)
 }\r
 \r
 \r
-// swap integer with xor\r
-static inline void swap_xor ( s32 &a, s32 &b )\r
-{\r
-       a ^= b;\r
-       b ^= a;\r
-       a ^= b;\r
-}\r
-\r
 \r
 /*!\r
+       2d line\r
 */\r
-void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const\r
+void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b, int renderZero) const\r
 {\r
        int pitch0 = RenderTarget->getDimension().Width << VIDEO_SAMPLE_GRANULARITY;\r
+#ifdef USE_ZBUFFER\r
        int pitch1 = RenderTarget->getDimension().Width << 2;\r
+#endif\r
 \r
-       int aposx = (int) a->Pos.x;\r
-       int aposy = (int) a->Pos.y;\r
-       int bposx = (int) b->Pos.x;\r
-       int bposy = (int) b->Pos.y;\r
+       //todo:!\r
+       int aposx = fill_convention_none(a->Pos.x);\r
+       int aposy = fill_convention_none(a->Pos.y);\r
+       int bposx = fill_convention_none(b->Pos.x);\r
+       int bposy = fill_convention_none(b->Pos.y);\r
 \r
        int dx = bposx - aposx;\r
        int dy = bposy - aposy;\r
@@ -138,37 +141,39 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
        int xInc0 = 1 << VIDEO_SAMPLE_GRANULARITY;\r
        int yInc0 = pitch0;\r
 \r
+#ifdef USE_ZBUFFER\r
        int xInc1 = 4;\r
        int yInc1 = pitch1;\r
-\r
-       tVideoSample color;\r
-\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-       tFixPoint r0, g0, b0;\r
-       getSample_color ( r0, g0, b0, a->Color[0] );\r
-       color = fix_to_color ( r0, g0, b0 );\r
-#else\r
-       color = (tVideoSample) 0xFFFFFFFF;\r
 #endif\r
 \r
        if ( dx < 0 )\r
        {\r
                xInc0 = - ( 1 << VIDEO_SAMPLE_GRANULARITY);\r
+#ifdef USE_ZBUFFER\r
                xInc1 = -4;\r
+#endif\r
                dx = -dx;\r
        }\r
 \r
        if ( dy > dx )\r
        {\r
-               swap_xor ( dx, dy );\r
-               swap_xor ( xInc0, yInc0 );\r
-               swap_xor ( xInc1, yInc1 );\r
+               //swap\r
+               register s32 t;\r
+               t = dx;dx=dy;dy=t;\r
+               t = xInc0;xInc0=yInc0;yInc0=t;\r
+#ifdef USE_ZBUFFER\r
+               t = xInc1;xInc1=yInc1;yInc1=t;\r
+#endif\r
        }\r
 \r
-       if ( 0 == dx )\r
-               return;\r
+       if (0 == dx)\r
+       {\r
+               if (!renderZero) return;\r
+               dx = 1;\r
+       }\r
 \r
-       dst = (tVideoSample*) ( (u8*) (tVideoSample*)RenderTarget->getData() + ( aposy * pitch0 ) + (aposx << VIDEO_SAMPLE_GRANULARITY ) );\r
+       SOFTWARE_DRIVER_2_CLIPCHECK_WIRE;\r
+       dst = (tVideoSample*) ( (u8*) RenderTarget->getData() + ( aposy * pitch0 ) + (aposx* (1<< VIDEO_SAMPLE_GRANULARITY) ) );\r
 #ifdef USE_ZBUFFER\r
        z = (fp24*) ( (u8*) (fp24*) DepthBuffer->lock() + ( aposy * pitch1 ) + (aposx << 2 ) );\r
 #endif\r
@@ -176,16 +181,43 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
        c = dx << 1;\r
        m = dy << 1;\r
 \r
+       // slopes\r
+       const f32 invDeltaX = reciprocal_zero2( (f32)dx );\r
+\r
 #ifdef IPOL_Z\r
-       f32 slopeZ = (b->Pos.z - a->Pos.z) / f32(dx);\r
+       f32 slopeZ = (b->Pos.z - a->Pos.z) * invDeltaX;\r
        f32 dataZ = a->Pos.z;\r
 #endif\r
 \r
 #ifdef IPOL_W\r
-       fp24 slopeW = (b->Pos.w - a->Pos.w) / f32( dx );\r
+       fp24 slopeW = (b->Pos.w - a->Pos.w) * invDeltaX;\r
        fp24 dataW = a->Pos.w;\r
 #endif\r
 \r
+       f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+       tVideoSample color;\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+       tFixPoint r0, g0, b0;\r
+#ifdef IPOL_C0\r
+       sVec4 slopeC;\r
+       sVec4 C;\r
+       slopeC = (b->Color[0] - a->Color[0]) * invDeltaX;\r
+       C = a->Color[0];\r
+#endif\r
+\r
+#ifdef INVERSE_W\r
+       inversew = fix_inverse32_color(dataW);\r
+#endif\r
+\r
+       vec4_to_fix( r0, g0, b0, a->Color[0], inversew);\r
+       color = fix_to_sample( r0, g0, b0 );\r
+\r
+#else\r
+       color = (tVideoSample) 0xFFFFFFFF;\r
+#endif\r
+\r
+\r
        run = dx;\r
        while ( run )\r
        {\r
@@ -203,15 +235,22 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
                        *z = dataW;\r
 #endif\r
 \r
-               *dst = color;\r
+#ifdef IPOL_C0\r
+#ifdef INVERSE_W\r
+                       inversew = fix_inverse32_color(dataW);\r
+#endif\r
+                       vec4_to_fix(r0, g0, b0, C,inversew);\r
+                       color = fix_to_sample( r0, g0, b0 );\r
+#endif\r
+                       *dst = color;\r
 \r
                }\r
 \r
                dst = (tVideoSample*) ( (u8*) dst + xInc0 );    // x += xInc\r
-#ifdef IPOL_Z\r
+#ifdef CMP_Z\r
                z = (fp24*) ( (u8*) z + xInc1 );\r
 #endif\r
-#ifdef IPOL_W\r
+#ifdef CMP_W\r
                z = (fp24*) ( (u8*) z + xInc1 );\r
 #endif\r
 \r
@@ -219,10 +258,10 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
                if ( d > dx )\r
                {\r
                        dst = (tVideoSample*) ( (u8*) dst + yInc0 );    // y += yInc\r
-#ifdef IPOL_Z\r
+#ifdef CMP_Z\r
                        z = (fp24*) ( (u8*) z + yInc1 );\r
 #endif\r
-#ifdef IPOL_W\r
+#ifdef CMP_W\r
                        z = (fp24*) ( (u8*) z + yInc1 );\r
 #endif\r
 \r
@@ -235,15 +274,21 @@ void CTRTextureWire2::renderLine ( const s4DVertex *a,const s4DVertex *b ) const
 #ifdef IPOL_W\r
                dataW += slopeW;\r
 #endif\r
+#ifdef IPOL_C0\r
+               C += slopeC;\r
+#endif\r
+\r
 \r
        }\r
 \r
 }\r
 \r
-void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+void CTRTextureWire2::scanline_bilinear()\r
 {\r
-       sScanLineData line;\r
+}\r
 \r
+void CTRTextureWire2::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
+{\r
        // sort on height, y\r
        if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
        if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
@@ -258,14 +303,17 @@ void CTRTextureWire2::drawTriangle ( const s4DVertex *a,const s4DVertex *b,const
 \r
 void CTRTextureWire2::drawLine ( const s4DVertex *a,const s4DVertex *b)\r
 {\r
-\r
        // query access to TexMaps\r
 \r
        // sort on height, y\r
-       if ( a->Pos.y > b->Pos.y ) swapVertexPointer(&a, &b);\r
+       if (F32_A_GREATER_B(a->Pos.y,b->Pos.y )) swapVertexPointer(&a, &b);\r
 \r
        renderLine ( a, b );\r
+}\r
 \r
+void CTRTextureWire2::drawPoint(const s4DVertex *a)\r
+{\r
+       if ( (a->flag & VERTEX4D_CLIPMASK ) == VERTEX4D_INSIDE ) renderLine(a, a,1);\r
 }\r
 \r
 \r
@@ -283,6 +331,7 @@ namespace video
 //! creates a flat triangle renderer\r
 IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver)\r
 {\r
+       //ETR_TEXTURE_GOURAUD_WIRE\r
        #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
        return new CTRTextureWire2(driver);\r
        #else\r
diff --git a/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp b/source/Irrlicht/CTR_transparent_reflection_2_layer.cpp
new file mode 100644 (file)
index 0000000..8fb9214
--- /dev/null
@@ -0,0 +1,729 @@
+// 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 "IBurningShader.h"\r
+\r
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+// compile flag for this file\r
+#undef USE_ZBUFFER\r
+#undef IPOL_Z\r
+#undef CMP_Z\r
+#undef WRITE_Z\r
+\r
+#undef IPOL_W\r
+#undef CMP_W\r
+#undef WRITE_W\r
+\r
+#undef SUBTEXEL\r
+#undef INVERSE_W\r
+\r
+#undef IPOL_C0\r
+#undef IPOL_T0\r
+#undef IPOL_T1\r
+\r
+// define render case\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+\r
+#define USE_ZBUFFER\r
+#define IPOL_W\r
+#define CMP_W\r
+#define WRITE_W\r
+\r
+#define IPOL_C0\r
+#define IPOL_T0\r
+#define IPOL_T1\r
+\r
+// apply global override\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+       #undef INVERSE_W\r
+#endif\r
+\r
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
+       #undef SUBTEXEL\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+       #undef IPOL_C0\r
+#endif\r
+\r
+#if !defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) && defined ( USE_ZBUFFER )\r
+       #ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+               #undef IPOL_W\r
+       #endif\r
+       #define IPOL_Z\r
+\r
+       #ifdef CMP_W\r
+               #undef CMP_W\r
+               #define CMP_Z\r
+       #endif\r
+\r
+       #ifdef WRITE_W\r
+               #undef WRITE_W\r
+               #define WRITE_Z\r
+       #endif\r
+\r
+#endif\r
+\r
+namespace irr\r
+{\r
+\r
+namespace video\r
+{\r
+\r
+class CTR_transparent_reflection_2_layer : public IBurningShader\r
+{\r
+public:\r
+\r
+       //! constructor\r
+       CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver);\r
+\r
+       //! draws an indexed triangle list\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
+\r
+private:\r
+       void fragmentShader();\r
+\r
+       E_MATERIAL_TYPE MaterialType;\r
+\r
+};\r
+\r
+//! constructor\r
+CTR_transparent_reflection_2_layer::CTR_transparent_reflection_2_layer(CBurningVideoDriver* driver)\r
+: IBurningShader(driver)\r
+{\r
+       #ifdef _DEBUG\r
+       setDebugName("CTR_transparent_reflection_2_layer");\r
+       #endif\r
+}\r
+\r
+void CTR_transparent_reflection_2_layer::OnSetMaterial(const SBurningShaderMaterial& material)\r
+{\r
+       MaterialType = material.org.MaterialType;\r
+\r
+}\r
+\r
+/*!\r
+*/\r
+void CTR_transparent_reflection_2_layer::fragmentShader()\r
+{\r
+       tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+       fp24 *z;\r
+#endif\r
+\r
+       s32 xStart;\r
+       s32 xEnd;\r
+       s32 dx;\r
+\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+       f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+       fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+       sVec4 slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+       // apply top-left fill-convention, left\r
+       xStart = fill_convention_left( line.x[0] );\r
+       xEnd = fill_convention_right( line.x[1] );\r
+\r
+       dx = xEnd - xStart;\r
+\r
+       if ( dx < 0 )\r
+               return;\r
+\r
+       // slopes\r
+       const f32 invDeltaX = reciprocal_zero2( line.x[1] - line.x[0] );\r
+\r
+#ifdef IPOL_Z\r
+       slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+       slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+       slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+       subPixel = ( (f32) xStart ) - line.x[0];\r
+#ifdef IPOL_Z\r
+       line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+       line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+       line.c[0][0] += slopeC * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+       line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+       line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+       dst = (tVideoSample*)RenderTarget->getData() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+       z = (fp24*) DepthBuffer->lock() + ( line.y * RenderTarget->getDimension().Width ) + xStart;\r
+#endif\r
+\r
+\r
+       f32 inversew = FIX_POINT_F32_MUL;\r
+\r
+       tFixPoint r0, g0, b0;\r
+       tFixPoint r1, g1, b1;\r
+\r
+#ifdef IPOL_C0\r
+       tFixPoint a1;\r
+#endif\r
+\r
+       switch(MaterialType) {\r
+       default:\r
+       case EMT_REFLECTION_2_LAYER:\r
+       for (s32 i = 0; i <= dx; ++i)\r
+       {\r
+#ifdef CMP_Z\r
+               if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+               if (line.w[0] >= z[i])\r
+#endif\r
+               {\r
+\r
+#ifdef INVERSE_W\r
+               inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+\r
+               getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));\r
+               getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));\r
+\r
+               r0 = imulFix_tex1(r0, r1);\r
+               g0 = imulFix_tex1(g0, g1);\r
+               b0 = imulFix_tex1(b0, b1);\r
+\r
+#ifdef IPOL_C0\r
+               vec4_to_fix(r1, g1, b1, line.c[0][0], inversew);\r
+               r0 = imulFix_simple(r1, r0);\r
+               g0 = imulFix_simple(g1, g0);\r
+               b0 = imulFix_simple(b1, b0);\r
+#endif\r
+\r
+               dst[i] = fix_to_sample(r0, g0, b0);\r
+\r
+#ifdef WRITE_Z\r
+               z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+               z[i] = line.w[0];\r
+#endif\r
+               }\r
+\r
+#ifdef IPOL_Z\r
+               line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+               line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+               line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+               line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+               line.t[1][0] += slopeT[1];\r
+#endif\r
+       }\r
+       break;\r
+\r
+       case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
+       for (s32 i = 0; i <= dx; ++i)\r
+       {\r
+#ifdef CMP_Z\r
+       if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+       if (line.w[0] >= z[i])\r
+#endif\r
+       {\r
+\r
+#ifdef INVERSE_W\r
+               inversew = fix_inverse32(line.w[0]);\r
+#endif\r
+\r
+               getSample_texture(r0, g0, b0, &IT[0], tofix(line.t[0][0].x, inversew), tofix(line.t[0][0].y, inversew));\r
+               getSample_texture(r1, g1, b1, &IT[1], tofix(line.t[1][0].x, inversew), tofix(line.t[1][0].y, inversew));\r
+\r
+               r0 = imulFix_tex1(r0, r1);\r
+               g0 = imulFix_tex1(g0, g1);\r
+               b0 = imulFix_tex1(b0, b1);\r
+\r
+#ifdef IPOL_C0\r
+               vec4_to_fix(a1, r1, g1, b1, line.c[0][0], inversew);\r
+               r0 = imulFix_simple(r1, r0);\r
+               g0 = imulFix_simple(g1, g0);\r
+               b0 = imulFix_simple(b1, b0);\r
+\r
+               //vertex alpha blend EMT_TRANSPARENT_REFLECTION_2_LAYER\r
+               if (a1 + 2 < FIX_POINT_ONE)\r
+               {\r
+                       color_to_fix(r1, g1, b1, dst[i]);\r
+                       r0 = r1 + imulFix(a1, r0 - r1);\r
+                       g0 = g1 + imulFix(a1, g0 - g1);\r
+                       b0 = b1 + imulFix(a1, b0 - b1);\r
+               }\r
+#endif\r
+\r
+               dst[i] = fix_to_sample(r0, g0, b0);\r
+\r
+#ifdef WRITE_Z\r
+               //z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+               //z[i] = line.w[0];\r
+#endif\r
+       }\r
+\r
+#ifdef IPOL_Z\r
+       line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+       line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+       line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+       line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+       line.t[1][0] += slopeT[1];\r
+#endif\r
+       }\r
+       break;\r
+\r
+       }\r
+\r
+\r
+}\r
+\r
+void CTR_transparent_reflection_2_layer::drawTriangle ( const s4DVertex* burning_restrict a,const s4DVertex* burning_restrict b,const s4DVertex* burning_restrict c )\r
+{\r
+       // sort on height, y\r
+       if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
+       if ( F32_A_GREATER_B ( b->Pos.y , c->Pos.y ) ) swapVertexPointer(&b, &c);\r
+       if ( F32_A_GREATER_B ( a->Pos.y , b->Pos.y ) ) swapVertexPointer(&a, &b);\r
+\r
+       const f32 ca = c->Pos.y - a->Pos.y;\r
+       const f32 ba = b->Pos.y - a->Pos.y;\r
+       const f32 cb = c->Pos.y - b->Pos.y;\r
+       // calculate delta y of the edges\r
+       scan.invDeltaY[0] = reciprocal_zero( ca );\r
+       scan.invDeltaY[1] = reciprocal_zero( ba );\r
+       scan.invDeltaY[2] = reciprocal_zero( cb );\r
+\r
+       if ( F32_LOWER_EQUAL_0 ( scan.invDeltaY[0] ) )\r
+               return;\r
+\r
+       // find if the major edge is left or right aligned\r
+       f32 temp[4];\r
+\r
+       temp[0] = a->Pos.x - c->Pos.x;\r
+       temp[1] = -ca;\r
+       temp[2] = b->Pos.x - a->Pos.x;\r
+       temp[3] = ba;\r
+\r
+       scan.left = ( temp[0] * temp[3] - temp[1] * temp[2] ) > 0.f ? 0 : 1;\r
+       scan.right = 1 - scan.left;\r
+\r
+       // calculate slopes for the major edge\r
+       scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];\r
+       scan.x[0] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+       scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];\r
+       scan.z[0] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+       scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
+       scan.w[0] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+       scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+       scan.c[0][0] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+       scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
+       scan.t[0][0] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+       scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];\r
+       scan.t[1][0] = a->Tex[1];\r
+#endif\r
+\r
+       // top left fill convention y run\r
+       s32 yStart;\r
+       s32 yEnd;\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+       // rasterize upper sub-triangle\r
+       if ( F32_GREATER_0(scan.invDeltaY[1])  )\r
+       {\r
+               // calculate slopes for top edge\r
+               scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
+               scan.x[1] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+               scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];\r
+               scan.z[1] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
+               scan.w[1] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+               scan.c[0][1] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
+               scan.t[0][1] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];\r
+               scan.t[1][1] = a->Tex[1];\r
+#endif\r
+\r
+               // apply top-left fill convention, top part\r
+               yStart = fill_convention_left( a->Pos.y );\r
+               yEnd = fill_convention_right( b->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+               subPixel = ( (f32) yStart ) - a->Pos.y;\r
+\r
+               // correct to pixel center\r
+               scan.x[0] += scan.slopeX[0] * subPixel;\r
+               scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+               scan.z[0] += scan.slopeZ[0] * subPixel;\r
+               scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.w[0] += scan.slopeW[0] * subPixel;\r
+               scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+               scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+               scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+               // rasterize the edge scanlines\r
+               for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+               {\r
+                       line.x[scan.left] = scan.x[0];\r
+                       line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+                       line.z[scan.left] = scan.z[0];\r
+                       line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       line.w[scan.left] = scan.w[0];\r
+                       line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       line.t[0][scan.left] = scan.t[0][0];\r
+                       line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       line.t[1][scan.left] = scan.t[1][0];\r
+                       line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+                       // render a scanline\r
+                       fragmentShader();\r
+\r
+                       scan.x[0] += scan.slopeX[0];\r
+                       scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+                       scan.z[0] += scan.slopeZ[0];\r
+                       scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       scan.w[0] += scan.slopeW[0];\r
+                       scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] += scan.slopeT[0][0];\r
+                       scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] += scan.slopeT[1][0];\r
+                       scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+               }\r
+       }\r
+\r
+       // rasterize lower sub-triangle\r
+       if ( F32_GREATER_0(scan.invDeltaY[2]) )\r
+       {\r
+               // advance to middle point\r
+               if( F32_GREATER_0(scan.invDeltaY[1]) )\r
+               {\r
+                       temp[0] = b->Pos.y - a->Pos.y;  // dy\r
+\r
+                       scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
+#ifdef IPOL_Z\r
+                       scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_W\r
+                       scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
+#endif\r
+\r
+               }\r
+\r
+               // calculate slopes for bottom edge\r
+               scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];\r
+               scan.x[1] = b->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+               scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];\r
+               scan.z[1] = b->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
+               scan.w[1] = b->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+               scan.c[0][1] = b->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
+               scan.t[0][1] = b->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];\r
+               scan.t[1][1] = b->Tex[1];\r
+#endif\r
+\r
+               // apply top-left fill convention, top part\r
+               yStart = fill_convention_left( b->Pos.y );\r
+               yEnd = fill_convention_right( c->Pos.y );\r
+\r
+#ifdef SUBTEXEL\r
+\r
+               subPixel = ( (f32) yStart ) - b->Pos.y;\r
+\r
+               // correct to pixel center\r
+               scan.x[0] += scan.slopeX[0] * subPixel;\r
+               scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+               scan.z[0] += scan.slopeZ[0] * subPixel;\r
+               scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.w[0] += scan.slopeW[0] * subPixel;\r
+               scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+               scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+               scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+               // rasterize the edge scanlines\r
+               for( line.y = yStart; line.y <= yEnd; ++line.y)\r
+               {\r
+                       line.x[scan.left] = scan.x[0];\r
+                       line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+                       line.z[scan.left] = scan.z[0];\r
+                       line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       line.w[scan.left] = scan.w[0];\r
+                       line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       line.t[0][scan.left] = scan.t[0][0];\r
+                       line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       line.t[1][scan.left] = scan.t[1][0];\r
+                       line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+                       // render a scanline\r
+                       fragmentShader();\r
+\r
+                       scan.x[0] += scan.slopeX[0];\r
+                       scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+                       scan.z[0] += scan.slopeZ[0];\r
+                       scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       scan.w[0] += scan.slopeW[0];\r
+                       scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] += scan.slopeT[0][0];\r
+                       scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] += scan.slopeT[1][0];\r
+                       scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+               }\r
+       }\r
+\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+namespace irr\r
+{\r
+namespace video\r
+{\r
+\r
+//! creates a flat triangle renderer\r
+IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver)\r
+{\r
+       /*\r
+       ETR_TRANSPARENT_REFLECTION_2_LAYER \r
+       Irrlicht EMT_REFLECTION_2_LAYER,EMT_TRANSPARENT_REFLECTION_2_LAYER\r
+       */\r
+       #ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+       return new CTR_transparent_reflection_2_layer(driver);\r
+       #else\r
+       return 0;\r
+       #endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+}\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+\r
+\r
index 89c2c77aa97d52a05e48314baf2a9ccfb04ce185..feddb4086f66d49193cf80338b41a6a676ce7bb5 100644 (file)
@@ -912,6 +912,12 @@ bool CXMeshFileLoader::parseDataObjectMesh(SXMesh &mesh)
                        s16 uv2type = -1;\r
                        s16 tangenttype = -1;\r
                        s16 binormaltype = -1;\r
+\r
+                       (void)tangentpos; // disable unused variable warnings\r
+                       (void)binormalpos; // disable unused variable warnings\r
+                       (void)tangenttype; // disable unused variable warnings\r
+                       (void)binormaltype; // disable unused variable warnings\r
+\r
                        for (j=0; j<dcnt; ++j)\r
                        {\r
                                const u32 type = readInt();\r
index f11eac31b05a92bc295236e5dbe337257ae49c78..a375ef387d73f41f18ed6c2dea5c4d4a233b1626 100644 (file)
@@ -8,9 +8,12 @@
 #include "SoftwareDriver2_compile_config.h"\r
 #include "IBurningShader.h"\r
 #include "CSoftwareDriver2.h"\r
+#include "IShaderConstantSetCallBack.h"\r
 \r
 namespace irr\r
 {\r
+\r
+\r
 namespace video\r
 {\r
 \r
@@ -22,95 +25,374 @@ namespace video
                0xf0,0x70,0xd0,0x50\r
        };\r
 \r
-       IBurningShader::IBurningShader(CBurningVideoDriver* driver)\r
-       {\r
-               #ifdef _DEBUG\r
-               setDebugName("IBurningShader");\r
-               #endif\r
-\r
-               for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
-               {\r
-                       IT[i].Texture = 0;\r
-               }\r
-\r
-               Driver = driver;\r
-               RenderTarget = 0;\r
-               ColorMask = COLOR_BRIGHT_WHITE;\r
-               DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();\r
-               if ( DepthBuffer )\r
-                       DepthBuffer->grab();\r
-\r
-               Stencil = (CStencilBuffer*) driver->getStencilBuffer ();\r
-               if ( Stencil )\r
-                       Stencil->grab();\r
+void IBurningShader::constructor_IBurningShader(CBurningVideoDriver* driver)\r
+{\r
+       #ifdef _DEBUG\r
+       setDebugName("IBurningShader");\r
+       #endif\r
 \r
+       EdgeTestPass = edge_test_pass;\r
+       EdgeTestPass_stack = edge_test_pass;\r
+\r
+       for ( u32 i = 0; i < BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
+       {\r
+               IT[i].Texture = 0;\r
        }\r
 \r
+       Driver = driver;\r
+       CallBack = 0;\r
+\r
+       RenderTarget = 0;\r
+       ColorMask = COLOR_BRIGHT_WHITE;\r
+       DepthBuffer = (CDepthBuffer*) driver->getDepthBuffer ();\r
+       if ( DepthBuffer )\r
+               DepthBuffer->grab();\r
+\r
+       Stencil = (CStencilBuffer*) driver->getStencilBuffer ();\r
+       if ( Stencil )\r
+               Stencil->grab();\r
+\r
+       stencilOp[0] = StencilOp_KEEP;\r
+       stencilOp[1] = StencilOp_KEEP;\r
+       stencilOp[2] = StencilOp_KEEP;\r
+       AlphaRef = 0;\r
+       RenderPass_ShaderIsTransparent = 0;\r
+       PrimitiveColor = COLOR_BRIGHT_WHITE;\r
+       TL_Flag = 0;\r
+}\r
+\r
+IBurningShader::IBurningShader(CBurningVideoDriver* driver)\r
+{\r
+       constructor_IBurningShader(driver);\r
+}\r
+\r
+//! Constructor\r
+IBurningShader::IBurningShader(\r
+       CBurningVideoDriver* driver,\r
+       s32& outMaterialTypeNr,\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
+{\r
+       constructor_IBurningShader(driver);\r
+       BaseMaterial = baseMaterial;\r
+       CallBack = callback;\r
+       if (CallBack)\r
+               CallBack->grab();\r
+\r
+       // register myself as new material\r
+       outMaterialTypeNr = Driver->addMaterialRenderer(this);\r
+}\r
+\r
+\r
+//! destructor\r
+IBurningShader::~IBurningShader()\r
+{\r
+       if (RenderTarget)\r
+               RenderTarget->drop();\r
 \r
-       //! destructor\r
-       IBurningShader::~IBurningShader()\r
+       if (DepthBuffer)\r
+               DepthBuffer->drop();\r
+\r
+       if (Stencil)\r
+               Stencil->drop();\r
+\r
+       for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
        {\r
-               if (RenderTarget)\r
-                       RenderTarget->drop();\r
+               if ( IT[i].Texture )\r
+                       IT[i].Texture->drop();\r
+       }\r
 \r
-               if (DepthBuffer)\r
-                       DepthBuffer->drop();\r
+       if (CallBack)\r
+               CallBack->drop();\r
 \r
-               if (Stencil)\r
-                       Stencil->drop();\r
+}\r
 \r
-               for ( u32 i = 0; i != BURNING_MATERIAL_MAX_TEXTURES; ++i )\r
-               {\r
-                       if ( IT[i].Texture )\r
-                               IT[i].Texture->drop();\r
-               }\r
+//! sets a render target\r
+void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)\r
+{\r
+       if (RenderTarget)\r
+               RenderTarget->drop();\r
+\r
+       RenderTarget = (video::CImage* ) surface;\r
+\r
+       if (RenderTarget)\r
+       {\r
+               RenderTarget->grab();\r
+\r
+               //(fp24*) DepthBuffer->lock() = DepthBuffer->lock();\r
        }\r
+}\r
+\r
 \r
-       //! sets a render target\r
-       void IBurningShader::setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort)\r
+//! sets the Texture\r
+void IBurningShader::setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor)\r
+{\r
+       sInternalTexture *it = &IT[stage];\r
+\r
+       if ( it->Texture)\r
+               it->Texture->drop();\r
+\r
+       it->Texture = texture;\r
+\r
+       if ( it->Texture)\r
        {\r
-               if (RenderTarget)\r
-                       RenderTarget->drop();\r
+               it->Texture->grab();\r
 \r
-               RenderTarget = (video::CImage* ) surface;\r
+               // select mignify and magnify\r
+               it->lodFactor = lodFactor;\r
 \r
-               if (RenderTarget)\r
-               {\r
-                       RenderTarget->grab();\r
+               //only mipmap chain (means positive lodFactor)\r
+               u32 existing_level = it->Texture->getMipmapLevel(lodFactor);\r
+               it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY, existing_level, 0);\r
 \r
-                       //(fp24*) DepthBuffer->lock() = DepthBuffer->lock();\r
-               }\r
+               // prepare for optimal fixpoint\r
+               it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );\r
+\r
+               const core::dimension2d<u32> &dim = it->Texture->getSize();\r
+               it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
+               it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
        }\r
+}\r
+\r
+//emulate a line with degenerate triangle and special shader mode (not perfect...)\r
+void IBurningShader::drawLine ( const s4DVertex *a,const s4DVertex *b)\r
+{\r
+       sVec2 d;\r
+       d.x = b->Pos.x - a->Pos.x;      d.x *= d.x;\r
+       d.y = b->Pos.y - a->Pos.y;      d.y *= d.y;\r
+       //if ( d.x * d.y < 0.001f ) return;\r
+\r
+       if ( a->Pos.x > b->Pos.x ) swapVertexPointer(&a, &b);\r
+\r
+       s4DVertex c = *a;\r
+\r
+       const f32 w = (f32)RenderTarget->getDimension().Width-1;\r
+       const f32 h = (f32)RenderTarget->getDimension().Height-1;\r
+\r
+       if ( d.x < 2.f ) { c.Pos.x = b->Pos.x + 1.f + d.y; if ( c.Pos.x > w ) c.Pos.x = w; }\r
+       else c.Pos.x = b->Pos.x;\r
+       if ( d.y < 2.f ) { c.Pos.y = b->Pos.y + 1.f; if ( c.Pos.y > h ) c.Pos.y = h; EdgeTestPass |= edge_test_first_line; }\r
+\r
+       drawTriangle ( a,b,&c );\r
+       EdgeTestPass &= ~edge_test_first_line;\r
+\r
+}\r
 \r
+void IBurningShader::drawPoint(const s4DVertex *a)\r
+{\r
+}\r
 \r
-       //! sets the Texture\r
-       void IBurningShader::setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel)\r
+void IBurningShader::drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c )\r
+{\r
+       if ( EdgeTestPass & edge_test_pass ) drawTriangle(a, b, c);\r
+       else if (EdgeTestPass & edge_test_point)\r
+       {\r
+               drawPoint(a);\r
+               drawPoint(b);\r
+               drawPoint(c);\r
+       }\r
+       else\r
        {\r
-               sInternalTexture *it = &IT[stage];\r
+               drawLine(a, b);\r
+               drawLine(b, c);\r
+               drawLine(a, c);\r
+       }\r
+}\r
 \r
-               if ( it->Texture)\r
-                       it->Texture->drop();\r
 \r
-               it->Texture = texture;\r
+void IBurningShader::OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
+       bool resetAllRenderstates, IMaterialRendererServices* services)\r
+{\r
+       if (Driver)\r
+               Driver->setFallback_Material(BaseMaterial);\r
+       services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
+       if (CallBack)\r
+               CallBack->OnSetMaterial(material);\r
 \r
-               if ( it->Texture)\r
-               {\r
-                       it->Texture->grab();\r
+}\r
 \r
-                       // select mignify and magnify ( lodLevel )\r
-                       //SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS\r
-                       it->lodLevel = lodLevel;\r
-                       it->data = (tVideoSample*) it->Texture->lock(ETLM_READ_ONLY,\r
-                               core::s32_clamp ( lodLevel + SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS, 0, SOFTWARE_DRIVER_2_MIPMAPPING_MAX - 1 ), 0);\r
+void IBurningShader::OnUnsetMaterial()\r
+{\r
+}\r
 \r
-                       // prepare for optimal fixpoint\r
-                       it->pitchlog2 = s32_log2_s32 ( it->Texture->getPitch() );\r
+bool IBurningShader::OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype)\r
+{\r
+       // call callback to set shader constants\r
+       if (CallBack)\r
+               CallBack->OnSetConstants(this, UserData);\r
+       return true;\r
+}\r
+\r
+\r
+//! Returns if the material is transparent.\r
+bool IBurningShader::isTransparent() const\r
+{\r
+       return RenderPass_ShaderIsTransparent != 0;\r
+}\r
+\r
+//! Access the callback provided by the users when creating shader materials\r
+IShaderConstantSetCallBack* IBurningShader::getShaderConstantSetCallBack() const\r
+{\r
+       return CallBack;\r
+}\r
 \r
-                       const core::dimension2d<u32> &dim = it->Texture->getSize();\r
-                       it->textureXMask = s32_to_fixPoint ( dim.Width - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
-                       it->textureYMask = s32_to_fixPoint ( dim.Height - 1 ) & FIX_POINT_UNSIGNED_MASK;\r
-               }\r
+// implementations for the render services\r
+void IBurningShader::setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates)\r
+{\r
+       // forward\r
+       Driver->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);\r
+}\r
+\r
+s32 IBurningShader::getShaderConstantID(EBurningUniformFlags flags,const c8* name)\r
+{\r
+       if (!name || !name[0])\r
+               return -1;\r
+\r
+       BurningUniform add;\r
+       tiny_strcpy(add.name, name);\r
+       add.type = flags;\r
+\r
+       s32 index = UniformInfo.linear_search(add);\r
+       if (index < 0)\r
+       {\r
+               UniformInfo.push_back(add);\r
+               index = UniformInfo.size() - 1;\r
+       }\r
+\r
+       return index;\r
+}\r
+\r
+const char* tiny_itoa(s32 value, int base)\r
+{\r
+       static char b[32];\r
+       int p = 31;\r
+\r
+       //int sign = 0;\r
+       //if (value < 0) { sign = 1; value = -value; }\r
+\r
+       b[p] = '\0';\r
+       do {\r
+               b[--p] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[value%base];\r
+               value /= base;\r
+       } while (value && p > 0);\r
+\r
+       //if (sign && p > 0) { b[--p] = '-'; }\r
+\r
+       return b + p;\r
+}\r
+\r
+bool IBurningShader::setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count)\r
+{\r
+       if ((u32)index >= UniformInfo.size())\r
+               return false;\r
+#if 0\r
+       BurningUniform add;\r
+       while ((u32)index >= UniformInfo.size())\r
+       {\r
+               tiny_strcpy(add.name, tiny_itoa(UniformInfo.size(),10));\r
+               add.type = flags;\r
+               UniformInfo.push_back(add);\r
        }\r
+#endif\r
+\r
+       BurningUniform& use = UniformInfo[index];\r
+       use.type = flags;\r
+\r
+       const u32* s = (u32*)data;\r
+       u32* d = (u32*)use.data;\r
+\r
+       if (!s) u32_count = 0;\r
+       if (u32_count > array_size(use.data)) u32_count = array_size(use.data);\r
+       for (size_t i = 0; i < u32_count; ++i)\r
+       {\r
+               d[i] = s[i];\r
+       }\r
+\r
+       return true;\r
+}\r
+\r
+\r
+s32 IBurningShader::getVertexShaderConstantID(const c8* name)\r
+{\r
+       return getShaderConstantID(BL_VERTEX_PROGRAM, name);\r
+}\r
+\r
+s32 IBurningShader::getPixelShaderConstantID(const c8* name)\r
+{\r
+       return getShaderConstantID(BL_FRAGMENT_PROGRAM, name);\r
+}\r
+\r
+void IBurningShader::setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
+{\r
+       c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];\r
+       tiny_strcpy(name, tiny_itoa(startRegister, 10));\r
+\r
+       setShaderConstantID(BL_VERTEX_FLOAT, getShaderConstantID(BL_VERTEX_PROGRAM,name), data, constantAmount);\r
+}\r
+\r
+void IBurningShader::setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount)\r
+{\r
+       c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];\r
+       tiny_strcpy(name, tiny_itoa(startRegister, 10));\r
+\r
+       setShaderConstantID(BL_FRAGMENT_FLOAT, getShaderConstantID(BL_FRAGMENT_PROGRAM, name), data, constantAmount);\r
+}\r
+\r
+bool IBurningShader::setVertexShaderConstant(s32 index, const f32* floats, int count)\r
+{\r
+       return setShaderConstantID(BL_VERTEX_FLOAT, index, floats, count);\r
+}\r
+\r
+bool IBurningShader::setVertexShaderConstant(s32 index, const s32* ints, int count)\r
+{\r
+       return setShaderConstantID(BL_VERTEX_INT, index, ints, count);\r
+}\r
+\r
+bool IBurningShader::setVertexShaderConstant(s32 index, const u32* ints, int count)\r
+{\r
+       return setShaderConstantID(BL_VERTEX_UINT, index, ints, count);\r
+}\r
+\r
+bool IBurningShader::setPixelShaderConstant(s32 index, const f32* floats, int count)\r
+{\r
+       return setShaderConstantID(BL_FRAGMENT_FLOAT, index, floats, count);\r
+}\r
+\r
+bool IBurningShader::setPixelShaderConstant(s32 index, const s32* ints, int count)\r
+{\r
+       return setShaderConstantID(BL_FRAGMENT_INT, index, ints, count);\r
+}\r
+\r
+bool IBurningShader::setPixelShaderConstant(s32 index, const u32* ints, int count)\r
+{\r
+       return setShaderConstantID(BL_FRAGMENT_UINT, index, ints, count);\r
+}\r
+\r
+void IBurningShader::setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass)\r
+{\r
+       stencilOp[0] = sfail;\r
+       stencilOp[1] = dpfail;\r
+       stencilOp[2] = dppass;\r
+}\r
+\r
+\r
+IVideoDriver* IBurningShader::getVideoDriver()\r
+{\r
+       return Driver;\r
+}\r
 \r
 \r
 } // end namespace video\r
index 0fffff7ccee537b7219ce2896867afe0c3d448f0..8a9a8180347838e1cedd52169f40547f3cd335c1 100644 (file)
@@ -18,7 +18,9 @@
 #include "SLight.h"\r
 #include "SMaterial.h"\r
 #include "os.h"\r
-\r
+#include "IMaterialRenderer.h"\r
+#include "IMaterialRendererServices.h"\r
+#include "IGPUProgrammingServices.h"\r
 \r
 namespace irr\r
 {\r
@@ -29,56 +31,109 @@ namespace video
        struct SBurningShaderLight\r
        {\r
                //SLight org;\r
-               bool LightIsOn;\r
+\r
+               sVec4 pos;      //light position input\r
+               sVec4 pos4; //light position Model*View (Identity*View)\r
 \r
                E_LIGHT_TYPE Type;\r
-               f32 radius;\r
                f32 linearAttenuation;\r
                f32 constantAttenuation;\r
                f32 quadraticAttenuation;\r
-               sVec4 pos;\r
 \r
-               sVec3 AmbientColor;\r
-               sVec3 DiffuseColor;\r
-               sVec3 SpecularColor;\r
-               sVec4 pos_objectspace;\r
+               sVec4 spotDirection;\r
+               sVec4 spotDirection4;\r
+               f32 spotCosCutoff;\r
+               f32 spotCosInnerCutoff;\r
+               f32 spotExponent;\r
+               bool LightIsOn;\r
+\r
+               sVec3Color AmbientColor;\r
+               sVec3Color DiffuseColor;\r
+               sVec3Color SpecularColor;\r
        };\r
 \r
-       enum eLightFlags\r
+       enum eTransformLightFlags\r
        {\r
-               ENABLED         = 0x01,\r
-               POINTLIGHT      = 0x02,\r
-               SPECULAR        = 0x04,\r
-               FOG                     = 0x08,\r
-               NORMALIZE       = 0x10,\r
-               VERTEXTRANSFORM = 0x20,\r
+               //ENABLED               = 0x01,\r
+               TL_SCISSOR                              = 0x02,\r
+               TL_LIGHT                                = 0x04,\r
+               TL_SPECULAR                             = 0x08,\r
+               TL_FOG                                  = 0x10,\r
+               TL_NORMALIZE_NORMALS    = 0x20,\r
+               TL_TEXTURE_TRANSFORM    = 0x40,\r
+               TL_LIGHT_LOCAL_VIEWER   = 0x80,\r
+               TL_LIGHT0_IS_NORMAL_MAP = 0x100         //sVec4 Light Vector is used as normal or specular\r
        };\r
 \r
-       struct SBurningShaderLightSpace\r
+       struct SBurningShaderEyeSpace\r
        {\r
+               SBurningShaderEyeSpace() {}\r
+               virtual ~SBurningShaderEyeSpace() {}\r
                void reset ()\r
                {\r
                        Light.set_used ( 0 );\r
-                       Global_AmbientLight.set ( 0.f, 0.f, 0.f );\r
-                       Flags = 0;\r
+                       Global_AmbientLight.set ( 0.f );\r
+\r
+                       TL_Flag = TL_LIGHT_LOCAL_VIEWER;\r
+               }\r
+               void resetFog()\r
+               {\r
+                       fog_scale = 0.f;\r
+                       //cam_distance = 0.f;\r
                }\r
+\r
                core::array<SBurningShaderLight> Light;\r
-               sVec3 Global_AmbientLight;\r
-               sVec4 FogColor;\r
-               sVec4 campos;\r
-               sVec4 vertex;\r
-               sVec4 normal;\r
-               u32 Flags;\r
+               sVec3Color Global_AmbientLight;\r
+\r
+               //sVec4 cam_eye_pos; //Camera Position in eye Space (0,0,-1)\r
+               //sVec4 cam_world_pos; //Camera Position in world Space\r
+               //sVec4 vertex4; //eye coordinate position of vertex\r
+               sVec4 normal; //transformed normal\r
+               sVec4 vertex; //eye coordinate position of vertex projected\r
+\r
+               //derivative of vertex\r
+               //f32 cam_distance; // vertex.length();\r
+               sVec4 cam_dir; //vertex.normalize();\r
+\r
+               f32 fog_scale; // 1 / (fog.end-fog.start)\r
+\r
+               size_t TL_Flag; // eTransformLightFlags\r
+       };\r
+\r
+       enum eBurningCullFlag\r
+       {\r
+               CULL_FRONT = 1,\r
+               CULL_BACK = 2,\r
+               CULL_INVISIBLE = 4,     //primitive smaller than a pixel (AreaMinDrawSize)\r
+               CULL_FRONT_AND_BACK = 8,\r
+       };\r
+\r
+       enum eBurningStencilOp\r
+       {\r
+               StencilOp_KEEP = 0x1E00,\r
+               StencilOp_INCR = 0x1E02,\r
+               StencilOp_DECR = 0x1E03\r
        };\r
 \r
        struct SBurningShaderMaterial\r
        {\r
                SMaterial org;\r
+               SMaterial lastMaterial;\r
+               bool resetRenderStates;\r
+\r
+               E_MATERIAL_TYPE Fallback_MaterialType;\r
 \r
-               sVec3 AmbientColor;\r
-               sVec3 DiffuseColor;\r
-               sVec3 SpecularColor;\r
-               sVec3 EmissiveColor;\r
+               SMaterial mat2D;\r
+               //SMaterial save3D;\r
+\r
+               size_t CullFlag; //eCullFlag\r
+               u32 depth_write;\r
+               u32 depth_test;\r
+\r
+               sVec3Color AmbientColor;\r
+               sVec3Color DiffuseColor;\r
+               sVec3Color SpecularColor;\r
+               sVec3Color EmissiveColor;\r
 \r
        };\r
 \r
@@ -106,29 +161,88 @@ namespace video
                ETR_TEXTURE_GOURAUD_DETAIL_MAP,\r
                ETR_TEXTURE_GOURAUD_LIGHTMAP_ADD,\r
 \r
-               ETR_GOURAUD_ALPHA,\r
+               ETR_GOURAUD_NOZ,\r
+               //ETR_GOURAUD_ALPHA,\r
                ETR_GOURAUD_ALPHA_NOZ,\r
 \r
                ETR_TEXTURE_GOURAUD_ALPHA,\r
                ETR_TEXTURE_GOURAUD_ALPHA_NOZ,\r
+               ETR_TEXTURE_GOURAUD_ALPHA_NOZ_NOPERSPECTIVE_CORRECT,\r
 \r
                ETR_NORMAL_MAP_SOLID,\r
                ETR_STENCIL_SHADOW,\r
 \r
                ETR_TEXTURE_BLEND,\r
-               ETR_REFERENCE,\r
+               ETR_TRANSPARENT_REFLECTION_2_LAYER,\r
+\r
+               ETR_COLOR,\r
+\r
+               //ETR_REFERENCE,\r
                ETR_INVALID,\r
 \r
                ETR2_COUNT\r
        };\r
 \r
+       typedef enum\r
+       {\r
+               BL_VERTEX_PROGRAM = 1,\r
+               BL_FRAGMENT_PROGRAM = 2,\r
+               BL_TYPE_FLOAT = 4,\r
+               BL_TYPE_INT = 8,\r
+               BL_TYPE_UINT = 16,\r
+\r
+               BL_VERTEX_FLOAT = (BL_VERTEX_PROGRAM | BL_TYPE_FLOAT),\r
+               BL_VERTEX_INT = (BL_VERTEX_PROGRAM | BL_TYPE_INT),\r
+               BL_VERTEX_UINT = (BL_VERTEX_PROGRAM | BL_TYPE_UINT),\r
+               BL_FRAGMENT_FLOAT = (BL_FRAGMENT_PROGRAM | BL_TYPE_FLOAT),\r
+               BL_FRAGMENT_INT = (BL_FRAGMENT_PROGRAM | BL_TYPE_INT),\r
+               BL_FRAGMENT_UINT = (BL_FRAGMENT_PROGRAM | BL_TYPE_UINT),\r
+\r
+               BL_ACTIVE_UNIFORM_MAX_LENGTH = 28\r
+       } EBurningUniformFlags;\r
+\r
+       struct BurningUniform\r
+       {\r
+               c8 name[BL_ACTIVE_UNIFORM_MAX_LENGTH];\r
+               u32 type; //EBurningUniformFlags\r
+               //int location; // UniformLocation is index\r
+               f32 data[16];   // simple LocalParameter\r
+\r
+               bool operator==(const BurningUniform& other) const\r
+               {\r
+                       return tiny_istoken(name, other.name);\r
+               }\r
+\r
+       };\r
+\r
 \r
        class CBurningVideoDriver;\r
-       class IBurningShader : public virtual IReferenceCounted\r
+       class IBurningShader : public IMaterialRenderer, public IMaterialRendererServices\r
        {\r
        public:\r
+               //! Constructor\r
                IBurningShader(CBurningVideoDriver* driver);\r
 \r
+               //! Constructor\r
+               IBurningShader(\r
+                       CBurningVideoDriver* driver,\r
+                       s32& outMaterialTypeNr,\r
+                       const c8* vertexShaderProgram = 0,\r
+                       const c8* vertexShaderEntryPointName = 0,\r
+                       E_VERTEX_SHADER_TYPE vsCompileTarget = video::EVST_VS_1_1,\r
+                       const c8* pixelShaderProgram = 0,\r
+                       const c8* pixelShaderEntryPointName = 0,\r
+                       E_PIXEL_SHADER_TYPE psCompileTarget = video::EPST_PS_1_1,\r
+                       const c8* geometryShaderProgram = 0,\r
+                       const c8* geometryShaderEntryPointName = "main",\r
+                       E_GEOMETRY_SHADER_TYPE gsCompileTarget = EGST_GS_4_0,\r
+                       scene::E_PRIMITIVE_TYPE inType = scene::EPT_TRIANGLES,\r
+                       scene::E_PRIMITIVE_TYPE outType = scene::EPT_TRIANGLE_STRIP,\r
+                       u32 verticesOut = 0,\r
+                       IShaderConstantSetCallBack* callback = 0,\r
+                       E_MATERIAL_TYPE baseMaterial = EMT_SOLID,\r
+                       s32 userData = 0);\r
+\r
                //! destructor\r
                virtual ~IBurningShader();\r
 \r
@@ -136,27 +250,121 @@ namespace video
                virtual void setRenderTarget(video::IImage* surface, const core::rect<s32>& viewPort);\r
 \r
                //! sets the Texture\r
-               virtual void setTextureParam( u32 stage, video::CSoftwareTexture2* texture, s32 lodLevel);\r
-               virtual void drawTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c ) = 0;\r
-               virtual void drawLine ( const s4DVertex *a,const s4DVertex *b) {};\r
+               virtual void setTextureParam( const size_t stage, video::CSoftwareTexture2* texture, s32 lodFactor);\r
+               virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) {};\r
+               virtual void drawLine ( const s4DVertex *a,const s4DVertex *b);\r
+               virtual void drawPoint(const s4DVertex *a);\r
+\r
+               void drawWireFrameTriangle ( const s4DVertex *a,const s4DVertex *b,const s4DVertex *c );\r
+\r
+               virtual void OnSetMaterial( const SBurningShaderMaterial& material ) {};\r
+\r
+               void pushEdgeTest(const int wireFrame,const int point,int save)\r
+               {\r
+                       if ( save ) EdgeTestPass_stack = EdgeTestPass;\r
+                       EdgeTestPass = point ? edge_test_point : wireFrame ? edge_test_left : edge_test_pass;\r
+               }\r
+               void popEdgeTest() { EdgeTestPass = EdgeTestPass_stack; }\r
+               virtual bool canWireFrame () { return false; }\r
+               virtual bool canPointCloud() { return false; }\r
+\r
+               void setStencilOp(eBurningStencilOp sfail, eBurningStencilOp dpfail, eBurningStencilOp dppass);\r
 \r
-               virtual void setParam ( u32 index, f32 value) {};\r
-               virtual void setZCompareFunc ( u32 func) {};\r
+               //IMaterialRenderer\r
 \r
-               virtual void setMaterial ( const SBurningShaderMaterial &material ) {};\r
+               virtual void OnSetMaterial(const SMaterial& material, const SMaterial& lastMaterial,\r
+                       bool resetAllRenderstates, IMaterialRendererServices* services) _IRR_OVERRIDE_;\r
+\r
+               virtual bool OnRender(IMaterialRendererServices* service, E_VERTEX_TYPE vtxtype) _IRR_OVERRIDE_;\r
+\r
+               virtual void OnUnsetMaterial() _IRR_OVERRIDE_;\r
+\r
+               //! Returns if the material is transparent.\r
+               virtual bool isTransparent() const _IRR_OVERRIDE_;\r
+\r
+               //! Access the callback provided by the users when creating shader materials\r
+               virtual IShaderConstantSetCallBack* getShaderConstantSetCallBack() const _IRR_OVERRIDE_;\r
+\r
+               // implementations for the render services\r
+               virtual void setBasicRenderStates(const SMaterial& material, const SMaterial& lastMaterial, bool resetAllRenderstates) _IRR_OVERRIDE_;\r
+               virtual s32 getVertexShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+               virtual s32 getPixelShaderConstantID(const c8* name) _IRR_OVERRIDE_;\r
+               virtual void setVertexShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;\r
+               virtual void setPixelShaderConstant(const f32* data, s32 startRegister, s32 constantAmount = 1) _IRR_OVERRIDE_;\r
+               virtual bool setVertexShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+               virtual bool setVertexShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+               virtual bool setVertexShaderConstant(s32 index, const u32* ints, int count) _IRR_OVERRIDE_;\r
+               virtual bool setPixelShaderConstant(s32 index, const f32* floats, int count) _IRR_OVERRIDE_;\r
+               virtual bool setPixelShaderConstant(s32 index, const s32* ints, int count) _IRR_OVERRIDE_;\r
+               virtual bool setPixelShaderConstant(s32 index, const u32* ints, int count)  _IRR_OVERRIDE_;\r
+               virtual IVideoDriver* getVideoDriver() _IRR_OVERRIDE_;\r
+\r
+               //used if no color interpolation is defined\r
+               void setPrimitiveColor(const video::SColor& color)\r
+               {\r
+                       #if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8\r
+                               PrimitiveColor = color.color;\r
+                       #else\r
+                               PrimitiveColor = color.toA1R5G5B5();\r
+                       #endif\r
+               }\r
+               void setTLFlag(size_t in /*eTransformLightFlags*/)\r
+               {\r
+                       TL_Flag = in;\r
+               }\r
+               void setFog(SColor color_fog)\r
+               {\r
+#if BURNINGSHADER_COLOR_FORMAT == ECF_A8R8G8B8\r
+                       fog_color_sample = color_fog.color;\r
+#else\r
+                       fog_color_sample = color_fog.toA1R5G5B5();\r
+#endif\r
+                       color_to_fix(fog_color, fog_color_sample);\r
+               }\r
+               void setScissor(const AbsRectangle& scissor)\r
+               {\r
+                       Scissor = scissor;\r
+               }\r
 \r
        protected:\r
 \r
+               void constructor_IBurningShader(CBurningVideoDriver* driver);\r
+\r
                CBurningVideoDriver *Driver;\r
+               IShaderConstantSetCallBack* CallBack;\r
+               E_MATERIAL_TYPE BaseMaterial;\r
+               s32 UserData;\r
+\r
+               core::array<BurningUniform> UniformInfo;\r
+               s32 getShaderConstantID(EBurningUniformFlags program, const c8* name);\r
+               bool setShaderConstantID(EBurningUniformFlags flags, s32 index, const void* data, size_t u32_count);\r
 \r
                video::CImage* RenderTarget;\r
                CDepthBuffer* DepthBuffer;\r
-               CStencilBuffer * Stencil;\r
+               CStencilBuffer* Stencil;\r
                tVideoSample ColorMask;\r
 \r
                sInternalTexture IT[ BURNING_MATERIAL_MAX_TEXTURES ];\r
 \r
                static const tFixPointu dithermask[ 4 * 4];\r
+\r
+               //draw degenerate triangle as line (left edge) drawTriangle -> holes,drawLine dda/bresenham\r
+               int EdgeTestPass; //edge_test_flag\r
+               int EdgeTestPass_stack;\r
+\r
+               eBurningStencilOp stencilOp[4];\r
+               tFixPoint AlphaRef;\r
+               int RenderPass_ShaderIsTransparent;\r
+\r
+               sScanConvertData scan;\r
+               sScanLineData line;\r
+               tVideoSample PrimitiveColor; //used if no color interpolation is defined\r
+\r
+               size_t /*eTransformLightFlags*/ TL_Flag;\r
+               tFixPoint fog_color[4];\r
+               tVideoSample fog_color_sample;\r
+\r
+               AbsRectangle Scissor;\r
        };\r
 \r
 \r
@@ -172,6 +380,7 @@ namespace video
 \r
        IBurningShader* createTriangleRendererTextureGouraudWire2(CBurningVideoDriver* driver);\r
        IBurningShader* createTriangleRendererGouraud2(CBurningVideoDriver* driver);\r
+       IBurningShader* createTriangleRendererGouraudNoZ2(CBurningVideoDriver* driver);\r
        IBurningShader* createTriangleRendererGouraudAlpha2(CBurningVideoDriver* driver);\r
        IBurningShader* createTRGouraudAlphaNoZ2(CBurningVideoDriver* driver);\r
        IBurningShader* createTriangleRendererGouraudWire2(CBurningVideoDriver* driver);\r
@@ -192,8 +401,9 @@ namespace video
        IBurningShader* createTRStencilShadow(CBurningVideoDriver* driver);\r
 \r
        IBurningShader* createTriangleRendererReference(CBurningVideoDriver* driver);\r
+       IBurningShader* createTriangleRendererTexture_transparent_reflection_2_layer(CBurningVideoDriver* driver);\r
 \r
-\r
+       IBurningShader* create_burning_shader_color(CBurningVideoDriver* driver);\r
 \r
 } // end namespace video\r
 } // end namespace irr\r
index 719d9f171d8cd36c936f4e6777761ee2ea9c1fc1..89f604f383f5742ce70b7703bb74c01f4ba6d351 100644 (file)
@@ -21,7 +21,7 @@ namespace video
                virtual ~IDepthBuffer() {};\r
 \r
                //! clears the zbuffer\r
-               virtual void clear() = 0;\r
+               virtual void clear(f32 value) = 0;\r
 \r
                //! sets the new size of the zbuffer\r
                virtual void setSize(const core::dimension2d<u32>& size) = 0;\r
@@ -51,29 +51,29 @@ namespace video
                //! destructor\r
                virtual ~IStencilBuffer() {};\r
 \r
-               //! clears the zbuffer\r
-               virtual void clear() = 0;\r
+               //! clears the stencil buffer\r
+               virtual void clear(u8 value) = 0;\r
 \r
                //! sets the new size of the zbuffer\r
                virtual void setSize(const core::dimension2d<u32>& size) = 0;\r
 \r
-               //! returns the size of the zbuffer\r
+               //! returns the size of the stencil buffer\r
                virtual const core::dimension2d<u32>& getSize() const = 0;\r
 \r
-               //! locks the zbuffer\r
+               //! locks the stencil buffer\r
                virtual void* lock() = 0;\r
 \r
-               //! unlocks the zbuffer\r
+               //! unlocks the stencil buffer\r
                virtual void unlock() = 0;\r
 \r
-               //! returns pitch of depthbuffer (in bytes)\r
+               //! returns pitch of stencil buffer (in bytes)\r
                virtual u32 getPitch() const = 0;\r
 \r
        };\r
 \r
 \r
        //! creates a Stencil Buffer\r
-       IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size);\r
+       IStencilBuffer* createStencilBuffer(const core::dimension2d<u32>& size, u32 bit);\r
 \r
 } // end namespace video\r
 } // end namespace irr\r
index 3e8d0ad02a9834a0a6abfe275f0ed31d9d5e72c2..a1dbf210157789e93aabc208acbec79b96f77b84 100644 (file)
                <Unit filename="CTRGouraud2.cpp" />
                <Unit filename="CTRGouraudAlpha2.cpp" />
                <Unit filename="CTRGouraudAlphaNoZ2.cpp" />
+               <Unit filename="CTRGouraudNoZ2.cpp" />
                <Unit filename="CTRGouraudWire.cpp" />
                <Unit filename="CTRNormalMap.cpp" />
                <Unit filename="CTRStencilShadow.cpp" />
                <Unit filename="CTRTextureLightMap2_M4.cpp" />
                <Unit filename="CTRTextureLightMapGouraud2_M4.cpp" />
                <Unit filename="CTRTextureWire2.cpp" />
+               <Unit filename="CTR_transparent_reflection_2_layer.cpp" />
                <Unit filename="CTarReader.cpp" />
                <Unit filename="CTarReader.h" />
                <Unit filename="CTerrainSceneNode.cpp" />
                <Unit filename="aesGladman/sha1.h" />
                <Unit filename="aesGladman/sha2.cpp" />
                <Unit filename="aesGladman/sha2.h" />
+               <Unit filename="burning_shader_color.cpp" />
+               <Unit filename="burning_shader_color_fraq.h" />
+               <Unit filename="burning_shader_compile_fragment_default.h" />
+               <Unit filename="burning_shader_compile_fragment_end.h" />
+               <Unit filename="burning_shader_compile_fragment_start.h" />
+               <Unit filename="burning_shader_compile_start.h" />
+               <Unit filename="burning_shader_compile_triangle.h" />
+               <Unit filename="burning_shader_compile_verify.h" />
                <Unit filename="bzip2/blocksort.c">
                        <Option compilerVar="CC" />
                </Unit>
index 78c279ca608ebdea1e80a4f497d9b955ea478ce3..b61cdc0c2cf70c72fb7f4459e275ed1f0e24a8dc 100644 (file)
     <ClInclude Include="..\..\include\IGUIToolbar.h" />\r
     <ClInclude Include="..\..\include\IGUITreeView.h" />\r
     <ClInclude Include="..\..\include\IGUIWindow.h" />\r
+    <ClInclude Include="burning_shader_color_fraq.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+    <ClInclude Include="burning_shader_compile_start.h" />\r
+    <ClInclude Include="burning_shader_compile_triangle.h" />\r
+    <ClInclude Include="burning_shader_compile_verify.h" />    \r
     <ClInclude Include="CB3DMeshWriter.h" />\r
     <ClInclude Include="CD3D9RenderTarget.h" />\r
     <ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
     <None Include="..\..\readme.txt" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+       <ClCompile Include="burning_shader_color.cpp" />\r
     <ClCompile Include="CB3DMeshWriter.cpp" />\r
     <ClCompile Include="CD3D9RenderTarget.cpp" />\r
     <ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
     <ClCompile Include="CQ3LevelMesh.cpp" />\r
     <ClCompile Include="CSkinnedMesh.cpp" />\r
     <ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+       <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
     <ClCompile Include="CWGLManager.cpp" />\r
     <ClCompile Include="CXMeshFileLoader.cpp" />\r
     <ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
index 6269a9c5f09297de96ab4a6b98e4b98caa54ef6c..618fb8818c0d02a531e3adf73f55d8e49b231682 100644 (file)
     </ClInclude>\r
     <ClInclude Include="..\..\include\IOctreeSceneNode.h">\r
       <Filter>include\scene</Filter>\r
+    </ClInclude>\r
+       <ClInclude Include="burning_shader_color_fraq.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_triangle.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_verify.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
     </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     </ClCompile>\r
     <ClCompile Include="CWGLManager.cpp">\r
       <Filter>Irrlicht\video\OpenGL Context</Filter>\r
+    </ClCompile>\r
+       <ClCompile Include="burning_shader_color.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
     </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
index 791a36a0df0ea79db04bff8e3b2b97341688d969..e6b828e4339e9996ca83c715de1ba95dc8af9530 100644 (file)
     <ClInclude Include="..\..\include\IGUIToolbar.h" />\r
     <ClInclude Include="..\..\include\IGUITreeView.h" />\r
     <ClInclude Include="..\..\include\IGUIWindow.h" />\r
+    <ClInclude Include="burning_shader_color_fraq.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+    <ClInclude Include="burning_shader_compile_start.h" />\r
+    <ClInclude Include="burning_shader_compile_triangle.h" />\r
+    <ClInclude Include="burning_shader_compile_verify.h" />\r
     <ClInclude Include="CB3DMeshWriter.h" />\r
     <ClInclude Include="CD3D9RenderTarget.h" />\r
     <ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
     <None Include="..\..\readme.txt" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ClCompile Include="burning_shader_color.cpp" />\r
     <ClCompile Include="CB3DMeshWriter.cpp" />\r
     <ClCompile Include="CD3D9RenderTarget.cpp" />\r
     <ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
     <ClCompile Include="CQ3LevelMesh.cpp" />\r
     <ClCompile Include="CSkinnedMesh.cpp" />\r
     <ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
     <ClCompile Include="CWGLManager.cpp" />\r
     <ClCompile Include="CXMeshFileLoader.cpp" />\r
     <ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
index f61a3f95d7b2b241cd9df79ea24d9d1e855e32ed..1cffa753612c189e870d11b8f3dd73f4c958b357 100644 (file)
     <ClInclude Include="..\..\include\IOctreeSceneNode.h">\r
       <Filter>include\scene</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="burning_shader_color_fraq.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_triangle.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_verify.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="..\..\changes.txt">\r
     <ClCompile Include="CWGLManager.cpp">\r
       <Filter>Irrlicht\video\OpenGL Context</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="burning_shader_color.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="Irrlicht.rc" />\r
index 7b01c7467b50bc76e2b13c6c5929bbdcbebcb69f..9581357aca29c4d978a0ffaf2895df1890ec302f 100644 (file)
     <ClCompile Include="CQ3LevelMesh.cpp" />\r
     <ClCompile Include="CSkinnedMesh.cpp" />\r
     <ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
     <ClCompile Include="CWGLManager.cpp" />\r
     <ClCompile Include="CXMeshFileLoader.cpp" />\r
     <ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
index 7e94d188b762fe98375fafbe57923082a95b57d5..0623a911ba4afdd182bed47b663ad802656f41ed 100644 (file)
     <ClCompile Include="CWGLManager.cpp">\r
       <Filter>Irrlicht\video\OpenGL Context</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="Irrlicht.rc" />\r
index 22385f150145ca74af7c54a62891add76aa0cc44..47f07a3ac95cea6cae0575bd6d1a217bb21073e2 100644 (file)
     <ClInclude Include="..\..\include\IGUIToolbar.h" />\r
     <ClInclude Include="..\..\include\IGUITreeView.h" />\r
     <ClInclude Include="..\..\include\IGUIWindow.h" />\r
+    <ClInclude Include="burning_shader_color_fraq.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+    <ClInclude Include="burning_shader_compile_start.h" />\r
+    <ClInclude Include="burning_shader_compile_triangle.h" />\r
+    <ClInclude Include="burning_shader_compile_verify.h" />\r
     <ClInclude Include="CB3DMeshWriter.h" />\r
+    <ClInclude Include="CBlit.h" />\r
     <ClInclude Include="CD3D9RenderTarget.h" />\r
     <ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
     <ClInclude Include="CDefaultSceneNodeFactory.h" />\r
     <None Include="..\..\readme.txt" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ClCompile Include="burning_shader_color.cpp" />\r
     <ClCompile Include="CB3DMeshWriter.cpp" />\r
     <ClCompile Include="CD3D9RenderTarget.cpp" />\r
     <ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
     <ClCompile Include="CQ3LevelMesh.cpp" />\r
     <ClCompile Include="CSkinnedMesh.cpp" />\r
     <ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
     <ClCompile Include="CWGLManager.cpp" />\r
     <ClCompile Include="CXMeshFileLoader.cpp" />\r
     <ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
index ed8c285bafc66822daf68d2968f45213528cb882..077634de35fcaf6bd1c6cde54ab4bbbb92c57501 100644 (file)
     <ClInclude Include="..\..\include\IOctreeSceneNode.h">\r
       <Filter>include\scene</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="burning_shader_color_fraq.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_triangle.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_verify.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="CBlit.h">\r
+      <Filter>Irrlicht\video\Null</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="..\..\changes.txt">\r
     <ClCompile Include="CWGLManager.cpp">\r
       <Filter>Irrlicht\video\OpenGL Context</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="burning_shader_color.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="Irrlicht.rc" />\r
index 3e7660787d568a10301ab787a745485e37d17eb6..4ae8670cde04313ee4c88d37caa9f9bb744b94d0 100644 (file)
     <ClInclude Include="..\..\include\IGUIToolbar.h" />\r
     <ClInclude Include="..\..\include\IGUITreeView.h" />\r
     <ClInclude Include="..\..\include\IGUIWindow.h" />\r
+    <ClInclude Include="burning_shader_color_fraq.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h" />\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h" />\r
+    <ClInclude Include="burning_shader_compile_start.h" />\r
+    <ClInclude Include="burning_shader_compile_triangle.h" />\r
+    <ClInclude Include="burning_shader_compile_verify.h" />\r
     <ClInclude Include="CB3DMeshWriter.h" />\r
     <ClInclude Include="CD3D9RenderTarget.h" />\r
     <ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />\r
     <None Include="Irrlicht.ruleset" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ClCompile Include="burning_shader_color.cpp" />\r
     <ClCompile Include="CB3DMeshWriter.cpp" />\r
     <ClCompile Include="CD3D9RenderTarget.cpp" />\r
     <ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />\r
     <ClCompile Include="CQ3LevelMesh.cpp" />\r
     <ClCompile Include="CSkinnedMesh.cpp" />\r
     <ClCompile Include="CSTLMeshFileLoader.cpp" />\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp" />\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp" />\r
     <ClCompile Include="CWGLManager.cpp" />\r
     <ClCompile Include="CXMeshFileLoader.cpp" />\r
     <ClCompile Include="CAnimatedMeshSceneNode.cpp" />\r
index 7230ff84c6fc449a0df93d2014f856913adc5b0a..16c0835f43158226927759e649961ab9882b4378 100644 (file)
     <ClInclude Include="..\..\include\SOverrideMaterial.h">\r
       <Filter>include\video</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="burning_shader_color_fraq.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_default.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_end.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_fragment_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_start.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_triangle.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="burning_shader_compile_verify.h">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="..\..\changes.txt">\r
     <ClCompile Include="CWGLManager.cpp">\r
       <Filter>Irrlicht\video\OpenGL Context</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="burning_shader_color.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTR_transparent_reflection_2_layer.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="CTRGouraudNoZ2.cpp">\r
+      <Filter>Irrlicht\video\Burning Video</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ResourceCompile Include="Irrlicht.rc" />\r
index 37b14fb35148e8a13262a7b1b4a85c01529a05f5..c967d24764d197d412a1a503bf7a75e5c8c3c4ae 100644 (file)
@@ -47,7 +47,13 @@ IRRDRVROBJ = CNullDriver.o COpenGLCacheHandler.o COpenGLDriver.o COpenGLNormalMa
 IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderDDS.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderPVR.o CImageLoaderTGA.o CImageLoaderPPM.o CImageLoaderWAL.o CImageLoaderRGB.o \\r
        CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o\r
 IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)\r
-IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o\r
+IRRSWRENDEROBJ = CSoftwareDriver.o CSoftwareTexture.o CTRFlat.o CTRFlatWire.o CTRGouraud.o CTRGouraudWire.o CTRNormalMap.o \\r
+       CTRStencilShadow.o CTRTextureFlat.o CTRTextureFlatWire.o CTRTextureGouraud.o CTRTextureGouraudAdd.o CTRTextureGouraudNoZ.o \\r
+       CTRTextureGouraudWire.o CZBuffer.o CTRTextureGouraudVertexAlpha2.o CTRTextureGouraudNoZ2.o CTRTextureLightMap2_M2.o \\r
+       CTRTextureLightMap2_M4.o CTRTextureLightMap2_M1.o CSoftwareDriver2.o CSoftwareTexture2.o CTRTextureGouraud2.o CTRGouraud2.o \\r
+       CTRGouraudAlpha2.o CTRGouraudAlphaNoZ2.o CTRTextureDetailMap2.o CTRTextureGouraudAdd2.o CTRTextureGouraudAddNoZ2.o CTRTextureWire2.o \\r
+       CTRTextureLightMap2_Add.o CTRTextureLightMapGouraud2_M4.o IBurningShader.o CTRTextureBlend.o CTRTextureGouraudAlpha.o \\r
+       CTRTextureGouraudAlphaNoZ.o CDepthBuffer.o CBurningShader_Raster_Reference.o CTR_transparent_reflection_2_layer.o CTRGouraudNoZ2.o burning_shader_color.o\r
 IRRIOOBJ = CFileList.o CFileSystem.o CLimitReadFile.o CMemoryFile.o CReadFile.o CWriteFile.o CXMLReader.o CXMLWriter.o CWADReader.o CZipReader.o CPakReader.o CNPKReader.o CTarReader.o CMountPointReader.o irrXML.o CAttributes.o lzma/LzmaDec.o\r
 IRROTHEROBJ = CIrrDeviceSDL.o CIrrDeviceLinux.o CIrrDeviceConsole.o CIrrDeviceStub.o CIrrDeviceWin32.o CIrrDeviceFB.o CLogger.o COSOperator.o Irrlicht.o os.o leakHunter.o     CProfiler.o utf8.o\r
 IRRGUIOBJ = CGUIButton.o CGUICheckBox.o CGUIComboBox.o CGUIContextMenu.o CGUIEditBox.o CGUIEnvironment.o CGUIFileOpenDialog.o CGUIFont.o CGUIImage.o CGUIInOutFader.o CGUIListBox.o CGUIMenu.o CGUIMeshViewer.o CGUIMessageBox.o CGUIModalScreen.o CGUIScrollBar.o CGUISpinBox.o CGUISkin.o CGUIStaticText.o CGUITabControl.o CGUITable.o CGUIToolBar.o CGUIWindow.o CGUIColorSelectDialog.o CDefaultGUIElementFactory.o CGUISpriteBank.o CGUIImageList.o CGUITreeView.o CGUIProfiler.o\r
index 7ad6b83de99b41e31d5ae6587cf15aec397368f9..92abbb26edf42c21cd811dcf25ea8f4fda6bbde6 100644 (file)
@@ -9,6 +9,7 @@
 #include "SoftwareDriver2_compile_config.h"\r
 #include "SoftwareDriver2_helper.h"\r
 #include "irrAllocator.h"\r
+#include "EPrimitiveTypes.h"\r
 \r
 namespace irr\r
 {\r
@@ -16,6 +17,7 @@ namespace irr
 namespace video\r
 {\r
 \r
+//! sVec2 used in BurningShader texture coordinates\r
 struct sVec2\r
 {\r
        f32 x;\r
@@ -34,10 +36,10 @@ struct sVec2
        }\r
 \r
        // f = a * t + b * ( 1 - t )\r
-       void interpolate(const sVec2& a, const sVec2& b, const f32 t)\r
+       void interpolate(const sVec2& burning_restrict a, const sVec2& burning_restrict b, const ipoltype t)\r
        {\r
-               x = b.x + ( ( a.x - b.x ) * t );\r
-               y = b.y + ( ( a.y - b.y ) * t );\r
+               x = (f32)(b.x + ( ( a.x - b.x ) * t ));\r
+               y = (f32)(b.y + ( ( a.y - b.y ) * t ));\r
        }\r
 \r
        sVec2 operator-(const sVec2& other) const\r
@@ -75,333 +77,298 @@ struct sVec2
 \r
 };\r
 \r
-// A8R8G8B8\r
-struct sVec4;\r
-struct sCompressedVec4\r
+#include "irrpack.h"\r
+\r
+//! sVec3Pack used in BurningShader, packed direction\r
+struct sVec3Pack\r
 {\r
-       u32 argb;\r
+       f32 x, y, z;\r
+       //f32 _can_pack;\r
+\r
+       sVec3Pack() {}\r
+       sVec3Pack(f32 _x, f32 _y, f32 _z)\r
+               : x(_x), y(_y), z(_z) {}\r
 \r
-       void setA8R8G8B8 ( u32 value )\r
+       // f = a * t + b * ( 1 - t )\r
+       void interpolate(const sVec3Pack& burning_restrict v0, const sVec3Pack& burning_restrict v1, const ipoltype t)\r
        {\r
-               argb = value;\r
+               x = (f32)(v1.x + ((v0.x - v1.x) * t));\r
+               y = (f32)(v1.y + ((v0.y - v1.y) * t));\r
+               z = (f32)(v1.z + ((v0.z - v1.z) * t));\r
        }\r
 \r
-       void setColorf ( const video::SColorf & color )\r
+       sVec3Pack operator-(const sVec3Pack& other) const\r
        {\r
-               argb = core::floor32_fast( color.a * 255.f ) << 24 |\r
-                               core::floor32_fast( color.r * 255.f ) << 16 |\r
-                               core::floor32_fast( color.g * 255.f ) << 8  |\r
-                               core::floor32_fast( color.b * 255.f );\r
+               return sVec3Pack(x - other.x, y - other.y, z - other.z);\r
        }\r
 \r
-       void setVec4 ( const sVec4 & v );\r
+       sVec3Pack operator+(const sVec3Pack& other) const\r
+       {\r
+               return sVec3Pack(x + other.x, y + other.y, z + other.z);\r
+       }\r
 \r
-       // f = a * t + b * ( 1 - t )\r
-       void interpolate(const sCompressedVec4& a, const sCompressedVec4& b, const f32 t)\r
+       sVec3Pack operator*(const f32 s) const\r
        {\r
-               argb = PixelBlend32 ( b.argb, a.argb, core::floor32_fast( t * 256.f ) );\r
+               return sVec3Pack(x * s, y * s, z * s);\r
        }\r
 \r
+       void operator+=(const sVec3Pack& other)\r
+       {\r
+               x += other.x;\r
+               y += other.y;\r
+               z += other.z;\r
+       }\r
 \r
-};\r
+       void operator=(const sVec3Pack& other)\r
+       {\r
+               x = other.x;\r
+               y = other.y;\r
+               z = other.z;\r
+       }\r
 \r
+}  PACK_STRUCT;\r
 \r
+#include "irrunpack.h"\r
+\r
+//! sVec4 used in Driver,BurningShader, direction/color\r
 struct sVec4\r
 {\r
        union\r
        {\r
                struct { f32 x, y, z, w; };\r
                struct { f32 a, r, g, b; };\r
-//             struct { sVec2 xy, zw; };       // sorry, this does not compile with gcc\r
        };\r
 \r
-\r
-\r
        sVec4 () {}\r
-\r
-       sVec4 ( f32 s) : x ( s ), y ( s ), z ( s ), w ( s ) {}\r
-\r
        sVec4 ( f32 _x, f32 _y, f32 _z, f32 _w )\r
                : x ( _x ), y ( _y ), z( _z ), w ( _w ){}\r
 \r
-       void set ( f32 _x, f32 _y, f32 _z, f32 _w )\r
-       {\r
-               x = _x;\r
-               y = _y;\r
-               z = _z;\r
-               w = _w;\r
-       }\r
-\r
-       void setA8R8G8B8 ( u32 argb )\r
-       {\r
-               x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f );\r
-               y = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f );\r
-               z = ( ( argb & 0x0000FF00 ) >>  8 ) * ( 1.f / 255.f );\r
-               w = ( ( argb & 0x000000FF )       ) * ( 1.f / 255.f );\r
-       }\r
-\r
-\r
-       void setColorf ( const video::SColorf & color )\r
-       {\r
-               x = color.a;\r
-               y = color.r;\r
-               z = color.g;\r
-               w = color.b;\r
-       }\r
-\r
-\r
        // f = a * t + b * ( 1 - t )\r
-       void interpolate(const sVec4& a, const sVec4& b, const f32 t)\r
+       void interpolate(const sVec4& burning_restrict a, const sVec4& burning_restrict b, const ipoltype t)\r
        {\r
-               x = b.x + ( ( a.x - b.x ) * t );\r
-               y = b.y + ( ( a.y - b.y ) * t );\r
-               z = b.z + ( ( a.z - b.z ) * t );\r
-               w = b.w + ( ( a.w - b.w ) * t );\r
+               x = (f32)(b.x + ( ( a.x - b.x ) * t ));\r
+               y = (f32)(b.y + ( ( a.y - b.y ) * t ));\r
+               z = (f32)(b.z + ( ( a.z - b.z ) * t ));\r
+               w = (f32)(b.w + ( ( a.w - b.w ) * t ));\r
        }\r
 \r
-\r
-       f32 dotProduct(const sVec4& other) const\r
+       sVec4 operator-(const sVec4& other) const\r
        {\r
-               return x*other.x + y*other.y + z*other.z + w*other.w;\r
+               return sVec4(x - other.x, y - other.y, z - other.z,w - other.w);\r
        }\r
 \r
-       f32 dot_xyz( const sVec4& other) const\r
+       sVec4 operator+(const sVec4& other) const\r
        {\r
-               return x*other.x + y*other.y + z*other.z;\r
+               return sVec4(x + other.x, y + other.y, z + other.z,w + other.w);\r
        }\r
 \r
-       f32 get_length_xyz_square () const\r
+       void operator+=(const sVec4& other)\r
        {\r
-               return x * x + y * y + z * z;\r
+               x += other.x;\r
+               y += other.y;\r
+               z += other.z;\r
+               w += other.w;\r
        }\r
 \r
-       f32 get_length_xyz () const\r
+       sVec4 operator*(const f32 s) const\r
        {\r
-               return core::squareroot ( x * x + y * y + z * z );\r
+               return sVec4(x * s , y * s, z * s,w * s);\r
        }\r
 \r
-       void normalize_xyz ()\r
+       sVec4 operator*(const sVec4 &other) const\r
        {\r
-               const f32 l = core::reciprocal_squareroot ( x * x + y * y + z * z );\r
-\r
-               x *= l;\r
-               y *= l;\r
-               z *= l;\r
+               return sVec4(x * other.x , y * other.y, z * other.z,w * other.w);\r
        }\r
 \r
-       void project_xyz ()\r
+       void operator*=(const sVec4 &other)\r
        {\r
-               w = core::reciprocal ( w );\r
-               x *= w;\r
-               y *= w;\r
-               z *= w;\r
+               x *= other.x;\r
+               y *= other.y;\r
+               z *= other.z;\r
+               w *= other.w;\r
        }\r
 \r
-       sVec4 operator-(const sVec4& other) const\r
+       void operator=(const sVec4& other)\r
        {\r
-               return sVec4(x - other.x, y - other.y, z - other.z,w - other.w);\r
+               x = other.x;\r
+               y = other.y;\r
+               z = other.z;\r
+               w = other.w;\r
        }\r
 \r
-       sVec4 operator+(const sVec4& other) const\r
+       //outside shader\r
+       void set(f32 _x, f32 _y, f32 _z, f32 _w)\r
        {\r
-               return sVec4(x + other.x, y + other.y, z + other.z,w + other.w);\r
+               x = _x;\r
+               y = _y;\r
+               z = _z;\r
+               w = _w;\r
        }\r
-\r
-       void operator+=(const sVec4& other)\r
+       void setA8R8G8B8(const u32 argb)\r
        {\r
-               x += other.x;\r
-               y += other.y;\r
-               z += other.z;\r
-               w += other.w;\r
+               a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);\r
+               r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);\r
+               g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);\r
+               b = ((argb & 0x000000FF)      ) * (1.f / 255.f);\r
        }\r
 \r
-       sVec4 operator*(const f32 s) const\r
+       REALINLINE ipoltype dot_xyzw(const sVec4& other) const\r
        {\r
-               return sVec4(x * s , y * s, z * s,w * s);\r
+               return (ipoltype)x * other.x + (ipoltype)y * other.y + (ipoltype)z * other.z + (ipoltype)w * other.w;\r
        }\r
 \r
-       sVec4 operator*(const sVec4 &other) const\r
+       REALINLINE f32 dot_xyz(const sVec4& other) const\r
        {\r
-               return sVec4(x * other.x , y * other.y, z * other.z,w * other.w);\r
+               return x * other.x + y * other.y + z * other.z;\r
        }\r
 \r
-       void mulReciprocal ( f32 s )\r
+       REALINLINE f32 dot_minus_xyz(const sVec4& other) const\r
        {\r
-               const f32 i = core::reciprocal ( s );\r
-               x = (f32) ( x * i );\r
-               y = (f32) ( y * i );\r
-               z = (f32) ( z * i );\r
-               w = (f32) ( w * i );\r
+               return -x * other.x + -y * other.y + -z * other.z;\r
        }\r
 \r
-       void mul ( const f32 s )\r
+       void mul_xyz(const f32 s)\r
        {\r
                x *= s;\r
                y *= s;\r
                z *= s;\r
-               w *= s;\r
        }\r
 \r
-/*\r
-       void operator*=(f32 s)\r
+       f32 length_xyz() const\r
        {\r
-               x *= s;\r
-               y *= s;\r
-               z *= s;\r
-               w *= s;\r
+               return sqrtf(x * x + y * y + z * z);\r
        }\r
-*/\r
-       void operator*=(const sVec4 &other)\r
+\r
+       void normalize_dir_xyz()\r
        {\r
-               x *= other.x;\r
-               y *= other.y;\r
-               z *= other.z;\r
-               w *= other.w;\r
+               //const f32 l = core::reciprocal_squareroot(x * x + y * y + z * z);\r
+               f32 l = x * x + y * y + z * z;\r
+               l = l > 0.0000001f ? 1.f / sqrtf(l) : 1.f;\r
+               x *= l;\r
+               y *= l;\r
+               z *= l;\r
        }\r
 \r
-       void operator=(const sVec4& other)\r
+\r
+       //unpack sVec3 to aligned during runtime\r
+       sVec4(const sVec3Pack& other)\r
        {\r
                x = other.x;\r
                y = other.y;\r
                z = other.z;\r
-               w = other.w;\r
+               w = 0.f;\r
        }\r
-};\r
 \r
-struct sVec3\r
-{\r
-       union\r
+       void normalize_pack_xyz(sVec3Pack& out, const f32 len, const f32 ofs) const\r
        {\r
-               struct { f32 r, g, b; };\r
-               struct { f32 x, y, z; };\r
-       };\r
+               //const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b );\r
+               f32 l = x * x + y * y + z * z;\r
 \r
+               l = l > 0.0000001f ? len / sqrtf(l) : 0.f;\r
+               out.x = (x*l) + ofs;\r
+               out.y = (y*l) + ofs;\r
+               out.z = (z*l) + ofs;\r
+       }\r
 \r
-       sVec3 () {}\r
-       sVec3 ( f32 _x, f32 _y, f32 _z )\r
-               : r ( _x ), g ( _y ), b( _z ) {}\r
+};\r
 \r
-       sVec3 ( const sVec4 &v )\r
-               : r ( v.x ), g ( v.y ), b( v.z ) {}\r
+//!during runtime sVec3Pack\r
+typedef sVec4 sVec3Pack_unpack;\r
 \r
-       void set ( f32 _r, f32 _g, f32 _b )\r
+//!sVec4 is argb. sVec3Color is rgba\r
+struct sVec3Color\r
+{\r
+       f32 r, g, b,a;\r
+\r
+       void set(const f32 s)\r
        {\r
-               r = _r;\r
-               g = _g;\r
-               b = _b;\r
+               r = s;\r
+               g = s;\r
+               b = s;\r
+               a = s;\r
        }\r
 \r
-       void setR8G8B8 ( u32 argb )\r
+       void setA8R8G8B8(const u32 argb)\r
        {\r
-               r = ( ( argb & 0x00FF0000 ) >> 16 ) * ( 1.f / 255.f );\r
-               g = ( ( argb & 0x0000FF00 ) >>  8 ) * ( 1.f / 255.f );\r
-               b = ( ( argb & 0x000000FF )       ) * ( 1.f / 255.f );\r
+               r = ((argb & 0x00FF0000) >> 16) * (1.f / 255.f);\r
+               g = ((argb & 0x0000FF00) >> 8 ) * (1.f / 255.f);\r
+               b = ((argb & 0x000000FF)      ) * (1.f / 255.f);\r
+               a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);\r
        }\r
 \r
-       void setColorf ( const video::SColorf & color )\r
+       void setColorf(const video::SColorf & color)\r
        {\r
                r = color.r;\r
                g = color.g;\r
                b = color.b;\r
+               a = color.a;\r
        }\r
 \r
-       void add (const sVec3& other)\r
+       void add_rgb(const sVec3Color& other)\r
        {\r
                r += other.r;\r
                g += other.g;\r
                b += other.b;\r
        }\r
 \r
-       void mulAdd(const sVec3& other, const f32 v)\r
+       void mad_rgb(const sVec3Color& other, const f32 v)\r
        {\r
                r += other.r * v;\r
                g += other.g * v;\r
                b += other.b * v;\r
        }\r
 \r
-       void mulAdd(const sVec3& v0, const sVec3& v1)\r
+       void mad_rgbv(const sVec3Color& v0, const sVec3Color& v1)\r
        {\r
                r += v0.r * v1.r;\r
                g += v0.g * v1.g;\r
                b += v0.b * v1.b;\r
        }\r
 \r
-       void saturate ( sVec4 &dest, u32 argb )\r
-       {\r
-               dest.x = ( ( argb & 0xFF000000 ) >> 24 ) * ( 1.f / 255.f );\r
-               dest.y = core::min_ ( r, 1.f );\r
-               dest.z = core::min_ ( g, 1.f );\r
-               dest.w = core::min_ ( b, 1.f );\r
-       }\r
-\r
-       // f = a * t + b * ( 1 - t )\r
-       void interpolate(const sVec3& v0, const sVec3& v1, const f32 t)\r
-       {\r
-               r = v1.r + ( ( v0.r - v1.r ) * t );\r
-               g = v1.g + ( ( v0.g - v1.g ) * t );\r
-               b = v1.b + ( ( v0.b - v1.b ) * t );\r
-       }\r
-\r
-       sVec3 operator-(const sVec3& other) const\r
+       //sVec4 is a,r,g,b, alpha pass\r
+       void sat(sVec4 &dest, const u32 argb) const\r
        {\r
-               return sVec3(r - other.r, b - other.b, g - other.g);\r
+               dest.a = ((argb & 0xFF000000) >> 24) * (1.f / 255.f);\r
+               dest.r = r <= 1.f ? r : 1.f;\r
+               dest.g = g <= 1.f ? g : 1.f;\r
+               dest.b = b <= 1.f ? b : 1.f;\r
        }\r
 \r
-       sVec3 operator+(const sVec3& other) const\r
+       void sat_xyz(sVec3Pack &dest, const sVec3Color& v1) const\r
        {\r
-               return sVec3(r + other.r, g + other.g, b + other.b);\r
+               f32 v;\r
+               v = r * v1.r;   dest.x = v < 1.f ? v : 1.f;\r
+               v = g * v1.g;   dest.y = v < 1.f ? v : 1.f;\r
+               v = b * v1.b;   dest.z = v < 1.f ? v : 1.f;\r
        }\r
 \r
-       sVec3 operator*(const f32 s) const\r
+       void sat_xyz(sVec4 &dest, const sVec3Color& v1) const\r
        {\r
-               return sVec3(r * s , g * s, b * s);\r
+               f32 v;\r
+               dest.a = 1.f;\r
+               v = r * v1.r;   dest.r = v < 1.f ? v : 1.f;\r
+               v = g * v1.g;   dest.g = v < 1.f ? v : 1.f;\r
+               v = b * v1.b;   dest.b = v < 1.f ? v : 1.f;\r
        }\r
 \r
-       sVec3 operator/(const f32 s) const\r
-       {\r
-               f32 inv = 1.f / s;\r
-               return sVec3(r * inv , g * inv, b * inv);\r
-       }\r
-\r
-       sVec3 operator*(const sVec3 &other) const\r
-       {\r
-               return sVec3(r * other.r , b * other.b, g * other.g);\r
-       }\r
-\r
-       void operator+=(const sVec3& other)\r
-       {\r
-               r += other.r;\r
-               g += other.g;\r
-               b += other.b;\r
-       }\r
-\r
-       void setLength ( f32 len )\r
-       {\r
-               const f32 l = len * core::reciprocal_squareroot ( r * r + g * g + b * b );\r
-\r
-               r *= l;\r
-               g *= l;\r
-               b *= l;\r
-       }\r
 \r
 };\r
 \r
-\r
-\r
-inline void sCompressedVec4::setVec4 ( const sVec4 & v )\r
-{\r
-       argb = core::floor32_fast( v.x * 255.f ) << 24 |\r
-                       core::floor32_fast( v.y * 255.f ) << 16 |\r
-                       core::floor32_fast( v.z * 255.f ) << 8  |\r
-                       core::floor32_fast( v.w * 255.f );\r
-}\r
-\r
-\r
+//internal BurningShaderFlag for a Vertex\r
 enum e4DVertexFlag\r
 {\r
-       VERTEX4D_INSIDE         = 0x0000003F,\r
-       VERTEX4D_CLIPMASK       = 0x0000003F,\r
-       VERTEX4D_PROJECTED      = 0x00000100,\r
+       VERTEX4D_CLIPMASK                               = 0x0000003F,\r
+       VERTEX4D_CLIP_NEAR                              = 0x00000001,\r
+       VERTEX4D_CLIP_FAR                               = 0x00000002,\r
+       VERTEX4D_CLIP_LEFT                              = 0x00000004,\r
+       VERTEX4D_CLIP_RIGHT                             = 0x00000008,\r
+       VERTEX4D_CLIP_BOTTOM                    = 0x00000010,\r
+       VERTEX4D_CLIP_TOP                               = 0x00000020,\r
+       VERTEX4D_INSIDE                                 = 0x0000003F,\r
+\r
+       VERTEX4D_PROJECTED                              = 0x00000100,\r
+       VERTEX4D_VAL_ZERO                               = 0x00000200,\r
+       VERTEX4D_VAL_ONE                                = 0x00000400,\r
 \r
        VERTEX4D_FORMAT_MASK                    = 0xFFFF0000,\r
 \r
@@ -413,113 +380,291 @@ enum e4DVertexFlag
 \r
        VERTEX4D_FORMAT_MASK_COLOR              = 0x00F00000,\r
        VERTEX4D_FORMAT_COLOR_1                 = 0x00100000,\r
-       VERTEX4D_FORMAT_COLOR_2                 = 0x00200000,\r
+       VERTEX4D_FORMAT_COLOR_2_FOG             = 0x00200000,\r
+       VERTEX4D_FORMAT_COLOR_3                 = 0x00300000,\r
+       VERTEX4D_FORMAT_COLOR_4                 = 0x00400000,\r
+\r
+       VERTEX4D_FORMAT_MASK_LIGHT              = 0x0F000000,\r
+       VERTEX4D_FORMAT_LIGHT_1                 = 0x01000000,\r
+       VERTEX4D_FORMAT_LIGHT_2                 = 0x02000000,\r
 \r
-       VERTEX4D_FORMAT_MASK_BUMP               = 0x0F000000,\r
-       VERTEX4D_FORMAT_BUMP_DOT3               = 0x01000000,\r
+       VERTEX4D_FORMAT_MASK_TANGENT    = 0xF0000000,\r
+       VERTEX4D_FORMAT_BUMP_DOT3               = 0x10000000,\r
+       VERTEX4D_FORMAT_SPECULAR                = 0x20000000,\r
 \r
 };\r
 \r
-const u32 MATERIAL_MAX_COLORS = 1;\r
-const u32 BURNING_MATERIAL_MAX_TEXTURES = 2;\r
-const u32 BURNING_MATERIAL_MAX_TANGENT = 1;\r
+//! vertex layout\r
+enum e4DVertexType\r
+{\r
+       E4VT_STANDARD = 0,                      // EVT_STANDARD, video::S3DVertex.\r
+       E4VT_2TCOORDS = 1,                      // EVT_2TCOORDS, video::S3DVertex2TCoords.\r
+       E4VT_TANGENTS = 2,                      // EVT_TANGENTS, video::S3DVertexTangents\r
+       E4VT_REFLECTION_MAP = 3,\r
+       E4VT_SHADOW = 4,                        // float * 3\r
+       E4VT_NO_TEXTURE = 5,            // runtime if texture missing\r
+       E4VT_LINE = 6,\r
+\r
+       E4VT_COUNT\r
+};\r
+\r
+enum e4DIndexType\r
+{\r
+       E4IT_16BIT = 1, // EIT_16BIT,\r
+       E4IT_32BIT = 2, // EIT_32BIT,\r
+       E4IT_NONE  = 4, //\r
+};\r
+\r
+#ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
+       #define BURNING_MATERIAL_MAX_TEXTURES 4\r
+       #define BURNING_MATERIAL_MAX_COLORS 4\r
+       #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1\r
+\r
+       //ensure handcrafted sizeof(s4DVertex)\r
+       #define sizeof_s4DVertex        128\r
+\r
+#else\r
+       #define BURNING_MATERIAL_MAX_TEXTURES 2\r
+       #ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+               #define BURNING_MATERIAL_MAX_COLORS 1\r
+       #else\r
+               #define BURNING_MATERIAL_MAX_COLORS 0\r
+       #endif\r
+       #define BURNING_MATERIAL_MAX_LIGHT_TANGENT 1\r
+\r
+       //ensure handcrafted sizeof(s4DVertex)\r
+       #define sizeof_s4DVertex        64\r
+#endif\r
 \r
 // dummy Vertex. used for calculation vertex memory size\r
 struct s4DVertex_proxy\r
 {\r
-       u32 flag;\r
        sVec4 Pos;\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
        sVec2 Tex[BURNING_MATERIAL_MAX_TEXTURES];\r
-\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-       sVec4 Color[MATERIAL_MAX_COLORS];\r
 #endif\r
-\r
-       sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT];\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+       sVec4 Color[BURNING_MATERIAL_MAX_COLORS];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+       sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
+#endif\r
+       u32 flag; // e4DVertexFlag\r
 \r
 };\r
 \r
-#define SIZEOF_SVERTEX 64\r
-#define SIZEOF_SVERTEX_LOG2    6\r
 \r
 /*!\r
        Internal BurningVideo Vertex\r
 */\r
 struct s4DVertex\r
 {\r
-       u32 flag;\r
-\r
        sVec4 Pos;\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
        sVec2 Tex[ BURNING_MATERIAL_MAX_TEXTURES ];\r
-\r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-       sVec4 Color[ MATERIAL_MAX_COLORS ];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+       sVec4 Color[ BURNING_MATERIAL_MAX_COLORS ];\r
+#endif\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+       sVec3Pack LightTangent[BURNING_MATERIAL_MAX_LIGHT_TANGENT];\r
 #endif\r
 \r
-       sVec3 LightTangent[BURNING_MATERIAL_MAX_TANGENT];\r
+       u32 flag; // e4DVertexFlag\r
 \r
-       //u8 fill [ SIZEOF_SVERTEX - sizeof (s4DVertex_proxy) ];\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1 || BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+       u8 __align [sizeof_s4DVertex - sizeof (s4DVertex_proxy) ];\r
+#endif\r
 \r
        // f = a * t + b * ( 1 - t )\r
-       void interpolate(const s4DVertex& b, const s4DVertex& a, const f32 t)\r
+       void interpolate(const s4DVertex& burning_restrict b, const s4DVertex& burning_restrict a, const ipoltype t)\r
        {\r
-               u32 i;\r
-               u32 size;\r
-\r
                Pos.interpolate ( a.Pos, b.Pos, t );\r
+#if 0\r
+               Tex[0].interpolate(a.Tex[0], b.Tex[0], t);\r
+               Tex[1].interpolate(a.Tex[1], b.Tex[1], t);\r
+               Color[0].interpolate(a.Color[0], b.Color[0], t);\r
+               LightTangent[0].interpolate(a.LightTangent[0], b.LightTangent[0], t);\r
+#endif\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-               size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;\r
+               size_t i;\r
+               size_t size;\r
+\r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
+               size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;\r
                for ( i = 0; i!= size; ++i )\r
                {\r
-                       Color[i].interpolate ( a.Color[i], b.Color[i], t );\r
+                       Tex[i].interpolate ( a.Tex[i], b.Tex[i], t );\r
                }\r
 #endif\r
 \r
-               size = (flag & VERTEX4D_FORMAT_MASK_TEXTURE) >> 16;\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+               size = (flag & VERTEX4D_FORMAT_MASK_COLOR) >> 20;\r
                for ( i = 0; i!= size; ++i )\r
                {\r
-                       Tex[i].interpolate ( a.Tex[i], b.Tex[i], t );\r
+                       Color[i].interpolate ( a.Color[i], b.Color[i], t );\r
                }\r
+#endif\r
 \r
-               size = (flag & VERTEX4D_FORMAT_MASK_BUMP) >> 24;\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+               size = (flag & VERTEX4D_FORMAT_MASK_LIGHT) >> 24;\r
                for ( i = 0; i!= size; ++i )\r
                {\r
                        LightTangent[i].interpolate ( a.LightTangent[i], b.LightTangent[i], t );\r
                }\r
+#endif\r
 \r
        }\r
 };\r
 \r
 // ----------------- Vertex Cache ---------------------------\r
 \r
-struct SAlignedVertex\r
+// Buffer is used as pairs of S4DVertex (0 ... ndc, 1 .. dc and projected)\r
+typedef s4DVertex s4DVertexPair;\r
+#define sizeof_s4DVertexPairRel 2\r
+#define s4DVertex_ofs(index)  ((index)*sizeof_s4DVertexPairRel)\r
+#define s4DVertex_proj(index) ((index)*sizeof_s4DVertexPairRel) + 1\r
+\r
+struct SAligned4DVertex\r
 {\r
-       SAlignedVertex ( u32 element, u32 aligned )\r
-               : ElementSize ( element )\r
+       SAligned4DVertex()\r
+               :data(0),mem(0), ElementSize(0) {}\r
+\r
+       virtual ~SAligned4DVertex ()\r
        {\r
-               u32 byteSize = (ElementSize << SIZEOF_SVERTEX_LOG2 ) + aligned;\r
-               mem = new u8 [ byteSize ];\r
-               data = (s4DVertex*) mem;\r
+               if (mem)\r
+               {\r
+                       delete[] mem;\r
+                       mem = 0;\r
+               }\r
        }\r
 \r
-       virtual ~SAlignedVertex ()\r
+       void resize(size_t element)\r
        {\r
-               delete [] mem;\r
+               if (element > ElementSize)\r
+               {\r
+                       if (mem) delete[] mem;\r
+                       size_t byteSize = align_next(element * sizeof_s4DVertex, 4096);\r
+                       mem = new u8[byteSize];\r
+               }\r
+               ElementSize = element;\r
+               data = (s4DVertex*)mem;\r
        }\r
 \r
-       s4DVertex *data;\r
-       u8 *mem;\r
-       u32 ElementSize;\r
+       s4DVertex* data;        //align to 16 byte\r
+       u8mem;\r
+       size_t ElementSize;\r
 };\r
 \r
+//#define memcpy_s4DVertexPair(dst,src) memcpy(dst,src,sizeof_s4DVertex * 2)\r
+static REALINLINE void memcpy_s4DVertexPair(void* burning_restrict dst, const void* burning_restrict src)\r
+{\r
+       //test alignment -> if already in aligned data\r
+#if 0\r
+       if (((size_t)dst & 0xC) | ((size_t)src & 0xC))\r
+       {\r
+               int g = 1;\r
+       }\r
+#endif\r
+\r
+#if defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 128)\r
+       u64* burning_restrict dst64 = (u64*)dst;\r
+       const u64* burning_restrict src64 = (const u64*)src;\r
+\r
+       dst64[0]  = src64[0];\r
+       dst64[1]  = src64[1];\r
+       dst64[2]  = src64[2];\r
+       dst64[3]  = src64[3];\r
+       dst64[4]  = src64[4];\r
+       dst64[5]  = src64[5];\r
+       dst64[6]  = src64[6];\r
+       dst64[7]  = src64[7];\r
+\r
+       dst64[8]  = src64[8];\r
+       dst64[9]  = src64[9];\r
+       dst64[10] = src64[10];\r
+       dst64[11] = src64[11];\r
+       dst64[12] = src64[12];\r
+       dst64[13] = src64[13];\r
+       dst64[14] = src64[14];\r
+       dst64[15] = src64[15];\r
+\r
+#elif defined(ENV64BIT) && (sizeof_s4DVertex * sizeof_s4DVertexPairRel == 256)\r
+       u64* burning_restrict dst64 = (u64*)dst;\r
+       const u64* burning_restrict src64 = (const u64*)src;\r
+\r
+       dst64[0]  = src64[0];\r
+       dst64[1]  = src64[1];\r
+       dst64[2]  = src64[2];\r
+       dst64[3]  = src64[3];\r
+       dst64[4]  = src64[4];\r
+       dst64[5]  = src64[5];\r
+       dst64[6]  = src64[6];\r
+       dst64[7]  = src64[7];\r
+\r
+       dst64[8]  = src64[8];\r
+       dst64[9]  = src64[9];\r
+       dst64[10] = src64[10];\r
+       dst64[11] = src64[11];\r
+       dst64[12] = src64[12];\r
+       dst64[13] = src64[13];\r
+       dst64[14] = src64[14];\r
+       dst64[15] = src64[15];\r
+\r
+       dst64[16] = src64[16];\r
+       dst64[17] = src64[17];\r
+       dst64[18] = src64[18];\r
+       dst64[19] = src64[19];\r
+       dst64[20] = src64[20];\r
+       dst64[21] = src64[21];\r
+       dst64[22] = src64[22];\r
+       dst64[23] = src64[23];\r
+\r
+       dst64[24] = src64[24];\r
+       dst64[25] = src64[25];\r
+       dst64[26] = src64[26];\r
+       dst64[27] = src64[27];\r
+       dst64[28] = src64[28];\r
+       dst64[29] = src64[29];\r
+       dst64[30] = src64[30];\r
+       dst64[31] = src64[31];\r
 \r
-// hold info for different Vertex Types\r
+#else\r
+       u32* dst32 = (u32*)dst;\r
+       const u32* src32 = (const u32*)src;\r
+\r
+       size_t len = sizeof_s4DVertex * sizeof_s4DVertexPairRel;\r
+       while (len >= 32)\r
+       {\r
+               *dst32++ = *src32++;\r
+               *dst32++ = *src32++;\r
+               *dst32++ = *src32++;\r
+               *dst32++ = *src32++;\r
+               *dst32++ = *src32++;\r
+               *dst32++ = *src32++;\r
+               *dst32++ = *src32++;\r
+               *dst32++ = *src32++;\r
+               len -= 32;\r
+       }\r
+/*\r
+       while (len >= 4)\r
+       {\r
+               *dst32++ = *src32++;\r
+               len -= 4;\r
+       }\r
+*/\r
+#endif\r
+}\r
+\r
+\r
+//! hold info for different Vertex Types\r
 struct SVSize\r
 {\r
-       u32 Format;\r
-       u32 Pitch;\r
-       u32 TexSize;\r
+       size_t Format;          // e4DVertexFlag VERTEX4D_FORMAT_MASK_TEXTURE\r
+       size_t Pitch;           // sizeof Vertex\r
+       size_t TexSize; // amount Textures\r
+       size_t TexCooSize;      // sizeof TextureCoordinates\r
 };\r
 \r
 \r
@@ -530,18 +675,24 @@ struct SCacheInfo
        u32 hit;\r
 };\r
 \r
-#define VERTEXCACHE_ELEMENT    16\r
+//must at least hold all possible (clipped) vertices of primitive.\r
+#define VERTEXCACHE_ELEMENT    16                      \r
 #define VERTEXCACHE_MISS 0xFFFFFFFF\r
 struct SVertexCache\r
 {\r
-       SVertexCache (): mem ( VERTEXCACHE_ELEMENT * 2, 128 ) {}\r
+       SVertexCache () {}\r
+       ~SVertexCache() {}\r
+\r
+       //VertexType\r
+       SVSize vSize[E4VT_COUNT];\r
 \r
        SCacheInfo info[VERTEXCACHE_ELEMENT];\r
+       SCacheInfo info_temp[VERTEXCACHE_ELEMENT];\r
 \r
 \r
        // Transformed and lite, clipping state\r
        // + Clipped, Projected\r
-       SAlignedVertex mem;\r
+       SAligned4DVertex mem;\r
 \r
        // source\r
        const void* vertices;\r
@@ -550,15 +701,15 @@ struct SVertexCache
        const void* indices;\r
        u32 indexCount;\r
        u32 indicesIndex;\r
-\r
        u32 indicesRun;\r
+       u32 indicesPitch;\r
 \r
        // primitives consist of x vertices\r
-       u32 primitivePitch;\r
+       size_t primitiveHasVertex;\r
 \r
-       u32 vType;              //E_VERTEX_TYPE\r
-       u32 pType;              //scene::E_PRIMITIVE_TYPE\r
-       u32 iType;              //E_INDEX_TYPE iType\r
+       e4DVertexType vType;            //E_VERTEX_TYPE\r
+       scene::E_PRIMITIVE_TYPE pType;          //scene::E_PRIMITIVE_TYPE\r
+       e4DIndexType iType;             //E_INDEX_TYPE iType\r
 \r
 };\r
 \r
@@ -579,10 +730,11 @@ REALINLINE void swapVertexPointer(const s4DVertex** v1, const s4DVertex** v2)
 // internal scan convert\r
 struct sScanConvertData\r
 {\r
-       u8 left;                        // major edge left/right\r
-       u8 right;                       // !left\r
+       u32 left;                       // major edge left/right\r
+       u32 right;                      // !left\r
+       u32 _unused_pack[2];\r
 \r
-       f32 invDeltaY[3];       // inverse edge delta y\r
+       f32 invDeltaY[4];       // inverse edge delta for screen space sorted triangle \r
 \r
        f32 x[2];                       // x coordinate\r
        f32 slopeX[2];          // x slope along edges\r
@@ -595,20 +747,27 @@ struct sScanConvertData
        f32 slopeZ[2];          // z slope along edges\r
 #endif\r
 \r
-       sVec4 c[MATERIAL_MAX_COLORS][2];                        // color\r
-       sVec4 slopeC[MATERIAL_MAX_COLORS][2];   // color slope along edges\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+       sVec4 c[BURNING_MATERIAL_MAX_COLORS][2];                // color\r
+       sVec4 slopeC[BURNING_MATERIAL_MAX_COLORS][2];   // color slope along edges\r
+#endif\r
 \r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
        sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2];              // texture\r
        sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES][2]; // texture slope along edges\r
+#endif\r
 \r
-       sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2];               // Light Tangent\r
-       sVec3 slopeL[BURNING_MATERIAL_MAX_TEXTURES][2]; // tanget slope along edges\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+       sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2];              // Light Tangent\r
+       sVec3Pack_unpack slopeL[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2]; // tanget slope along edges\r
+#endif\r
 };\r
 \r
 // passed to scan Line\r
 struct sScanLineData\r
 {\r
        s32 y;                          // y position of scanline\r
+       u32 _unused_pack[1];\r
        f32 x[2];                       // x start, x end of scanline\r
 \r
 #if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )\r
@@ -617,12 +776,19 @@ struct sScanLineData
        f32 z[2];                       // z start, z end of scanline\r
 #endif\r
 \r
-#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-       sVec4 c[MATERIAL_MAX_COLORS][2];                        // color start, color end of scanline\r
+       u32 _unused_pack_1[2];\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS > 0\r
+       sVec4 c[BURNING_MATERIAL_MAX_COLORS][2];                        // color start, color end of scanline\r
 #endif\r
 \r
+#if BURNING_MATERIAL_MAX_TEXTURES > 0\r
        sVec2 t[BURNING_MATERIAL_MAX_TEXTURES][2];              // texture start, texture end of scanline\r
-       sVec3 l[BURNING_MATERIAL_MAX_TANGENT][2];               // Light Tangent start, end\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT > 0\r
+       sVec3Pack_unpack l[BURNING_MATERIAL_MAX_LIGHT_TANGENT][2];              // Light Tangent start, end\r
+#endif\r
 };\r
 \r
 // passed to pixel Shader\r
@@ -640,49 +806,54 @@ struct sPixelShaderData
 /*\r
        load a color value\r
 */\r
-inline void getTexel_plain2 (  tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                                       const sVec4 &v\r
-                                                       )\r
+REALINLINE void getTexel_plain2 (      tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )\r
 {\r
-       r = tofix(v.y, FIX_POINT_F32_MUL);\r
-       g = tofix(v.z, FIX_POINT_F32_MUL);\r
-       b = tofix(v.w, FIX_POINT_F32_MUL);\r
+       r = tofix(v.r, FIX_POINT_F32_MUL);\r
+       g = tofix(v.g, FIX_POINT_F32_MUL);\r
+       b = tofix(v.b, FIX_POINT_F32_MUL);\r
 }\r
 \r
+#if 0\r
 /*\r
        load a color value\r
 */\r
-inline void getSample_color (  tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                                       const sVec4 &v\r
-                                                       )\r
+REALINLINE void getSample_color (      tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const sVec4 &v )\r
 {\r
-       a = tofix(v.x, FIX_POINT_F32_MUL);\r
-       r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL);\r
-       g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL);\r
-       b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL);\r
+       a = tofix ( v.a, FIX_POINT_F32_MUL);\r
+       r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);\r
+       g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);\r
+       b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);\r
 }\r
 \r
 /*\r
        load a color value\r
 */\r
-inline void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )\r
+REALINLINE void getSample_color ( tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v )\r
 {\r
-       r = tofix ( v.y, COLOR_MAX * FIX_POINT_F32_MUL);\r
-       g = tofix ( v.z, COLOR_MAX * FIX_POINT_F32_MUL);\r
-       b = tofix ( v.w, COLOR_MAX * FIX_POINT_F32_MUL);\r
+       r = tofix ( v.r, COLOR_MAX * FIX_POINT_F32_MUL);\r
+       g = tofix ( v.g, COLOR_MAX * FIX_POINT_F32_MUL);\r
+       b = tofix ( v.b, COLOR_MAX * FIX_POINT_F32_MUL);\r
 }\r
+#endif\r
 \r
 /*\r
-       load a color value\r
+       load a color value. mulby controls [0;1] or [0;ColorMax]\r
+       aka getSample_color\r
 */\r
-inline void getSample_color (  tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                                               const sVec4 &v, const f32 mulby )\r
+REALINLINE void vec4_to_fix(tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby )\r
 {\r
-       r = tofix ( v.y, mulby);\r
-       g = tofix ( v.z, mulby);\r
-       b = tofix ( v.w, mulby);\r
+       r = tofix(v.r, mulby);\r
+       g = tofix(v.g, mulby);\r
+       b = tofix(v.b, mulby);\r
 }\r
 \r
+REALINLINE void vec4_to_fix(tFixPoint &a,tFixPoint &r, tFixPoint &g, tFixPoint &b,const sVec4 &v, const f32 mulby)\r
+{\r
+       a = tofix(v.a, mulby);\r
+       r = tofix(v.r, mulby);\r
+       g = tofix(v.g, mulby);\r
+       b = tofix(v.b, mulby);\r
+}\r
 \r
 \r
 }\r
index a471318136a964cb8a5b43772507a0debfb745f2..725ba1a90962ad815378536b51fd311a4f70d995 100644 (file)
@@ -7,10 +7,28 @@
 \r
 #include "IrrCompileConfig.h"\r
 \r
-\r
 // Generic Render Flags for burning's video rasterizer\r
 // defined now in irrlicht compile config\r
 \r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
+       #undef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
+\r
+       //#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+       #define SOFTWARE_DRIVER_2_SUBTEXEL\r
+       //#define SOFTWARE_DRIVER_2_BILINEAR\r
+       #define SOFTWARE_DRIVER_2_LIGHTING\r
+       #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+       #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR\r
+       #define SOFTWARE_DRIVER_2_32BIT\r
+       #define SOFTWARE_DRIVER_2_MIPMAPPING\r
+       #define SOFTWARE_DRIVER_2_USE_WBUFFER\r
+       #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
+       #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               256\r
+       #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+       #define SOFTWARE_DRIVER_2_CLIPPING\r
+       #define SOFTWARE_DRIVER_2_2D_AS_2D\r
+#endif\r
+\r
 \r
 #ifdef BURNINGVIDEO_RENDERER_BEAUTIFUL\r
        #define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
        #define SOFTWARE_DRIVER_2_BILINEAR\r
        #define SOFTWARE_DRIVER_2_LIGHTING\r
        #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+       #define SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR\r
        #define SOFTWARE_DRIVER_2_32BIT\r
        #define SOFTWARE_DRIVER_2_MIPMAPPING\r
        #define SOFTWARE_DRIVER_2_USE_WBUFFER\r
        #define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
        #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               0\r
+       #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+       #define SOFTWARE_DRIVER_2_CLIPPING\r
+       #define SOFTWARE_DRIVER_2_2D_AS_3D\r
 #endif\r
 \r
 //! Set Flags for Windows Mobile\r
        #define SOFTWARE_DRIVER_2_MIPMAPPING\r
        #define SOFTWARE_DRIVER_2_USE_WBUFFER\r
        //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
-       #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               128\r
+       #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               64\r
+       #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+       //#define SOFTWARE_DRIVER_2_CLIPPING\r
+       #define SOFTWARE_DRIVER_2_2D_AS_2D\r
 #endif\r
 \r
 #ifdef BURNINGVIDEO_RENDERER_FAST\r
        #define SOFTWARE_DRIVER_2_SUBTEXEL\r
        //#define SOFTWARE_DRIVER_2_BILINEAR\r
        //#define SOFTWARE_DRIVER_2_LIGHTING\r
-       //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
-       #define SOFTWARE_DRIVER_2_32BIT\r
+       #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+       //#define SOFTWARE_DRIVER_2_32BIT\r
+       #define SOFTWARE_DRIVER_2_16BIT\r
        #define SOFTWARE_DRIVER_2_MIPMAPPING\r
        #define SOFTWARE_DRIVER_2_USE_WBUFFER\r
-       #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               0\r
+       #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               256\r
+       #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+       #define SOFTWARE_DRIVER_2_CLIPPING\r
+       #define SOFTWARE_DRIVER_2_2D_AS_2D\r
 #endif\r
 \r
 #ifdef BURNINGVIDEO_RENDERER_ULTRA_FAST\r
        #define BURNINGVIDEO_RENDERER_FAST\r
 \r
        //#define SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
-       #define SOFTWARE_DRIVER_2_SUBTEXEL\r
+       //#define SOFTWARE_DRIVER_2_SUBTEXEL\r
        //#define SOFTWARE_DRIVER_2_BILINEAR\r
        //#define SOFTWARE_DRIVER_2_LIGHTING\r
-       //#define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+       #define SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
        //#define SOFTWARE_DRIVER_2_32BIT\r
-       #define SOFTWARE_DRIVER_2_MIPMAPPING\r
-       #define SOFTWARE_DRIVER_2_USE_WBUFFER\r
-       #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               0\r
+       #define SOFTWARE_DRIVER_2_16BIT\r
+       //#define SOFTWARE_DRIVER_2_MIPMAPPING\r
+       //#define SOFTWARE_DRIVER_2_USE_WBUFFER\r
+       //#define SOFTWARE_DRIVER_2_TEXTURE_TRANSFORM\r
+       #define SOFTWARE_DRIVER_2_TEXTURE_MAXSIZE               128\r
+       #define SOFTWARE_DRIVER_2_SCANLINE_MAG_MIN\r
+       //#define SOFTWARE_DRIVER_2_CLIPPING\r
+       #define SOFTWARE_DRIVER_2_2D_AS_2D\r
 #endif\r
 \r
 // Derivate flags\r
        #define BURNINGSHADER_COLOR_FORMAT      ECF_A1R5G5B5\r
 #endif\r
 \r
-// mip mapping\r
+// mip mapping - precalculated texture filter\r
 #if defined ( SOFTWARE_DRIVER_2_MIPMAPPING )\r
        #if defined( BURNINGVIDEO_RENDERER_BEAUTIFUL )\r
                #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX                16\r
-               #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS   0\r
+               #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE   1\r
        #elif defined ( BURNINGVIDEO_RENDERER_CE )\r
                #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX                4\r
-               #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS   0\r
+               #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE   8\r
        #else\r
-               #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX                8\r
-               #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS   0\r
+               #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX                4\r
+               #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE   8\r
        #endif\r
 #else\r
        #define SOFTWARE_DRIVER_2_MIPMAPPING_MAX                1\r
-       #define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS   0\r
+       #define SOFTWARE_DRIVER_2_MIPMAPPING_MIN_SIZE   1\r
 #endif\r
 \r
-#define SOFTWARE_DRIVER_2_MIPMAPPING_SCALE (16/SOFTWARE_DRIVER_2_MIPMAPPING_MAX)\r
+\r
 \r
 #ifndef REALINLINE\r
        #ifdef _MSC_VER\r
        #endif\r
 #endif\r
 \r
+\r
+// null check necessary (burningvideo only)\r
+#define reciprocal_zero(x) ((x) != 0.f ? 1.f / (x):0.f)\r
+static inline float reciprocal_zero2(float x) { return x != 0.f ? 1.f / x : 0.f; }\r
+#define reciprocal_one(x) ((x) != 0.f ? 1.f / (x):1.f)\r
+\r
+#define fill_convention_left(x) (s32) ceilf(x)\r
+#define fill_convention_right(x) ((s32) ceilf(x))-1\r
+#define fill_convention_none(x) (s32) (x)\r
+//#define fill_convention_left(x) 65536 - int(65536.0f - x)\r
+//#define fill_convention_right(x) 65535 - int(65536.0f - x)\r
+\r
+\r
+//Check coordinates are in render target/window space\r
+//#define SOFTWARE_DRIVER_2_DO_CLIPCHECK\r
+#if defined (SOFTWARE_DRIVER_2_DO_CLIPCHECK) && defined(_WIN32)\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK      if( xStart < 0 || xStart + dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_REF  if( pShader.xStart < 0 || pShader.xStart + pShader.dx >= (s32)RenderTarget->getDimension().Width || line.y < 0 || line.y >= (s32) RenderTarget->getDimension().Height ) __debugbreak()\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE if( aposx < 0 || aposx >= (s32)RenderTarget->getDimension().Width || aposy < 0 || aposy >= (s32) RenderTarget->getDimension().Height ) __debugbreak()\r
+\r
+inline float reciprocal_zero_no(const float x)\r
+{\r
+       if (x*x <= 0.00001f) __debugbreak();\r
+       return 1.f / x;\r
+}\r
+#else\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_REF\r
+#define SOFTWARE_DRIVER_2_CLIPCHECK_WIRE\r
+\r
+#define reciprocal_zero_no(x) 1.f/x\r
 #endif\r
+\r
+//!scanline renderer emulate line\r
+enum edge_test_flag\r
+{\r
+       edge_test_pass = 1,             //! not wireframe\r
+       edge_test_left = 0,\r
+       edge_test_first_line = 2,\r
+       edge_test_point = 4\r
+};\r
+//if any edge test flag is set result=1 else 0. ( pass height test for degenerate triangle )\r
+#define reciprocal_edge(x) ((x) != 0.f ? 1.f / (x):(~EdgeTestPass)&1)\r
+\r
+//! normalize from fixed point Color Max to fixed point [0;1]\r
+#define fix_color_norm(x) x = (x+1) >> COLOR_MAX_LOG2\r
+\r
+//! from 1 bit to 5 bit\r
+#ifdef SOFTWARE_DRIVER_2_32BIT\r
+       #define fix_alpha_color_max(x)\r
+#else\r
+       #define fix_alpha_color_max(x) if (x) x = (x << COLOR_MAX_LOG2) - 1\r
+#endif\r
+\r
+// Check windows\r
+#if _WIN32 || _WIN64\r
+#if _WIN64\r
+       #define ENV64BIT\r
+#else\r
+       #define ENV32BIT\r
+#endif\r
+#endif\r
+\r
+// Check GCC\r
+#if __GNUC__\r
+#if __x86_64__ || __ppc64__\r
+       #define ENV64BIT\r
+#else\r
+       #define ENV32BIT\r
+#endif\r
+#endif\r
+\r
+#if defined(ENV64BIT) && defined(BURNINGVIDEO_RENDERER_BEAUTIFUL)\r
+       typedef float ipoltype;\r
+#else\r
+       typedef float ipoltype;\r
+#endif\r
+\r
+#define        ipol_lower_equal_0(n)   ((n) <= (ipoltype)0.0)\r
+#define        ipol_greater_0(n)               ((n) >  (ipoltype)0.0)\r
+\r
+#if    (_MSC_VER > 1700 )\r
+       #define burning_restrict __restrict\r
+#else\r
+       #define burning_restrict\r
+#endif\r
+\r
+/*\r
+       if (condition) state |= mask; else state &= ~mask;\r
+*/\r
+static inline void burning_setbit(size_t &state, int condition, size_t mask)\r
+{\r
+       if (condition) state |= mask;\r
+       else state &= ~mask;\r
+}\r
+\r
+/*\r
+       if (condition) state |= m; else state &= ~m;\r
+*/\r
+REALINLINE void burning_setbit32(unsigned int &state, int condition, const unsigned int mask)\r
+{\r
+       // 0, or any positive to mask\r
+       //s32 conmask = -condition >> 31;\r
+       state ^= ((-condition >> 31) ^ state) & mask;\r
+}\r
+\r
+#define burning_stringify(s) #s\r
+#define burning_create_indirect(s) create_##s\r
+#define burning_create(s) burning_create_indirect(s)\r
+\r
+\r
+#if defined(PATCH_SUPERTUX_8_0_1)\r
+#define getData lock\r
+#define snprintf_irr sprintf_s\r
+\r
+#ifdef SOFTWARE_DRIVER_2_USE_VERTEX_COLOR\r
+#ifdef SOFTWARE_DRIVER_2_USE_SEPARATE_SPECULAR_COLOR\r
+#define BURNING_MATERIAL_MAX_COLORS 2\r
+#else\r
+#define BURNING_MATERIAL_MAX_COLORS 1\r
+#endif\r
+#else\r
+#define BURNING_MATERIAL_MAX_COLORS 0\r
+#endif\r
+\r
+#ifndef _IRR_OVERRIDE_\r
+#define _IRR_OVERRIDE_ /**/\r
+#endif\r
+\r
+#define fix_to_color fix_to_sample\r
+#define fix4_to_color fix4_to_sample\r
+#define vec4_to_fix getSample_color\r
+#define SOFTWARE_DRIVER_2_MIPMAPPING_LOD_BIAS 0\r
+\r
+namespace irr {\r
+\r
+       REALINLINE void memcpy32_small(void * dest, const void *source, size_t bytesize)\r
+       {\r
+               size_t c = bytesize >> 2;\r
+\r
+               do\r
+               {\r
+                       ((unsigned int *)dest)[c - 1] = ((unsigned int *)source)[c - 1];\r
+               } while (--c);\r
+\r
+       }\r
+\r
+} // namespace irr\r
+#endif // #if defined(PATCH_SUPERTUX_8_0_1)\r
+\r
+\r
+#endif // __S_VIDEO_2_SOFTWARE_COMPILE_CONFIG_H_INCLUDED__\r
index 01e2f4f73b5e2233433a3e53cac0147f49123a59..59a91b8590c3b8a1e51dd37334507501ba26e7ac 100644 (file)
@@ -24,40 +24,42 @@ namespace irr
 \r
 #ifdef SOFTWARE_DRIVER_2_32BIT\r
        typedef u32     tVideoSample;\r
+       typedef u32     tStencilSample;\r
 \r
        #define MASK_A  0xFF000000\r
        #define MASK_R  0x00FF0000\r
        #define MASK_G  0x0000FF00\r
        #define MASK_B  0x000000FF\r
 \r
-       #define SHIFT_A 24\r
-       #define SHIFT_R 16\r
-       #define SHIFT_G 8\r
-       #define SHIFT_B 0\r
+       #define SHIFT_A (unsigned)24\r
+       #define SHIFT_R (unsigned)16\r
+       #define SHIFT_G (unsigned)8\r
+       #define SHIFT_B (unsigned)0\r
 \r
        #define COLOR_MAX                                       0xFF\r
        #define COLOR_MAX_LOG2                          8\r
        #define COLOR_BRIGHT_WHITE                      0xFFFFFFFF\r
 \r
-       #define VIDEO_SAMPLE_GRANULARITY        2\r
+       #define VIDEO_SAMPLE_GRANULARITY        (unsigned)2\r
 \r
 #else\r
        typedef u16     tVideoSample;\r
+       typedef u8      tStencilSample;\r
 \r
        #define MASK_A  0x8000\r
        #define MASK_R  0x7C00\r
        #define MASK_G  0x03E0\r
        #define MASK_B  0x001F\r
 \r
-       #define SHIFT_A 15\r
-       #define SHIFT_R 10\r
-       #define SHIFT_G 5\r
-       #define SHIFT_B 0\r
+       #define SHIFT_A (unsigned)15\r
+       #define SHIFT_R (unsigned)10\r
+       #define SHIFT_G (unsigned)5\r
+       #define SHIFT_B (unsigned)0\r
 \r
        #define COLOR_MAX                                       0x1F\r
        #define COLOR_MAX_LOG2                          5\r
        #define COLOR_BRIGHT_WHITE                      0xFFFF\r
-       #define VIDEO_SAMPLE_GRANULARITY        1\r
+       #define VIDEO_SAMPLE_GRANULARITY        (unsigned)1\r
 \r
 #endif\r
 \r
@@ -65,14 +67,16 @@ namespace irr
 \r
 \r
 // ----------------------- Generic ----------------------------------\r
+//! align_next - align to next upper 2^n\r
+#define align_next(num,to) (((num) + (to-1)) & (~(to-1)))\r
 \r
-//! a more useful memset for pixel\r
+//! a more useful memset for pixel. dest must be aligned at least to 4 byte\r
 // (standard memset only works with 8-bit values)\r
-inline void memset32(void * dest, const u32 value, u32 bytesize)\r
+inline void memset32(void * dest, const u32 value, size_t bytesize)\r
 {\r
        u32 * d = (u32*) dest;\r
 \r
-       u32 i;\r
+       size_t i;\r
 \r
        // loops unrolled to reduce the number of increments by factor ~8.\r
        i = bytesize >> (2 + 3);\r
@@ -101,13 +105,13 @@ inline void memset32(void * dest, const u32 value, u32 bytesize)
        }\r
 }\r
 \r
-//! a more useful memset for pixel\r
+//! a more useful memset for pixel. dest must be aligned at least to 2 byte\r
 // (standard memset only works with 8-bit values)\r
-inline void memset16(void * dest, const u16 value, u32 bytesize)\r
+inline void memset16(void * dest, const u16 value, size_t bytesize)\r
 {\r
        u16 * d = (u16*) dest;\r
 \r
-       u32 i;\r
+       size_t i;\r
 \r
        // loops unrolled to reduce the number of increments by factor ~8.\r
        i = bytesize >> (1 + 3);\r
@@ -136,35 +140,52 @@ inline void memset16(void * dest, const u16 value, u32 bytesize)
        }\r
 }\r
 \r
-/*\r
-       use biased loop counter\r
-       --> 0 byte copy is forbidden\r
-*/\r
-REALINLINE void memcpy32_small ( void * dest, const void *source, u32 bytesize )\r
-{\r
-       u32 c = bytesize >> 2;\r
 \r
-       do\r
-       {\r
-               ((u32*) dest ) [ c-1 ] = ((u32*) source) [ c-1 ];\r
-       } while ( --c );\r
+// byte-align structures\r
+#include "irrpack.h"\r
 \r
-}\r
+//IEEE Standard for Floating - Point Arithmetic(IEEE 754)\r
+typedef union {\r
+       float f;\r
+       unsigned int u;\r
+       struct { unsigned int frac:23; unsigned exp:8; unsigned int sign:1; } fields;\r
+       struct { unsigned int frac_exp:31; } abs;\r
+} ieee754 PACK_STRUCT;\r
 \r
+// Default alignment\r
+#include "irrunpack.h"\r
 \r
+// 0.5f as integer\r
+#define ieee754_zero_dot_5     0x3f000000\r
+#define ieee754_one                    0x3f800000\r
+#define ieee754_two                    0x40000000\r
 \r
-// integer log2 of a float ieee 754. TODO: non ieee floating point\r
+#if 0\r
+// integer log2 of a float ieee 754. [not used anymore]\r
 static inline s32 s32_log2_f32( f32 f)\r
 {\r
-       u32 x = IR ( f );\r
-       return ((x & 0x7F800000) >> 23) - 127;\r
+       //u32 x = IR ( f ); return ((x & 0x7F800000) >> 23) - 127;\r
+       ieee754 _log2;\r
+       _log2.f = f;\r
+       return _log2.fields.exp ? _log2.fields.exp - 127 : 10000000; /*denormal very high number*/\r
 }\r
+#endif\r
 \r
-static inline s32 s32_log2_s32(u32 x)\r
+// integer log2 of an integer. returning 0 as denormal\r
+static inline s32 s32_log2_s32(u32 in)\r
 {\r
-       return s32_log2_f32( (f32) x);\r
+       s32 ret = 0;\r
+       while (in > 1)\r
+       {\r
+               in >>= 1;\r
+               ret++;\r
+       }\r
+       return ret;\r
+       //return s32_log2_f32( (f32) x);\r
+       //ieee754 _log2;_log2.f = (f32) in; return _log2.fields.exp - 127; \r
 }\r
 \r
+#if 0\r
 static inline s32 s32_abs(s32 x)\r
 {\r
        s32 b = x >> 31;\r
@@ -177,13 +198,14 @@ REALINLINE u32 if_mask_a_else_b ( const u32 mask, const u32 a, const u32 b )
 {\r
        return ( mask & ( a ^ b ) ) ^ b;\r
 }\r
+#endif\r
 \r
 // ------------------ Video---------------------------------------\r
 /*!\r
        Pixel = dest * ( 1 - alpha ) + source * alpha\r
        alpha [0;256]\r
 */\r
-REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha )\r
+REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, const u32 alpha )\r
 {\r
        u32 srcRB = c1 & 0x00FF00FF;\r
        u32 srcXG = c1 & 0x0000FF00;\r
@@ -213,7 +235,7 @@ REALINLINE u32 PixelBlend32 ( const u32 c2, const u32 c1, u32 alpha )
        Pixel = dest * ( 1 - alpha ) + source * alpha\r
        alpha [0;32]\r
 */\r
-inline u16 PixelBlend16 ( const u16 c2, const u32 c1, const u16 alpha )\r
+inline u16 PixelBlend16 ( const u16 c2, const u16 c1, const u16 alpha )\r
 {\r
        const u16 srcRB = c1 & 0x7C1F;\r
        const u16 srcXG = c1 & 0x03E0;\r
@@ -386,97 +408,45 @@ inline u32 PixelBlend32 ( const u32 c2, const u32 c1 )
        return (c1 & 0xFF000000) | rb | xg;\r
 }\r
 \r
-/*!\r
-       Pixel =>\r
-                       color = sourceAlpha > 0 ? source, else dest\r
-                       alpha = max(destAlpha, sourceAlpha)\r
-*/\r
-inline u16 PixelCombine16 ( const u16 c2, const u16 c1 )\r
-{\r
-       if ( video::getAlpha(c1) > 0 )\r
-               return c1;\r
-       else\r
-               return c2;\r
-}\r
-\r
-/*!\r
-       Pixel =>\r
-                       color = dest * ( 1 - SourceAlpha ) + source * SourceAlpha,\r
-                       alpha = destAlpha * ( 1 - SourceAlpha ) + sourceAlpha\r
-\r
-       where "1" means "full scale" (255)\r
-*/\r
-inline u32 PixelCombine32 ( const u32 c2, const u32 c1 )\r
-{\r
-       // alpha test\r
-       u32 alpha = c1 & 0xFF000000;\r
-\r
-       if ( 0 == alpha )\r
-               return c2;\r
-       if ( 0xFF000000 == alpha )\r
-       {\r
-               return c1;\r
-       }\r
-\r
-       alpha >>= 24;\r
-\r
-       // add highbit alpha, if ( alpha > 127 ) alpha += 1;\r
-       // stretches [0;255] to [0;256] to avoid division by 255. use division 256 == shr 8\r
-       alpha += ( alpha >> 7);\r
-\r
-       u32 srcRB = c1 & 0x00FF00FF;\r
-       u32 srcXG = c1 & 0x0000FF00;\r
-\r
-       u32 dstRB = c2 & 0x00FF00FF;\r
-       u32 dstXG = c2 & 0x0000FF00;\r
-\r
-\r
-       u32 rb = srcRB - dstRB;\r
-       u32 xg = srcXG - dstXG;\r
-\r
-       rb *= alpha;\r
-       xg *= alpha;\r
-       rb >>= 8;\r
-       xg >>= 8;\r
-\r
-       rb += dstRB;\r
-       xg += dstXG;\r
-\r
-       rb &= 0x00FF00FF;\r
-       xg &= 0x0000FF00;\r
-\r
-       u32 sa = c1 >> 24;\r
-       u32 da = c2 >> 24;\r
-       u32 blendAlpha_fix8 = (sa*256 + da*(256-alpha))>>8;\r
-       return blendAlpha_fix8 << 24 | rb | xg;\r
-}\r
-\r
 \r
 \r
 // ------------------ Fix Point ----------------------------------\r
 \r
+#if defined(ENV64BIT)\r
 typedef s32 tFixPoint;\r
 typedef u32 tFixPointu;\r
+#else\r
+typedef s32 tFixPoint;\r
+typedef u32 tFixPointu;\r
+#endif\r
 \r
-// Fix Point 12\r
+// Fix Point 12 (overflow on s32)\r
 #if 0\r
        #define FIX_POINT_PRE                   12\r
        #define FIX_POINT_FRACT_MASK    0xFFF\r
-       #define FIX_POINT_SIGNED_MASK   0xFFFFF000\r
        #define FIX_POINT_UNSIGNED_MASK 0x7FFFF000\r
        #define FIX_POINT_ONE                   0x1000\r
        #define FIX_POINT_ZERO_DOT_FIVE 0x0800\r
        #define FIX_POINT_F32_MUL               4096.f\r
 #endif\r
 \r
+// Fix Point 11 (overflow on s32)\r
+#if 0\r
+       #define FIX_POINT_PRE                   11\r
+       #define FIX_POINT_FRACT_MASK    0x7FF\r
+       #define FIX_POINT_UNSIGNED_MASK 0xFFFFF800\r
+       #define FIX_POINT_ONE                   0x800\r
+       #define FIX_POINT_ZERO_DOT_FIVE 0x400\r
+       #define FIX_POINT_F32_MUL               2048.f\r
+#endif\r
+\r
 // Fix Point 10\r
 #if 1\r
        #define FIX_POINT_PRE                   10\r
-       #define FIX_POINT_FRACT_MASK    0x3FF\r
-       #define FIX_POINT_SIGNED_MASK   0xFFFFFC00\r
+       #define FIX_POINT_FRACT_MASK    0x000003FF\r
        #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00\r
-       #define FIX_POINT_ONE                   0x400\r
-       #define FIX_POINT_ZERO_DOT_FIVE 0x200\r
+       #define FIX_POINT_ONE                   0x00000400\r
+       #define FIX_POINT_ZERO_DOT_FIVE 0x00000200\r
        #define FIX_POINT_F32_MUL               1024.f\r
 #endif\r
 \r
@@ -484,7 +454,6 @@ typedef u32 tFixPointu;
 #if 0\r
        #define FIX_POINT_PRE                   9\r
        #define FIX_POINT_FRACT_MASK    0x1FF\r
-       #define FIX_POINT_SIGNED_MASK   0xFFFFFE00\r
        #define FIX_POINT_UNSIGNED_MASK 0x7FFFFE00\r
        #define FIX_POINT_ONE                   0x200\r
        #define FIX_POINT_ZERO_DOT_FIVE 0x100\r
@@ -495,7 +464,6 @@ typedef u32 tFixPointu;
 #if 0\r
        #define FIX_POINT_PRE                   7\r
        #define FIX_POINT_FRACT_MASK    0x7F\r
-       #define FIX_POINT_SIGNED_MASK   0xFFFFFF80\r
        #define FIX_POINT_UNSIGNED_MASK 0x7FFFFF80\r
        #define FIX_POINT_ONE                   0x80\r
        #define FIX_POINT_ZERO_DOT_FIVE 0x40\r
@@ -503,7 +471,20 @@ typedef u32 tFixPointu;
 #endif\r
 \r
 #define        FIXPOINT_COLOR_MAX              ( COLOR_MAX << FIX_POINT_PRE )\r
-#define FIX_POINT_HALF_COLOR ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )\r
+\r
+#if   FIX_POINT_PRE == 10 && COLOR_MAX == 255\r
+       #define FIX_POINT_HALF_COLOR    0x1FE00\r
+       #define FIX_POINT_COLOR_ERROR   4\r
+#elif FIX_POINT_PRE == 12 && COLOR_MAX == 255\r
+       #define FIX_POINT_HALF_COLOR    0x7F800\r
+       #define FIX_POINT_COLOR_ERROR   16\r
+#elif FIX_POINT_PRE == 10 && COLOR_MAX == 31\r
+       #define FIX_POINT_HALF_COLOR    0x3E00\r
+       #define FIX_POINT_COLOR_ERROR   32\r
+#else\r
+       #define FIX_POINT_HALF_COLOR    ( (tFixPoint) ( ((f32) COLOR_MAX / 2.f * FIX_POINT_F32_MUL ) ) )\r
+       #define FIX_POINT_COLOR_ERROR   (1<<(FIX_POINT_PRE-COLOR_MAX_LOG2))\r
+#endif\r
 \r
 \r
 /*\r
@@ -521,12 +502,13 @@ inline tFixPointu u32_to_fixPoint (const u32 x)
 \r
 inline u32 fixPointu_to_u32 (const tFixPointu x)\r
 {\r
-       return x >> FIX_POINT_PRE;\r
+       return (u32)(x >> FIX_POINT_PRE);\r
 }\r
 \r
 \r
 // 1/x * FIX_POINT\r
 #define fix_inverse32(x) (FIX_POINT_F32_MUL / (x))\r
+#define fix_inverse32_color(x) ((FIX_POINT_F32_MUL*COLOR_MAX) / (x))\r
 \r
 \r
 /*\r
@@ -535,38 +517,50 @@ inline u32 fixPointu_to_u32 (const tFixPointu x)
        hints: compileflag /QIfist for msvc7. msvc 8.0 has smth different\r
        others should use their favourite assembler..\r
 */\r
+#if 0\r
 static inline int f_round2(f32 f)\r
 {\r
        f += (3<<22);\r
        return IR(f) - 0x4b400000;\r
 }\r
+#endif\r
 \r
 /*\r
        convert f32 to Fix Point.\r
        multiply is needed anyway, so scale mulby\r
 */\r
+/*\r
 REALINLINE tFixPoint tofix0 (const f32 x, const f32 mulby = FIX_POINT_F32_MUL )\r
 {\r
        return (tFixPoint) (x * mulby);\r
 }\r
+*/\r
 #define tofix(x,y) (tFixPoint)(x * y)\r
 \r
+\r
 /*\r
        Fix Point , Fix Point Multiply\r
 */\r
+/*\r
 REALINLINE tFixPointu imulFixu(const tFixPointu x, const tFixPointu y)\r
 {\r
        return (x * y) >> (tFixPointu) FIX_POINT_PRE;\r
 }\r
+*/\r
+#define imulFixu(x,y) (((x) * (y)) >> (tFixPointu) FIX_POINT_PRE)\r
+\r
 \r
 /*\r
        Fix Point , Fix Point Multiply\r
 */\r
 REALINLINE tFixPoint imulFix(const tFixPoint x, const tFixPoint y)\r
 {\r
-       return ( x * y) >> ( FIX_POINT_PRE );\r
+       return (x * y) >> FIX_POINT_PRE;\r
 }\r
 \r
+#define imulFix_simple(x,y) ((x*y)>>FIX_POINT_PRE)\r
+\r
+#if 0\r
 /*\r
        Fix Point , Fix Point Multiply x * y * 2\r
 */\r
@@ -574,14 +568,18 @@ REALINLINE tFixPoint imulFix2(const tFixPoint x, const tFixPoint y)
 {\r
        return ( x * y) >> ( FIX_POINT_PRE -1 );\r
 }\r
-\r
+#endif\r
 \r
 /*\r
-       Multiply x * y * 1\r
+       Multiply x * y * 1 FIXPOINT_COLOR_MAX\r
 */\r
 REALINLINE tFixPoint imulFix_tex1(const tFixPoint x, const tFixPoint y)\r
 {\r
-       return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 4 );\r
+#ifdef SOFTWARE_DRIVER_2_32BIT\r
+       return (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu) (FIX_POINT_PRE + 4);\r
+#else\r
+       return (x * (y+ FIX_POINT_ONE)) >> (FIX_POINT_PRE + 5);\r
+#endif\r
 }\r
 \r
 /*\r
@@ -593,26 +591,42 @@ REALINLINE tFixPoint imulFix_tex2(const tFixPoint x, const tFixPoint y)
 }\r
 \r
 /*\r
-       Multiply x * y * 4\r
+       Multiply x * y * 4 clamp\r
 */\r
+\r
 REALINLINE tFixPoint imulFix_tex4(const tFixPoint x, const tFixPoint y)\r
 {\r
 #ifdef SOFTWARE_DRIVER_2_32BIT\r
-       return ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 );\r
+       register tFixPoint a = (((tFixPointu)x >> 2)*(((tFixPointu)y + FIX_POINT_ONE) >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 2);\r
 #else\r
-       return ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) );\r
+       register tFixPoint a = (x * (y + FIX_POINT_ONE)) >> (FIX_POINT_PRE + 3);\r
 #endif\r
+       register tFixPoint mask = (a - FIXPOINT_COLOR_MAX) >> 31;\r
+       return (a & mask) | (FIXPOINT_COLOR_MAX & ~mask);\r
 }\r
 \r
+\r
+#if 0\r
+#define imulFix_tex1(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 4))\r
+#define imulFix_tex2(x,y) ((((tFixPointu)x >> 2) * ((tFixPointu)y >> 2)) >> (tFixPointu)(FIX_POINT_PRE + 3))\r
+\r
+#ifdef SOFTWARE_DRIVER_2_32BIT\r
+#define imulFix_tex4(x,y) ( ( (tFixPointu) x >> 2 ) * ( (tFixPointu) y >> 2 ) ) >> (tFixPointu) ( FIX_POINT_PRE + 2 )\r
+#else\r
+#define imulFix_tex4(x,y) ( x * y) >> ( FIX_POINT_PRE + ( VIDEO_SAMPLE_GRANULARITY * 3 ) )\r
+#endif\r
+#endif\r
+\r
 /*!\r
-       clamp FixPoint to maxcolor in FixPoint, min(a,31)\r
+       clamp FixPoint to maxcolor in FixPoint, min(a,COLOR_MAX)\r
 */\r
 REALINLINE tFixPoint clampfix_maxcolor ( const tFixPoint a)\r
 {\r
-       tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;\r
+       register tFixPoint c = (a - FIXPOINT_COLOR_MAX) >> 31;\r
        return (a & c) | ( FIXPOINT_COLOR_MAX & ~c);\r
 }\r
 \r
+\r
 /*!\r
        clamp FixPoint to 0 in FixPoint, max(a,0)\r
 */\r
@@ -630,22 +644,24 @@ REALINLINE tFixPoint saturateFix ( const tFixPoint a)
 // rount fixpoint to int\r
 inline s32 roundFix ( const tFixPoint x )\r
 {\r
-       return ( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE;\r
+       return (s32)(( x + FIX_POINT_ZERO_DOT_FIVE ) >> FIX_POINT_PRE);\r
 }\r
 \r
 \r
 \r
 // x in [0;1[\r
+#if 0\r
 inline s32 f32_to_23Bits(const f32 x)\r
 {\r
        f32 y = x + 1.f;\r
        return IR(y) & 0x7FFFFF;        // last 23 bits\r
 }\r
+#endif\r
 \r
 /*!\r
-       return VideoSample from fixpoint\r
+       fixpoint in [0..Fixpoint_color] to VideoSample xrgb\r
 */\r
-REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
+REALINLINE tVideoSample fix_to_sample ( const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
 {\r
        return  ( FIXPOINT_COLOR_MAX & FIXPOINT_COLOR_MAX) << ( SHIFT_A - FIX_POINT_PRE ) |\r
                        ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |\r
@@ -655,9 +671,11 @@ REALINLINE tVideoSample fix_to_color ( const tFixPoint r, const tFixPoint g, con
 \r
 \r
 /*!\r
-       return VideoSample from fixpoint\r
+       fixpoint to VideoSample argb\r
+       a in [0;1]\r
+       rgb in [0;255] colormax\r
 */\r
-REALINLINE tVideoSample fix4_to_color ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
+REALINLINE tVideoSample fix4_to_sample ( const tFixPoint a, const tFixPoint r, const tFixPoint g, const tFixPoint b )\r
 {\r
        return  ( a & (FIX_POINT_FRACT_MASK - 1 )) << ( SHIFT_A - 1 ) |\r
                        ( r & FIXPOINT_COLOR_MAX) << ( SHIFT_R - FIX_POINT_PRE ) |\r
@@ -666,7 +684,7 @@ REALINLINE tVideoSample fix4_to_color ( const tFixPoint a, const tFixPoint r, co
 }\r
 \r
 /*!\r
-       return fixpoint from VideoSample granularity COLOR_MAX\r
+       return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
 */\r
 inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
 {\r
@@ -676,7 +694,7 @@ inline void color_to_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVide
 }\r
 \r
 /*!\r
-       return fixpoint from VideoSample granularity COLOR_MAX\r
+       return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
 */\r
 inline void color_to_fix ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVideoSample t00 )\r
 {\r
@@ -694,6 +712,11 @@ inline void color_to_fix1 ( tFixPoint &r, tFixPoint &g, tFixPoint &b, const tVid
        (tFixPointu&) r =       (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
        (tFixPointu&) g =       (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
        (tFixPointu&) b =       (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );\r
+\r
+       //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
+       r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
 }\r
 \r
 /*!\r
@@ -705,11 +728,47 @@ inline void color_to_fix1 ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint
        (tFixPointu&) r =       (t00 & MASK_R) >> ( SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
        (tFixPointu&) g =       (t00 & MASK_G) >> ( SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE );\r
        (tFixPointu&) b =       (t00 & MASK_B) << ( FIX_POINT_PRE - COLOR_MAX_LOG2 );\r
+\r
+       //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
+       a += (a & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       r += (r & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       g += (g & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       b += (b & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+\r
+}\r
+\r
+/*!\r
+       return fixpoint from VideoSample granularity FIXPOINT_COLOR_MAX\r
+*/\r
+inline void color_to_fix(tFixPoint c[4], const tVideoSample t00)\r
+{\r
+       c[0] = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
+       c[1] = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+       c[2] = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+       c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
+}\r
+\r
+/*!\r
+       return fixpoint from VideoSample granularity 0..FIX_POINT_ONE\r
+*/\r
+inline void color_to_fix1(tFixPoint c[4], const tVideoSample t00)\r
+{\r
+       c[0] = (t00 & MASK_A) >> (SHIFT_A + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
+       c[1] = (t00 & MASK_R) >> (SHIFT_R + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
+       c[2] = (t00 & MASK_G) >> (SHIFT_G + COLOR_MAX_LOG2 - FIX_POINT_PRE);\r
+       c[3] = (t00 & MASK_B) << (FIX_POINT_PRE - COLOR_MAX_LOG2);\r
+\r
+       //0..255 -> 0..256 | c += c >= 0.5 ? 1 : 0\r
+       c[0] += (c[0] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       c[1] += (c[1] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       c[2] += (c[2] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+       c[3] += (c[3] & FIX_POINT_ZERO_DOT_FIVE) ? FIX_POINT_COLOR_ERROR : 0;\r
+\r
 }\r
 \r
 \r
 \r
-// ----- FP24 ---- floating point z-buffer\r
+//! ----- FP24 1.23 fix point z-buffer\r
 \r
 #if 1\r
 typedef f32 fp24;\r
@@ -751,22 +810,23 @@ struct fp24
 \r
 struct sInternalTexture\r
 {\r
-       u32 textureXMask;\r
-       u32 textureYMask;\r
+       //power-of-two\r
+       void* data; //tVideoSample* Texture->lock(miplevel)\r
+       size_t textureXMask;\r
+       size_t textureYMask;\r
 \r
-       u32 pitchlog2;\r
-       void *data;\r
+       size_t pitchlog2;\r
 \r
        video::CSoftwareTexture2 *Texture;\r
-       s32 lodLevel;\r
+       s32 lodFactor; // magnify/minify\r
 };\r
 \r
 \r
 \r
 // get video sample plain\r
-inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty )\r
+static inline tVideoSample getTexel_plain ( const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty )\r
 {\r
-       u32 ofs;\r
+       register size_t ofs;\r
 \r
        ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
        ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
@@ -777,16 +837,16 @@ inline tVideoSample getTexel_plain ( const sInternalTexture * t, const tFixPoint
 \r
 // get video sample to fix\r
 inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
+                                               const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty\r
                                                                )\r
 {\r
-       u32 ofs;\r
+       register size_t ofs;\r
 \r
-       ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+       ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
+       ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
 \r
        // texel\r
-       tVideoSample t00;\r
+       register tVideoSample t00;\r
        t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
 \r
        r = (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
@@ -795,165 +855,247 @@ inline void getTexel_fix ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
 \r
 }\r
 \r
-// get video sample to fixpoint\r
-REALINLINE void getTexel_fix ( tFixPoint &a,\r
-                       const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)\r
+// get video sample to fixpoint colormax\r
+inline void getTexel_fix(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+       const sInternalTexture* t, const tFixPointu tx, const tFixPointu ty\r
+)\r
 {\r
-       u32 ofs;\r
+       register size_t ofs;\r
 \r
-       ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+       ofs = (((ty+ FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+       ofs |= ((tx+ FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
 \r
        // texel\r
-       tVideoSample t00;\r
-       t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+       register tVideoSample t00;\r
+       t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
 \r
-       a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);\r
-}\r
+       a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
+       r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+       g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+       b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
 \r
+}\r
 \r
-inline void getSample_texture_dither ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty,\r
-                                                                               const u32 x, const u32 y\r
-                                                               )\r
+#if 0\r
+// get video sample to fixpoint\r
+static REALINLINE void getTexel_fix ( tFixPoint &a,\r
+                       const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty)\r
 {\r
-       static const tFixPointu dithermask[] =\r
-       {\r
-               0x00,0x80,0x20,0xa0,\r
-               0xc0,0x40,0xe0,0x60,\r
-               0x30,0xb0,0x10,0x90,\r
-               0xf0,0x70,0xd0,0x50\r
-       };\r
-\r
-       const u32 index = (y & 3 ) << 2 | (x & 3);\r
-\r
-       const tFixPointu _ntx = (tx + dithermask [ index ] ) & t->textureXMask;\r
-       const tFixPointu _nty = (ty + dithermask [ index ] ) & t->textureYMask;\r
+       size_t ofs;\r
 \r
-       u32 ofs;\r
-       ofs = ( ( _nty ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       ofs |= ( _ntx ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+       ofs = ( ((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
+       ofs |= ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
 \r
        // texel\r
-       const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
-\r
-       (tFixPointu &) r =      (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
-       (tFixPointu &) g =      (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
-       (tFixPointu &) b =      (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
+       tVideoSample t00;\r
+       t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
 \r
+       a = (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);\r
 }\r
+#endif\r
 \r
 /*\r
        load a sample from internal texture at position tx,ty to fixpoint\r
 */\r
-#ifndef SOFTWARE_DRIVER_2_BILINEAR\r
-\r
-// get Sample linear == getSample_fixpoint\r
+#if defined(SOFTWARE_DRIVER_2_BILINEAR)\r
 \r
-inline void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
-                                                               )\r
+#if 0\r
+// texture2D in fixpoint color range bilinear\r
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+       const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
+)\r
 {\r
-       u32 ofs;\r
-\r
-       ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
-\r
-       // texel\r
-       const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+#if 0\r
+       if (t->lodFactor > 0)\r
+       {\r
+               register size_t ofs;\r
 \r
-       (tFixPointu &) r =      (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
-       (tFixPointu &) g =      (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
-       (tFixPointu &) b =      (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
-}\r
+               ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+               ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
 \r
-inline void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
-                                                               )\r
-{\r
-       u32 ofs;\r
+               // texel\r
+               tVideoSample t00;\r
+               t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
 \r
-       ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+               r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+               g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+               b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
+               return;\r
+       }\r
+#endif\r
 \r
-       // texel\r
-       const tVideoSample t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+       tFixPointu r00, g00, b00;\r
+       tFixPointu r01, g01, b01;\r
+       tFixPointu r10, g10, b10;\r
+       tFixPointu r11, g11, b11;\r
+\r
+       size_t o0, o1, o2, o3;\r
+       register tVideoSample t00;\r
+\r
+       //wraps positive (ignoring negative)\r
+       o0 = (((ty)& t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+       o1 = (((ty + FIX_POINT_ONE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+       o2 = ((tx)& t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+       o3 = ((tx + FIX_POINT_ONE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+       t00 = *((tVideoSample*)((u8*)t->data + (o0 + o2)));\r
+       r00 = (t00 & MASK_R) >> SHIFT_R;\r
+       g00 = (t00 & MASK_G) >> SHIFT_G;\r
+       b00 = (t00 & MASK_B);\r
+\r
+       t00 = *((tVideoSample*)((u8*)t->data + (o0 + o3)));\r
+       r10 = (t00 & MASK_R) >> SHIFT_R;\r
+       g10 = (t00 & MASK_G) >> SHIFT_G;\r
+       b10 = (t00 & MASK_B);\r
+\r
+       t00 = *((tVideoSample*)((u8*)t->data + (o1 + o2)));\r
+       r01 = (t00 & MASK_R) >> SHIFT_R;\r
+       g01 = (t00 & MASK_G) >> SHIFT_G;\r
+       b01 = (t00 & MASK_B);\r
+\r
+       t00 = *((tVideoSample*)((u8*)t->data + (o1 + o3)));\r
+       r11 = (t00 & MASK_R) >> SHIFT_R;\r
+       g11 = (t00 & MASK_G) >> SHIFT_G;\r
+       b11 = (t00 & MASK_B);\r
+\r
+\r
+       register tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;\r
+       register tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;\r
+\r
+       //w00 w01 w10 w11\r
+       tFixPointu w[4];\r
+       w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);\r
+       w[1] = imulFixu(FIX_POINT_ONE - fracx, fracy);\r
+       w[2] = imulFixu(fracx, FIX_POINT_ONE - fracy);\r
+       w[3] = imulFixu(fracx, fracy);\r
+\r
+       r = (r00 * w[0]) +\r
+               (r01 * w[1]) +\r
+               (r10 * w[2]) +\r
+               (r11 * w[3]);\r
+\r
+       g = (g00 * w[0]) +\r
+               (g01 * w[1]) +\r
+               (g10 * w[2]) +\r
+               (g11 * w[3]);\r
+\r
+       b = (b00 * w[0]) +\r
+               (b01 * w[1]) +\r
+               (b10 * w[2]) +\r
+               (b11 * w[3]);\r
 \r
-       (tFixPointu &)a =       (t00 & MASK_A) >> ( SHIFT_A - FIX_POINT_PRE);\r
-       (tFixPointu &)r =       (t00 & MASK_R) >> ( SHIFT_R - FIX_POINT_PRE);\r
-       (tFixPointu &)g =       (t00 & MASK_G) << ( FIX_POINT_PRE - SHIFT_G );\r
-       (tFixPointu &)b =       (t00 & MASK_B) << ( FIX_POINT_PRE - SHIFT_B );\r
 }\r
 \r
-\r
 #else\r
 \r
-\r
-// get sample linear\r
-REALINLINE void getSample_linear ( tFixPointu &r, tFixPointu &g, tFixPointu &b,\r
-                                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
-                                                               )\r
+// texture2D in fixpoint color range bilinear\r
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+       const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty\r
+)\r
 {\r
-       u32 ofs;\r
+#if 0\r
+       if (tex->lodFactor > 1)\r
+       {\r
+               //nearest neighbor\r
+               register size_t ofs;\r
+               ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+               ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+               register tVideoSample t00;\r
+               t00 = *((tVideoSample*)((u8*)tex->data + ofs));\r
+\r
+               r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+               g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+               b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
+               return;\r
+       }\r
+#endif\r
+       //w00 w01 w10 w11\r
+       tFixPointu w[4];\r
+       {\r
+               register tFixPointu fracx = tx & FIX_POINT_FRACT_MASK;\r
+               register tFixPointu fracy = ty & FIX_POINT_FRACT_MASK;\r
+               w[0] = imulFixu(FIX_POINT_ONE - fracx, FIX_POINT_ONE - fracy);\r
+               w[1] = imulFixu(fracx, FIX_POINT_ONE - fracy);\r
+               w[2] = imulFixu(FIX_POINT_ONE - fracx, fracy);\r
+               w[3] = imulFixu(fracx, fracy);\r
+       }\r
 \r
-       ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+       //wraps positive (ignoring negative)\r
+       tVideoSample t[4];\r
+       {\r
+               register size_t o0, o1, o2, o3;\r
+               o0 = (((ty) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+               o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+               o2 = ((tx)& tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+               o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (unsigned)(FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+               t[0] = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));\r
+               t[1] = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));\r
+               t[2] = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));\r
+               t[3] = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));\r
+       }\r
 \r
-       // texel\r
-       tVideoSample t00;\r
-       t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+       r = (((t[0] & MASK_R) >> SHIFT_R) * w[0]) +\r
+               (((t[1] & MASK_R) >> SHIFT_R) * w[1]) +\r
+               (((t[2] & MASK_R) >> SHIFT_R) * w[2]) +\r
+               (((t[3] & MASK_R) >> SHIFT_R) * w[3]);\r
 \r
-       r =     (t00 & MASK_R) >> SHIFT_R;\r
-       g =     (t00 & MASK_G) >> SHIFT_G;\r
-       b =     (t00 & MASK_B);\r
+       g = (((t[0] & MASK_G) >> SHIFT_G) * w[0]) +\r
+               (((t[1] & MASK_G) >> SHIFT_G) * w[1]) +\r
+               (((t[2] & MASK_G) >> SHIFT_G) * w[2]) +\r
+               (((t[3] & MASK_G) >> SHIFT_G) * w[3]);\r
+\r
+       b = ((t[0] & MASK_B) * w[0]) +\r
+               ((t[1] & MASK_B) * w[1]) +\r
+               ((t[2] & MASK_B) * w[2]) +\r
+               ((t[3] & MASK_B) * w[3]);\r
 }\r
 \r
+#endif\r
+\r
 // get Sample bilinear\r
-REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
-                                                               )\r
+static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+       const sInternalTexture* burning_restrict tex, const tFixPointu tx, const tFixPointu ty\r
+)\r
 {\r
 \r
-       tFixPointu r00,g00,b00;\r
-       tFixPointu r01,g01,b01;\r
-       tFixPointu r10,g10,b10;\r
-       tFixPointu r11,g11,b11;\r
-\r
-#if 0\r
-       getSample_linear ( r00, g00, b00, t, tx,ty );\r
-       getSample_linear ( r10, g10, b10, t, tx + FIX_POINT_ONE,ty );\r
-       getSample_linear ( r01, g01, b01, t, tx,ty + FIX_POINT_ONE );\r
-       getSample_linear ( r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );\r
-#else\r
-       u32 o0, o1,o2,o3;\r
-       tVideoSample t00;\r
-\r
-       o0 = ( ( (ty) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       o1 = ( ( (ty+FIX_POINT_ONE) & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       o2 =   ( (tx) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
-       o3 =   ( (tx+FIX_POINT_ONE) & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
-\r
-       t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o2 ) ));\r
-       r00 =   (t00 & MASK_R) >> SHIFT_R;\r
-       g00 =   (t00 & MASK_G) >> SHIFT_G;\r
-       b00 =   (t00 & MASK_B);\r
-\r
-       t00 = *((tVideoSample*)( (u8*) t->data + (o0 | o3 ) ));\r
-       r10 =   (t00 & MASK_R) >> SHIFT_R;\r
-       g10 =   (t00 & MASK_G) >> SHIFT_G;\r
-       b10 =   (t00 & MASK_B);\r
-\r
-       t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o2 ) ));\r
-       r01 =   (t00 & MASK_R) >> SHIFT_R;\r
-       g01 =   (t00 & MASK_G) >> SHIFT_G;\r
-       b01 =   (t00 & MASK_B);\r
-\r
-       t00 = *((tVideoSample*)( (u8*) t->data + (o1 | o3 ) ));\r
-       r11 =   (t00 & MASK_R) >> SHIFT_R;\r
-       g11 =   (t00 & MASK_G) >> SHIFT_G;\r
-       b11 =   (t00 & MASK_B);\r
-\r
-#endif\r
+       tFixPointu a00, r00, g00, b00;\r
+       tFixPointu a01, r01, g01, b01;\r
+       tFixPointu a10, r10, g10, b10;\r
+       tFixPointu a11, r11, g11, b11;\r
+\r
+       size_t o0, o1, o2, o3;\r
+       register tVideoSample t00;\r
+\r
+       o0 = (((ty)& tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+       o1 = (((ty + FIX_POINT_ONE) & tex->textureYMask) >> FIX_POINT_PRE) << tex->pitchlog2;\r
+       o2 = ((tx)& tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+       o3 = ((tx + FIX_POINT_ONE) & tex->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
+\r
+       t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o2)));\r
+       a00 = (t00 & MASK_A) >> SHIFT_A;\r
+       r00 = (t00 & MASK_R) >> SHIFT_R;\r
+       g00 = (t00 & MASK_G) >> SHIFT_G;\r
+       b00 = (t00 & MASK_B);\r
+\r
+       t00 = *((tVideoSample*)((u8*)tex->data + (o0 + o3)));\r
+       a10 = (t00 & MASK_A) >> SHIFT_A;\r
+       r10 = (t00 & MASK_R) >> SHIFT_R;\r
+       g10 = (t00 & MASK_G) >> SHIFT_G;\r
+       b10 = (t00 & MASK_B);\r
+\r
+       t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o2)));\r
+       a01 = (t00 & MASK_A) >> SHIFT_A;\r
+       r01 = (t00 & MASK_R) >> SHIFT_R;\r
+       g01 = (t00 & MASK_G) >> SHIFT_G;\r
+       b01 = (t00 & MASK_B);\r
+\r
+       t00 = *((tVideoSample*)((u8*)tex->data + (o1 + o3)));\r
+       a11 = (t00 & MASK_A) >> SHIFT_A;\r
+       r11 = (t00 & MASK_R) >> SHIFT_R;\r
+       g11 = (t00 & MASK_G) >> SHIFT_G;\r
+       b11 = (t00 & MASK_B);\r
 \r
        const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;\r
        const tFixPointu txFractInv = FIX_POINT_ONE - txFract;\r
@@ -961,102 +1103,78 @@ REALINLINE void getSample_texture ( tFixPoint &r, tFixPoint &g, tFixPoint &b,
        const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;\r
        const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;\r
 \r
-       const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );\r
-       const tFixPointu w10 = imulFixu ( txFract       , tyFractInv );\r
-       const tFixPointu w01 = imulFixu ( txFractInv, tyFract );\r
-       const tFixPointu w11 = imulFixu ( txFract       , tyFract );\r
+       const tFixPointu w00 = imulFixu(txFractInv, tyFractInv);\r
+       const tFixPointu w10 = imulFixu(txFract, tyFractInv);\r
+       const tFixPointu w01 = imulFixu(txFractInv, tyFract);\r
+       const tFixPointu w11 = imulFixu(txFract, tyFract);\r
+\r
+       a = (a00 * w00) +\r
+               (a01 * w01) +\r
+               (a10 * w10) +\r
+               (a11 * w11);\r
 \r
-       r =             (r00 * w00 ) +\r
-                       (r01 * w01 ) +\r
-                       (r10 * w10 ) +\r
-                       (r11 * w11 );\r
+       fix_alpha_color_max(a);\r
 \r
-       g =             (g00 * w00 ) +\r
-                       (g01 * w01 ) +\r
-                       (g10 * w10 ) +\r
-                       (g11 * w11 );\r
+       r = (r00 * w00) +\r
+               (r01 * w01) +\r
+               (r10 * w10) +\r
+               (r11 * w11);\r
 \r
-       b =             (b00 * w00 ) +\r
-                       (b01 * w01 ) +\r
-                       (b10 * w10 ) +\r
-                       (b11 * w11 );\r
+       g = (g00 * w00) +\r
+               (g01 * w01) +\r
+               (g10 * w10) +\r
+               (g11 * w11);\r
+\r
+       b = (b00 * w00) +\r
+               (b01 * w01) +\r
+               (b10 * w10) +\r
+               (b11 * w11);\r
 \r
 }\r
 \r
+#else // SOFTWARE_DRIVER_2_BILINEAR\r
 \r
-// get sample linear\r
-REALINLINE void getSample_linear ( tFixPointu &a, tFixPointu &r, tFixPointu &g, tFixPointu &b,\r
-                                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
-                                                               )\r
-{\r
-       u32 ofs;\r
+// get Sample linear == getSample_fixpoint\r
 \r
-       ofs = ( ( ty & t->textureYMask ) >> FIX_POINT_PRE ) << t->pitchlog2;\r
-       ofs |= ( tx & t->textureXMask ) >> ( FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY );\r
+static REALINLINE void getSample_texture(tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+       const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
+)\r
+{\r
+       register size_t ofs;\r
+       ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+       ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
 \r
        // texel\r
-       tVideoSample t00;\r
-       t00 = *((tVideoSample*)( (u8*) t->data + ofs ));\r
+       const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
 \r
-       a =     (t00 & MASK_A) >> SHIFT_A;\r
-       r =     (t00 & MASK_R) >> SHIFT_R;\r
-       g =     (t00 & MASK_G) >> SHIFT_G;\r
-       b =     (t00 & MASK_B);\r
+       (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+       (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+       (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
 }\r
 \r
-// get Sample bilinear\r
-REALINLINE void getSample_texture ( tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
-                                                               const sInternalTexture * t, const tFixPointu tx, const tFixPointu ty\r
-                                                               )\r
+static REALINLINE void getSample_texture(tFixPoint &a, tFixPoint &r, tFixPoint &g, tFixPoint &b,\r
+       const sInternalTexture* burning_restrict t, const tFixPointu tx, const tFixPointu ty\r
+)\r
 {\r
+       register size_t ofs;\r
+       ofs = (((ty + FIX_POINT_ZERO_DOT_FIVE) & t->textureYMask) >> FIX_POINT_PRE) << t->pitchlog2;\r
+       ofs += ((tx + FIX_POINT_ZERO_DOT_FIVE) & t->textureXMask) >> (FIX_POINT_PRE - VIDEO_SAMPLE_GRANULARITY);\r
 \r
-       tFixPointu a00, r00,g00,b00;\r
-       tFixPointu a01, r01,g01,b01;\r
-       tFixPointu a10, r10,g10,b10;\r
-       tFixPointu a11, r11,g11,b11;\r
-\r
-       getSample_linear ( a00, r00, g00, b00, t, tx,ty );\r
-       getSample_linear ( a10, r10, g10, b10, t, tx + FIX_POINT_ONE,ty );\r
-       getSample_linear ( a01, r01, g01, b01, t, tx,ty + FIX_POINT_ONE );\r
-       getSample_linear ( a11, r11, g11, b11, t, tx + FIX_POINT_ONE,ty + FIX_POINT_ONE );\r
-\r
-       const tFixPointu txFract = tx & FIX_POINT_FRACT_MASK;\r
-       const tFixPointu txFractInv = FIX_POINT_ONE - txFract;\r
-\r
-       const tFixPointu tyFract = ty & FIX_POINT_FRACT_MASK;\r
-       const tFixPointu tyFractInv = FIX_POINT_ONE - tyFract;\r
-\r
-       const tFixPointu w00 = imulFixu ( txFractInv, tyFractInv );\r
-       const tFixPointu w10 = imulFixu ( txFract       , tyFractInv );\r
-       const tFixPointu w01 = imulFixu ( txFractInv, tyFract );\r
-       const tFixPointu w11 = imulFixu ( txFract       , tyFract );\r
-\r
-       a =             (a00 * w00 ) +\r
-                       (a01 * w01 ) +\r
-                       (a10 * w10 ) +\r
-                       (a11 * w11 );\r
-\r
-       r =             (r00 * w00 ) +\r
-                       (r01 * w01 ) +\r
-                       (r10 * w10 ) +\r
-                       (r11 * w11 );\r
-\r
-       g =             (g00 * w00 ) +\r
-                       (g01 * w01 ) +\r
-                       (g10 * w10 ) +\r
-                       (g11 * w11 );\r
-\r
-       b =             (b00 * w00 ) +\r
-                       (b01 * w01 ) +\r
-                       (b10 * w10 ) +\r
-                       (b11 * w11 );\r
+       // texel\r
+       const tVideoSample t00 = *((tVideoSample*)((u8*)t->data + ofs));\r
 \r
+       (tFixPointu &)a = (t00 & MASK_A) >> (SHIFT_A - FIX_POINT_PRE);\r
+       fix_alpha_color_max(a);\r
+       (tFixPointu &)r = (t00 & MASK_R) >> (SHIFT_R - FIX_POINT_PRE);\r
+       (tFixPointu &)g = (t00 & MASK_G) << (FIX_POINT_PRE - SHIFT_G);\r
+       (tFixPointu &)b = (t00 & MASK_B) << (FIX_POINT_PRE - SHIFT_B);\r
 }\r
 \r
 \r
-#endif\r
+#endif // SOFTWARE_DRIVER_2_BILINEAR\r
+\r
 \r
-// some 2D Defines\r
+// 2D Region closed [x0;x1]\r
 struct AbsRectangle\r
 {\r
        s32 x0;\r
@@ -1075,6 +1193,7 @@ inline bool intersect ( AbsRectangle &dest, const AbsRectangle& a, const AbsRect
        return dest.x0 < dest.x1 && dest.y0 < dest.y1;\r
 }\r
 \r
+#if 0\r
 // some 1D defines\r
 struct sIntervall\r
 {\r
@@ -1088,6 +1207,33 @@ inline s32 intervall_intersect_test( const sIntervall& a, const sIntervall& b)
        return core::s32_min( a.end, b.end ) - core::s32_max( a.start, b.start );\r
 }\r
 \r
+#endif\r
+\r
+// strings\r
+static inline void tiny_strncpy(char* to, const char* from, const size_t count)\r
+{\r
+       for (size_t r = 0; r < count && (*to = *from) != '\0'; ++from, ++to, ++r);\r
+       *to = '\0';\r
+}\r
+\r
+#define tiny_strcpy(a, b) tiny_strncpy(a,b,sizeof(a)-1)\r
+\r
+\r
+// tiny_isequal = !strncmp(a,b,sizeof(a)-1)\r
+static inline int tiny_isequal(const char *s1, const char *s2, size_t n)\r
+{\r
+       do {\r
+               if (*s1 != *s2++) return 0;\r
+               if (*s1++ == 0)\r
+                       break;\r
+       } while (--n != 0);\r
+       return 1;\r
+}\r
+\r
+#define tiny_istoken(a, b) tiny_isequal(a,b,sizeof(a)-1) != 0\r
+//! Size of a static C-style array.\r
+#define array_size(_arr)  ((sizeof(_arr)/sizeof(*_arr)))\r
+\r
 \r
 } // end namespace irr\r
 \r
diff --git a/source/Irrlicht/burning_shader_color.cpp b/source/Irrlicht/burning_shader_color.cpp
new file mode 100644 (file)
index 0000000..3af52ab
--- /dev/null
@@ -0,0 +1,95 @@
+// 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 "IBurningShader.h"\r
+\r
+#ifdef _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
+namespace irr\r
+{\r
+\r
+namespace video\r
+{\r
+\r
+#define burning_shader_class burning_shader_color\r
+#define burning_shader_frag "burning_shader_color_fraq.h"\r
+#include "burning_shader_compile_fragment_default.h"\r
+\r
+\r
+/*!\r
+*/\r
+void burning_shader_class::OnSetMaterial(const SBurningShaderMaterial& material)\r
+{\r
+       switch (material.org.MaterialType)\r
+       {\r
+       case EMT_TRANSPARENT_ADD_COLOR:\r
+       case EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR:\r
+       case EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR:\r
+               //glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);\r
+\r
+       case EMT_TRANSPARENT_ALPHA_CHANNEL:\r
+               //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
+\r
+       case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:\r
+               //? glBlendFunc(GL_ONE,GL_ZERO) or glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);\r
+\r
+       case EMT_TRANSPARENT_REFLECTION_2_LAYER:\r
+\r
+       case EMT_TRANSPARENT_VERTEX_ALPHA:\r
+       case EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA:\r
+       case EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA:\r
+               RenderPass_ShaderIsTransparent = 1;\r
+               AlphaRef = tofix(material.org.MaterialTypeParam, FIXPOINT_COLOR_MAX);\r
+               break;\r
+       default:\r
+               RenderPass_ShaderIsTransparent = 0;\r
+               AlphaRef = 0;\r
+               break;\r
+       }\r
+\r
+       if (0 == RenderPass_ShaderIsTransparent)\r
+       {\r
+               if (material.org.ZBuffer == ECFN_LESSEQUAL)\r
+               {\r
+                       if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;\r
+                       else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_one_zero;\r
+               }\r
+               else /*if (material.org.ZBuffer == ECFN_DISABLED)*/\r
+               {\r
+                       //check triangle on w = 1.f instead..\r
+#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
+                       if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_one_zero;\r
+                       else\r
+#endif\r
+                               fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_one_zero;\r
+               }\r
+       }\r
+       else\r
+       {\r
+               if (material.org.ZBuffer == ECFN_LESSEQUAL)\r
+               {\r
+                       if (material.depth_write) fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha;\r
+                       else fragmentShader = &burning_shader_class::fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha;\r
+               }\r
+               else /*if (material.org.ZBuffer == ECFN_DISABLED)*/\r
+               {\r
+                       //check triangle on w = 1.f instead..\r
+#ifdef SOFTWARE_DRIVER_2_BILINEAR\r
+                       if (material.org.TextureLayer[0].BilinearFilter) fragmentShader = &burning_shader_class::fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha;\r
+                       else\r
+#endif\r
+                               fragmentShader = &burning_shader_class::fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha;\r
+               }\r
+       }\r
+\r
+}\r
+\r
+\r
+\r
+} // end namespace video\r
+} // end namespace irr\r
+\r
+#endif // _IRR_COMPILE_WITH_BURNINGSVIDEO_\r
+\r
diff --git a/source/Irrlicht/burning_shader_color_fraq.h b/source/Irrlicht/burning_shader_color_fraq.h
new file mode 100644 (file)
index 0000000..f9efae2
--- /dev/null
@@ -0,0 +1,24 @@
+// pixelshader\r
+#ifdef IPOL_C0\r
+\r
+#ifdef IPOL_A0\r
+vec4_to_fix(a0, r0, g0, b0, line.c[0][0], inversew);\r
+if (a0 > AlphaRef)\r
+{\r
+       color_to_fix(r1, g1, b1, dst[i]);\r
+\r
+       fix_color_norm(a0);\r
+       r0 = r1 + imulFix(a0, r0 - r1);\r
+       g0 = g1 + imulFix(a0, g0 - g1);\r
+       b0 = b1 + imulFix(a0, b0 - b1);\r
+       dst[i] = fix_to_sample(r0, g0, b0);\r
+}\r
+#else\r
+vec4_to_fix(r0, g0, b0, line.c[0][0], inversew);\r
+dst[i] = fix_to_sample(r0, g0, b0);\r
+#endif\r
+\r
+#else\r
+dst[i] = PrimitiveColor;\r
+#endif\r
+\r
diff --git a/source/Irrlicht/burning_shader_compile_fragment_default.h b/source/Irrlicht/burning_shader_compile_fragment_default.h
new file mode 100644 (file)
index 0000000..f28ab70
--- /dev/null
@@ -0,0 +1,164 @@
+\r
+\r
+class burning_shader_class : public IBurningShader\r
+{\r
+public:\r
+\r
+       //! constructor\r
+       burning_shader_class(CBurningVideoDriver* driver);\r
+\r
+       //! draws an indexed triangle list\r
+       virtual void drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c) _IRR_OVERRIDE_;\r
+       virtual bool canWireFrame() { return true; }\r
+\r
+       virtual void OnSetMaterial(const SBurningShaderMaterial& material) _IRR_OVERRIDE_;\r
+\r
+private:\r
+\r
+       // fragment shader\r
+       typedef void (burning_shader_class::*tFragmentShader) ();\r
+       void fragment_depth_less_equal_depth_write_blend_one_zero();\r
+       void fragment_depth_less_equal_no_depth_write_blend_one_zero();\r
+       void fragment_nodepth_perspective_blend_one_zero();\r
+       void fragment_nodepth_noperspective_blend_one_zero(); // 2D Gradient\r
+\r
+       void fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha();\r
+       void fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha();\r
+       void fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha();\r
+       void fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha();\r
+\r
+\r
+       tFragmentShader fragmentShader;\r
+\r
+};\r
+\r
+\r
+//! constructor\r
+burning_shader_class::burning_shader_color(CBurningVideoDriver* driver)\r
+       : IBurningShader(driver)\r
+{\r
+#ifdef _DEBUG\r
+       setDebugName(burning_stringify(burning_shader_class) );\r
+#endif\r
+\r
+       fragmentShader = &burning_shader_class::fragment_depth_less_equal_depth_write_blend_one_zero;\r
+\r
+}\r
+\r
+\r
+IBurningShader* burning_create(burning_shader_class)(CBurningVideoDriver* driver)\r
+{\r
+       return new burning_shader_class(driver);\r
+}\r
+\r
+\r
+\r
+// compile flag for this triangle\r
+#include "burning_shader_compile_start.h"\r
+#define SUBTEXEL\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#include "burning_shader_compile_triangle.h"\r
+\r
+// compile flag for this scanline fragment\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_noperspective_blend_one_zero\r
+#define SUBTEXEL\r
+#define IPOL_C0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_perspective_blend_one_zero\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_one_zero\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_one_zero\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define WRITE_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+\r
+// compile flag for this scanline fragment\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_noperspective_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_nodepth_perspective_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_no_depth_write_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
+\r
+#include "burning_shader_compile_start.h"\r
+#define burning_shader_fragment fragment_depth_less_equal_depth_write_blend_src_alpha_one_minus_src_alpha\r
+#define SUBTEXEL\r
+#define INVERSE_W\r
+#define IPOL_W\r
+#define IPOL_C0\r
+#define IPOL_A0\r
+#define USE_ZBUFFER\r
+#define CMP_W\r
+#define WRITE_W\r
+#define INVERSE_W_RANGE FIX_POINT_F32_MUL*COLOR_MAX\r
+#include "burning_shader_compile_fragment_start.h"\r
+#include burning_shader_frag\r
+#include "burning_shader_compile_fragment_end.h"\r
diff --git a/source/Irrlicht/burning_shader_compile_fragment_end.h b/source/Irrlicht/burning_shader_compile_fragment_end.h
new file mode 100644 (file)
index 0000000..8e4719e
--- /dev/null
@@ -0,0 +1,20 @@
+               }\r
+\r
+#ifdef IPOL_Z\r
+               line.z[0] += slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+               line.w[0] += slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+               line.c[0][0] += slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+               line.t[0][0] += slopeT[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+               line.t[1][0] += slopeT[1];\r
+#endif\r
+       }\r
+\r
+}\r
diff --git a/source/Irrlicht/burning_shader_compile_fragment_start.h b/source/Irrlicht/burning_shader_compile_fragment_start.h
new file mode 100644 (file)
index 0000000..64a8463
--- /dev/null
@@ -0,0 +1,119 @@
+#include "burning_shader_compile_verify.h"\r
+\r
+/*!\r
+*/\r
+void burning_shader_class::burning_shader_fragment()\r
+{\r
+       tVideoSample *dst;\r
+\r
+#ifdef USE_ZBUFFER\r
+       fp24 *z;\r
+#endif\r
+\r
+       s32 xStart;\r
+       s32 xEnd;\r
+       s32 dx;\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_Z\r
+       f32 slopeZ;\r
+#endif\r
+#ifdef IPOL_W\r
+       fp24 slopeW;\r
+#endif\r
+#ifdef IPOL_C0\r
+       sVec4 slopeC;\r
+#endif\r
+#ifdef IPOL_T0\r
+       sVec2 slopeT[BURNING_MATERIAL_MAX_TEXTURES];\r
+#endif\r
+\r
+       // apply top-left fill-convention, left\r
+       xStart = fill_convention_left(line.x[0]);\r
+       xEnd = fill_convention_right(line.x[1]);\r
+\r
+       dx = xEnd - xStart;\r
+       if (dx < 0)\r
+               return;\r
+\r
+       // slopes\r
+       const f32 invDeltaX = reciprocal_zero2(line.x[1] - line.x[0]);\r
+\r
+#ifdef IPOL_Z\r
+       slopeZ = (line.z[1] - line.z[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_W\r
+       slopeW = (line.w[1] - line.w[0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_C0\r
+       slopeC = (line.c[0][1] - line.c[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T0\r
+       slopeT[0] = (line.t[0][1] - line.t[0][0]) * invDeltaX;\r
+#endif\r
+#ifdef IPOL_T1\r
+       slopeT[1] = (line.t[1][1] - line.t[1][0]) * invDeltaX;\r
+#endif\r
+\r
+#ifdef SUBTEXEL\r
+       subPixel = ((f32)xStart) - line.x[0];\r
+#ifdef IPOL_Z\r
+       line.z[0] += slopeZ * subPixel;\r
+#endif\r
+#ifdef IPOL_W\r
+       line.w[0] += slopeW * subPixel;\r
+#endif\r
+#ifdef IPOL_C0\r
+       line.c[0][0] += slopeC * subPixel;\r
+#endif\r
+#ifdef IPOL_T0\r
+       line.t[0][0] += slopeT[0] * subPixel;\r
+#endif\r
+#ifdef IPOL_T1\r
+       line.t[1][0] += slopeT[1] * subPixel;\r
+#endif\r
+#endif\r
+\r
+       SOFTWARE_DRIVER_2_CLIPCHECK;\r
+       dst = (tVideoSample*)RenderTarget->getData() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+\r
+#ifdef USE_ZBUFFER\r
+       z = (fp24*)DepthBuffer->lock() + (line.y * RenderTarget->getDimension().Width) + xStart;\r
+#endif\r
+\r
+\r
+       f32 inversew = INVERSE_W_RANGE;\r
+\r
+#ifdef IPOL_C0\r
+       tFixPoint r0, g0, b0;\r
+#endif\r
+\r
+#ifdef IPOL_A0\r
+       tFixPoint a0;\r
+       tFixPoint r1, g1, b1;\r
+#endif\r
+\r
+       for (s32 i = 0; i <= dx; ++i)\r
+       {\r
+               if ((0 == EdgeTestPass) & i) break;\r
+\r
+#ifdef CMP_Z\r
+               if (line.z[0] < z[i])\r
+#endif\r
+#ifdef CMP_W\r
+               if (line.w[0] >= z[i])\r
+#endif\r
+               {\r
+#ifdef WRITE_Z\r
+                       z[i] = line.z[0];\r
+#endif\r
+#ifdef WRITE_W\r
+                       z[i] = line.w[0];\r
+#endif\r
+               /* Pixel Shader here */\r
+#ifdef INVERSE_W\r
+                       inversew = (INVERSE_W_RANGE) / line.w[0]; /* fix_inverse32(line.w[0]);*/\r
+#endif\r
diff --git a/source/Irrlicht/burning_shader_compile_start.h b/source/Irrlicht/burning_shader_compile_start.h
new file mode 100644 (file)
index 0000000..0d8a5f7
--- /dev/null
@@ -0,0 +1,24 @@
+// undef compile flag for this file\r
+#undef USE_ZBUFFER\r
+#undef IPOL_Z\r
+#undef CMP_Z\r
+#undef WRITE_Z\r
+\r
+#undef IPOL_W\r
+#undef CMP_W\r
+#undef WRITE_W\r
+\r
+#undef SUBTEXEL\r
+#undef INVERSE_W\r
+\r
+#undef IPOL_C0\r
+#undef IPOL_A0\r
+#undef IPOL_T0\r
+#undef IPOL_T1\r
+#undef IPOL_T2\r
+#undef IPOL_L0\r
+\r
+#undef burning_shader_fragment\r
+#undef ipol_test\r
+\r
+#undef INVERSE_W_RANGE\r
diff --git a/source/Irrlicht/burning_shader_compile_triangle.h b/source/Irrlicht/burning_shader_compile_triangle.h
new file mode 100644 (file)
index 0000000..aa58858
--- /dev/null
@@ -0,0 +1,368 @@
+#include "burning_shader_compile_verify.h"\r
+\r
+\r
+void burning_shader_class::drawTriangle(const s4DVertex* burning_restrict a, const s4DVertex* burning_restrict b, const s4DVertex* burning_restrict c)\r
+{\r
+       // sort on height, y\r
+       if (a->Pos.y > b->Pos.y) swapVertexPointer(&a, &b);\r
+       if (a->Pos.y > c->Pos.y) swapVertexPointer(&a, &c);\r
+       if (b->Pos.y > c->Pos.y) swapVertexPointer(&b, &c);\r
+\r
+       const f32 ca = c->Pos.y - a->Pos.y;\r
+       const f32 ba = b->Pos.y - a->Pos.y;\r
+       const f32 cb = c->Pos.y - b->Pos.y;\r
+\r
+       // calculate delta y of the edges\r
+       scan.invDeltaY[0] = reciprocal_edge(ca);\r
+       scan.invDeltaY[1] = reciprocal_edge(ba);\r
+       scan.invDeltaY[2] = reciprocal_edge(cb);\r
+\r
+       if (F32_LOWER_EQUAL_0(scan.invDeltaY[0]))\r
+               return;\r
+\r
+       // find if the major edge is left or right aligned\r
+       f32 temp[4];\r
+\r
+       temp[0] = a->Pos.x - c->Pos.x;\r
+       temp[1] = -ca;\r
+       temp[2] = b->Pos.x - a->Pos.x;\r
+       temp[3] = ba;\r
+\r
+       scan.left = (temp[0] * temp[3] - temp[1] * temp[2]) > 0.f ? 0 : 1;\r
+       scan.right = 1 - scan.left;\r
+\r
+       // calculate slopes for the major edge\r
+       scan.slopeX[0] = (c->Pos.x - a->Pos.x) * scan.invDeltaY[0];\r
+       scan.x[0] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+       scan.slopeZ[0] = (c->Pos.z - a->Pos.z) * scan.invDeltaY[0];\r
+       scan.z[0] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+       scan.slopeW[0] = (c->Pos.w - a->Pos.w) * scan.invDeltaY[0];\r
+       scan.w[0] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+       scan.slopeC[0][0] = (c->Color[0] - a->Color[0]) * scan.invDeltaY[0];\r
+       scan.c[0][0] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+       scan.slopeT[0][0] = (c->Tex[0] - a->Tex[0]) * scan.invDeltaY[0];\r
+       scan.t[0][0] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+       scan.slopeT[1][0] = (c->Tex[1] - a->Tex[1]) * scan.invDeltaY[0];\r
+       scan.t[1][0] = a->Tex[1];\r
+#endif\r
+\r
+       // top left fill convention y run\r
+       s32 yStart;\r
+       s32 yEnd;\r
+\r
+#ifdef SUBTEXEL\r
+       f32 subPixel;\r
+#endif\r
+\r
+\r
+       // rasterize upper sub-triangle\r
+       if (F32_GREATER_0(scan.invDeltaY[1]))\r
+       {\r
+               // calculate slopes for top edge\r
+               scan.slopeX[1] = (b->Pos.x - a->Pos.x) * scan.invDeltaY[1];\r
+               scan.x[1] = a->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+               scan.slopeZ[1] = (b->Pos.z - a->Pos.z) * scan.invDeltaY[1];\r
+               scan.z[1] = a->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.slopeW[1] = (b->Pos.w - a->Pos.w) * scan.invDeltaY[1];\r
+               scan.w[1] = a->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.slopeC[0][1] = (b->Color[0] - a->Color[0]) * scan.invDeltaY[1];\r
+               scan.c[0][1] = a->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.slopeT[0][1] = (b->Tex[0] - a->Tex[0]) * scan.invDeltaY[1];\r
+               scan.t[0][1] = a->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.slopeT[1][1] = (b->Tex[1] - a->Tex[1]) * scan.invDeltaY[1];\r
+               scan.t[1][1] = a->Tex[1];\r
+#endif\r
+\r
+               // apply top-left fill convention, top part\r
+               yStart = fill_convention_left(a->Pos.y);\r
+               yEnd = fill_convention_right(b->Pos.y);\r
+\r
+#ifdef SUBTEXEL\r
+               subPixel = ((f32)yStart) - a->Pos.y;\r
+\r
+               // correct to pixel center\r
+               scan.x[0] += scan.slopeX[0] * subPixel;\r
+               scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+               scan.z[0] += scan.slopeZ[0] * subPixel;\r
+               scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.w[0] += scan.slopeW[0] * subPixel;\r
+               scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+               scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+               scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+               // rasterize the edge scanlines\r
+               for (line.y = yStart; line.y <= yEnd; ++line.y)\r
+               {\r
+                       line.x[scan.left] = scan.x[0];\r
+                       line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+                       line.z[scan.left] = scan.z[0];\r
+                       line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       line.w[scan.left] = scan.w[0];\r
+                       line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       line.t[0][scan.left] = scan.t[0][0];\r
+                       line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       line.t[1][scan.left] = scan.t[1][0];\r
+                       line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+                       // render a scanline\r
+                       (this->*fragmentShader) ();\r
+                       if (EdgeTestPass & edge_test_first_line) break;\r
+\r
+                       scan.x[0] += scan.slopeX[0];\r
+                       scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+                       scan.z[0] += scan.slopeZ[0];\r
+                       scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       scan.w[0] += scan.slopeW[0];\r
+                       scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] += scan.slopeT[0][0];\r
+                       scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] += scan.slopeT[1][0];\r
+                       scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+               }\r
+       }\r
+\r
+       // rasterize lower sub-triangle\r
+       if (F32_GREATER_0(scan.invDeltaY[2]))\r
+       {\r
+               // advance to middle point\r
+               if (F32_GREATER_0(scan.invDeltaY[1]))\r
+               {\r
+                       temp[0] = b->Pos.y - a->Pos.y;  // dy\r
+\r
+                       scan.x[0] = a->Pos.x + scan.slopeX[0] * temp[0];\r
+#ifdef IPOL_Z\r
+                       scan.z[0] = a->Pos.z + scan.slopeZ[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_W\r
+                       scan.w[0] = a->Pos.w + scan.slopeW[0] * temp[0];\r
+#endif\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] = a->Color[0] + scan.slopeC[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] = a->Tex[0] + scan.slopeT[0][0] * temp[0];\r
+#endif\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] = a->Tex[1] + scan.slopeT[1][0] * temp[0];\r
+#endif\r
+\r
+               }\r
+\r
+               // calculate slopes for bottom edge\r
+               scan.slopeX[1] = (c->Pos.x - b->Pos.x) * scan.invDeltaY[2];\r
+               scan.x[1] = b->Pos.x;\r
+\r
+#ifdef IPOL_Z\r
+               scan.slopeZ[1] = (c->Pos.z - b->Pos.z) * scan.invDeltaY[2];\r
+               scan.z[1] = b->Pos.z;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.slopeW[1] = (c->Pos.w - b->Pos.w) * scan.invDeltaY[2];\r
+               scan.w[1] = b->Pos.w;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.slopeC[0][1] = (c->Color[0] - b->Color[0]) * scan.invDeltaY[2];\r
+               scan.c[0][1] = b->Color[0];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.slopeT[0][1] = (c->Tex[0] - b->Tex[0]) * scan.invDeltaY[2];\r
+               scan.t[0][1] = b->Tex[0];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.slopeT[1][1] = (c->Tex[1] - b->Tex[1]) * scan.invDeltaY[2];\r
+               scan.t[1][1] = b->Tex[1];\r
+#endif\r
+\r
+               // apply top-left fill convention, top part\r
+               yStart = fill_convention_left(b->Pos.y);\r
+               yEnd = fill_convention_right(c->Pos.y);\r
+\r
+#ifdef SUBTEXEL\r
+\r
+               subPixel = ((f32)yStart) - b->Pos.y;\r
+\r
+               // correct to pixel center\r
+               scan.x[0] += scan.slopeX[0] * subPixel;\r
+               scan.x[1] += scan.slopeX[1] * subPixel;\r
+\r
+#ifdef IPOL_Z\r
+               scan.z[0] += scan.slopeZ[0] * subPixel;\r
+               scan.z[1] += scan.slopeZ[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+               scan.w[0] += scan.slopeW[0] * subPixel;\r
+               scan.w[1] += scan.slopeW[1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+               scan.c[0][0] += scan.slopeC[0][0] * subPixel;\r
+               scan.c[0][1] += scan.slopeC[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+               scan.t[0][0] += scan.slopeT[0][0] * subPixel;\r
+               scan.t[0][1] += scan.slopeT[0][1] * subPixel;\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+               scan.t[1][0] += scan.slopeT[1][0] * subPixel;\r
+               scan.t[1][1] += scan.slopeT[1][1] * subPixel;\r
+#endif\r
+\r
+#endif\r
+\r
+               // rasterize the edge scanlines\r
+               for (line.y = yStart; line.y <= yEnd; ++line.y)\r
+               {\r
+                       line.x[scan.left] = scan.x[0];\r
+                       line.x[scan.right] = scan.x[1];\r
+\r
+#ifdef IPOL_Z\r
+                       line.z[scan.left] = scan.z[0];\r
+                       line.z[scan.right] = scan.z[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       line.w[scan.left] = scan.w[0];\r
+                       line.w[scan.right] = scan.w[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       line.c[0][scan.left] = scan.c[0][0];\r
+                       line.c[0][scan.right] = scan.c[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       line.t[0][scan.left] = scan.t[0][0];\r
+                       line.t[0][scan.right] = scan.t[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       line.t[1][scan.left] = scan.t[1][0];\r
+                       line.t[1][scan.right] = scan.t[1][1];\r
+#endif\r
+\r
+                       // render a scanline\r
+                       (this->*fragmentShader) ();\r
+                       if (EdgeTestPass & edge_test_first_line) break;\r
+\r
+                       scan.x[0] += scan.slopeX[0];\r
+                       scan.x[1] += scan.slopeX[1];\r
+\r
+#ifdef IPOL_Z\r
+                       scan.z[0] += scan.slopeZ[0];\r
+                       scan.z[1] += scan.slopeZ[1];\r
+#endif\r
+\r
+#ifdef IPOL_W\r
+                       scan.w[0] += scan.slopeW[0];\r
+                       scan.w[1] += scan.slopeW[1];\r
+#endif\r
+\r
+#ifdef IPOL_C0\r
+                       scan.c[0][0] += scan.slopeC[0][0];\r
+                       scan.c[0][1] += scan.slopeC[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T0\r
+                       scan.t[0][0] += scan.slopeT[0][0];\r
+                       scan.t[0][1] += scan.slopeT[0][1];\r
+#endif\r
+\r
+#ifdef IPOL_T1\r
+                       scan.t[1][0] += scan.slopeT[1][0];\r
+                       scan.t[1][1] += scan.slopeT[1][1];\r
+#endif\r
+\r
+               }\r
+       }\r
+\r
+}\r
diff --git a/source/Irrlicht/burning_shader_compile_verify.h b/source/Irrlicht/burning_shader_compile_verify.h
new file mode 100644 (file)
index 0000000..c31c575
--- /dev/null
@@ -0,0 +1,43 @@
+// apply global override\r
+#ifndef SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT\r
+#undef INVERSE_W\r
+#endif\r
+\r
+#ifndef SOFTWARE_DRIVER_2_SUBTEXEL\r
+#undef SUBTEXEL\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_COLORS < 1\r
+#undef IPOL_C0\r
+#undef IPOL_A0\r
+#endif\r
+\r
+#if BURNING_MATERIAL_MAX_LIGHT_TANGENT < 1\r
+#undef IPOL_L0\r
+#endif\r
+\r
+\r
+// 1/x * FIX_POINT\r
+#if !defined(INVERSE_W_RANGE)\r
+       #define INVERSE_W_RANGE FIX_POINT_F32_MUL\r
+#endif\r
+\r
+#if defined ( SOFTWARE_DRIVER_2_USE_WBUFFER ) || defined ( SOFTWARE_DRIVER_2_PERSPECTIVE_CORRECT )\r
+#else\r
+\r
+#ifdef IPOL_W\r
+       #undef IPOL_W\r
+       #define IPOL_Z\r
+#endif\r
+\r
+#ifdef CMP_W\r
+       #undef CMP_W\r
+       #define CMP_Z\r
+#endif\r
+\r
+#ifdef WRITE_W\r
+       #undef WRITE_W\r
+       #define WRITE_Z\r
+#endif\r
+\r
+#endif\r
index af1a9e0bbd47188165ebc7603fe9590ac48a92fe..bdd17cd18c57daefd78b3016b231161714c12d59 100644 (file)
Binary files a/tests/media/Burning's Video-2dmatFilter.png and b/tests/media/Burning's Video-2dmatFilter.png differ
index 52feb695c0b60c6faf67e252e1ae50bd48a048ac..d16e689a8de39f43e4c490df7b4707bf28d58566 100644 (file)
Binary files a/tests/media/Burning's Video-b3dAnimation.png and b/tests/media/Burning's Video-b3dAnimation.png differ
index fc33f23c41eeb8c0cdfffbd6f98e9f31092bf082..b669f8f879930cb8bf24e8862558c1c4e7cd698b 100644 (file)
Binary files a/tests/media/Burning's Video-b3dJointPosition.png and b/tests/media/Burning's Video-b3dJointPosition.png differ
index 9892076a605ef12033d7b4c0dd97e9e634437256..59f36c1d4d40e4225bab3327f6460740ad7b0979 100644 (file)
Binary files a/tests/media/Burning's Video-billboard.png and b/tests/media/Burning's Video-billboard.png differ
index fb99360ff08db873f3973d0f24104942a389b72c..2805aed80dae420e6d29ec7512a933e6c37e8152 100644 (file)
Binary files a/tests/media/Burning's Video-billboardOrientation.png and b/tests/media/Burning's Video-billboardOrientation.png differ
index a245525bbccd0ec1e9b7b5e0c26eeb5704fd8bbf..0a98b70e40a4f85a3d6093462aeee7c52c8ccf62 100644 (file)
Binary files a/tests/media/Burning's Video-draw2DImage4cFilter.png and b/tests/media/Burning's Video-draw2DImage4cFilter.png differ
index b7539cf8f678eca2124d1071ca1e1c64d264165f..08288a85b105d966ff00d5bc722fffe93f672200 100644 (file)
Binary files a/tests/media/Burning's Video-drawPixel.png and b/tests/media/Burning's Video-drawPixel.png differ
index a3f516239c5abb2d6adf6d2567103900531bb488..bc839920348565bd447a958970bb69ecf8c86620 100644 (file)
Binary files a/tests/media/Burning's Video-drawVPL_e.png and b/tests/media/Burning's Video-drawVPL_e.png differ
index 113dc35c169f65a860e7eb31c252e7fb0acf5369..438941d1e163a68cf35936efd88bcf9be84f58ef 100644 (file)
Binary files a/tests/media/Burning's Video-drawVPL_g.png and b/tests/media/Burning's Video-drawVPL_g.png differ
index d1b1f8dc7b10976abcd89d3bf928234fa3e90afe..8ed44557ff1cf354f3a8ca7e6c89316dac82cf6b 100644 (file)
Binary files a/tests/media/Burning's Video-drawVPL_h.png and b/tests/media/Burning's Video-drawVPL_h.png differ
index be45d0f1982981ac97000b5812f326833ed3402a..e344631b061897cab5fa6ecac189ef7229d86896 100644 (file)
Binary files a/tests/media/Burning's Video-drawVPL_i.png and b/tests/media/Burning's Video-drawVPL_i.png differ
index fbc2ecad3c327086b366d270ac7673dba2919315..218af2a71f1a152bdc862061f68175d0f3ead782 100644 (file)
Binary files a/tests/media/Burning's Video-flyCircleAnimator.png and b/tests/media/Burning's Video-flyCircleAnimator.png differ
index a472e92dcc2a6e27115d5ef841ea07dbf484b281..446cc6dda316735b9f2cb8bb2832726fd65f1808 100644 (file)
Binary files a/tests/media/Burning's Video-lightType.png and b/tests/media/Burning's Video-lightType.png differ
index b68c9144610b7203ee2010dbcc300afab4ccec52..00e08b11d0215497f4db291a18c121fc3bc96429 100644 (file)
Binary files a/tests/media/Burning's Video-loadScene.png and b/tests/media/Burning's Video-loadScene.png differ
index 709b97e9eb7baadcc108fe5e8e9866530634a35e..302b9b3de52bc18805f18cf328586cea7a1e41b5 100644 (file)
Binary files a/tests/media/Burning's Video-md2Normals.png and b/tests/media/Burning's Video-md2Normals.png differ
index a5666b7ccac2fc1375d6506a849fb7231454f2d9..338f257eda01c31f705e223c98f71d9423330751 100644 (file)
Binary files a/tests/media/Burning's Video-multiTexture.png and b/tests/media/Burning's Video-multiTexture.png differ
index 5e35ddde2b773009d3f3ecdc11aef7663b9a3810..41a96b8b9557a8baa1e18eba3e244df781fb5358 100644 (file)
Binary files a/tests/media/Burning's Video-orthoCam.png and b/tests/media/Burning's Video-orthoCam.png differ
index 14f6dc35b20a86a31cceeba91e7653551a6ea678..7c93216ee16733cc4da174e3dd738db74f6bcf11 100644 (file)
Binary files a/tests/media/Burning's Video-planeMatrix-scaledClip.png and b/tests/media/Burning's Video-planeMatrix-scaledClip.png differ
index 06fc37f0fdbe9b31f0f3c374865253b8d07c87d8..d2d53210d6d44b2bf1298e851479223f2f22c588 100644 (file)
Binary files a/tests/media/Burning's Video-renderMipmap.png and b/tests/media/Burning's Video-renderMipmap.png differ
index dcdb60873dd30a7bf85280658c1016afc0ce9ba4..2bd6eecfef5a805bbc6eede7801cce31e780f0ca 100644 (file)
Binary files a/tests/media/Burning's Video-stencilSelfShadow.png and b/tests/media/Burning's Video-stencilSelfShadow.png differ
index 60f31cdc11908f292f097d3b024441f354172704..77c53fd6cc153c96b40c9fda736f07b4fe3aa4bc 100644 (file)
Binary files a/tests/media/Burning's Video-stencilShadow.png and b/tests/media/Burning's Video-stencilShadow.png differ
index 835a946c6aaebc6070c1c412fc9e17d5c2642927..db12562621e74ec8a2dc8e56be33bf8a3e25b922 100644 (file)
Binary files a/tests/media/Burning's Video-terrainGap.png and b/tests/media/Burning's Video-terrainGap.png differ
index ba53a28869ffb94543873ad00d0dfef2d9ed2dd3..e7a899355edc3c0fe026763f65bd1dbbdf7dc746 100644 (file)
Binary files a/tests/media/Burning's Video-terrainSceneNode-1.png and b/tests/media/Burning's Video-terrainSceneNode-1.png differ
index 4c92f024c7c6076bb8ce855112d3dbf8ca3bca9e..1c7538abd4a7835848fc92f6469cad2ec392365f 100644 (file)
Binary files a/tests/media/Burning's Video-terrainSceneNode-2.png and b/tests/media/Burning's Video-terrainSceneNode-2.png differ
index 5ea41667eefa7251741e49e99e5aa7651013338b..6904bde5667a7459db83dea28d750d838839c315 100644 (file)
Binary files a/tests/media/Burning's Video-testGeometryCreator.png and b/tests/media/Burning's Video-testGeometryCreator.png differ
index 53d0aa56cc02de87540a5103abe53c771c1edce5..ffbc74c6cfb9a5bebe48021368ce4e00dbae6ff9 100644 (file)
Binary files a/tests/media/Burning's Video-testTerrainMesh.png and b/tests/media/Burning's Video-testTerrainMesh.png differ
diff --git a/tests/media/Burning's Video-textureMatrix.png b/tests/media/Burning's Video-textureMatrix.png
new file mode 100644 (file)
index 0000000..26afc9e
Binary files /dev/null and b/tests/media/Burning's Video-textureMatrix.png differ
diff --git a/tests/media/Burning's Video-textureMatrix2.png b/tests/media/Burning's Video-textureMatrix2.png
new file mode 100644 (file)
index 0000000..26afc9e
Binary files /dev/null and b/tests/media/Burning's Video-textureMatrix2.png differ
diff --git a/tests/media/Burning's Video-textureMatrixInMixedScenes.png b/tests/media/Burning's Video-textureMatrixInMixedScenes.png
new file mode 100644 (file)
index 0000000..e5cdeb2
Binary files /dev/null and b/tests/media/Burning's Video-textureMatrixInMixedScenes.png differ
index 98282fa1ab04f5f9a038f4c1b9563b53c9c4f4fd..92c29fc74ddb2576ef82b5f3fa16c0af51d1528d 100644 (file)
Binary files a/tests/media/Burning's Video-textureRenderStates.png and b/tests/media/Burning's Video-textureRenderStates.png differ
index 87261e59dcc7dd75e2f719782392ceafb0d2ae41..59374484678b8272e48f30ec3aa22b3dc0a86455 100644 (file)
Binary files a/tests/media/Burning's Video-transparentAddColor.png and b/tests/media/Burning's Video-transparentAddColor.png differ
index 0986ed446f1d808b5ad44fdeecab577760a0efab..358455d3ab1601dd186cf294124c95550f9049f8 100644 (file)
Binary files a/tests/media/Burning's Video-transparentAlphaChannel.png and b/tests/media/Burning's Video-transparentAlphaChannel.png differ
index 09ff338bf08b28145472a1a32d28257de8a0fd7a..21844ab283d398b90eb314cefc654200b70627e9 100644 (file)
Binary files a/tests/media/Burning's Video-transparentAlphaChannelRef.png and b/tests/media/Burning's Video-transparentAlphaChannelRef.png differ
index 7acfba649aee3656bf9b86894db7a6e8d6388556..926d189a5a47a5b7cb391728847951c645524018 100644 (file)
Binary files a/tests/media/Burning's Video-transparentReflection2Layer.png and b/tests/media/Burning's Video-transparentReflection2Layer.png differ
index b8f268c6693e90cc22f4d03828af92863a3fd219..aef6dbd7b868d6a313350888ec3965166138986d 100644 (file)
Binary files a/tests/media/Burning's Video-transparentVertexAlpha.png and b/tests/media/Burning's Video-transparentVertexAlpha.png differ
index 4dfaff0c650efc56677e323b84d654b1e5830a37..666b8145b18fbec4be1ca452d4a7cb2daa227d74 100644 (file)
Binary files a/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png and b/tests/media/Burning's Video-transparentVertexAlphaChannelMore.png differ
index 7c9f78135e6be0a9a4bef392b0fc8dcad528b1c3..56e306505d5af23c7189399097186cd3a20fc631 100644 (file)
Binary files a/tests/media/Burning's Video-viewPortText.png and b/tests/media/Burning's Video-viewPortText.png differ
diff --git a/tests/media/Burning's Video-writeImageToFile.png b/tests/media/Burning's Video-writeImageToFile.png
new file mode 100644 (file)
index 0000000..08288a8
Binary files /dev/null and b/tests/media/Burning's Video-writeImageToFile.png differ
index 673e1c4d86848bdb0c5bbb04f964d0e04a8fb9e1..9158849dd12de24af35b989347123d9d9f1d4aca 100644 (file)
@@ -1,4 +1,4 @@
 Tests finished. 72 tests of 72 passed.\r
-Compiled as DEBUG\r
-Test suite pass at GMT Mon Feb 10 14:59:56 2020\r
+Compiled as RELEASE\r
+Test suite pass at GMT Sun Feb 23 02:59:02 2020\r
 \r